文章目录
- 1.C程序运行机制
- 2.HelloWorld的剖析
-
- [① main()](#① main())
- [② 函数体](#② 函数体)
- [③ printf()](#③ printf())
- [④ 标准库、头文件](#④ 标准库、头文件)
- 3.输出
-
- [3.1 printf()标准格式](#3.1 printf()标准格式)
- [3.2 占位符](#3.2 占位符)
- [3.3 输出格式](#3.3 输出格式)
1.C程序运行机制
过程1:编辑
编写C语言源程序代码,并已文件的形式存储到磁盘中。源程序文件以".c
"作为扩展名。
过程2:编译
将C语言源程序转换为目标程序(或目标文件)
。如果程序没有错误,没有任何提示,就会生成一个扩展名为".obj
"的二进制文件。
C语言中的每条可执行语句经过编译后最终都将被转换成二进制的机器指令。
过程3:链接/连接
将编译形成的目标文件".obj"和库函数及其他目录文件连接/链接,形成统一的可执行的
二进制文件".exe
"。
为什么需要链接库文件呢?
因为我们的C程序中会使用 C程序库的内容,比如<stdio.h> 、<stdlib.h> 中的函数printf()、system()等,这些函数不是程序员自己写的,而是C程序库中提供的,因此需要链接。链接后,生成的.exe 文件,比obj 文件大了很多。
过程4:运行
有了可执行的exe文件,我们可以在控制台下直接运行此exe文件。
对修改后的xxx.c源文件需要重新编译、链接,生成新的exe文件后,再执行,才能生效。
2.HelloWorld的剖析
① main()
c
int main(){}
- 每一个程序(或工程)可以定义很多函数,但有且只有一个main()函数,作为程序执行的入口,在main() 函数结尾结束整个程序的运行。
- 空括号(), 表示 main 不接受任何参数。
- 写在main之前的"int"称为关键字,代表数据类型是整型。它是main()的返回值类型。即在执行main()函数后会得到一个整型值(即函数值)。
- C 语言约定:
return 0
,表示main()函数终止运行,且运行成功;如果返回其它非零整数,就表示运行失败。默认情况下,如果 main() 里面省略return 0
这一行,编译器会自动加上,但是为了保持统一的代码风格,不建议省略。
② 函数体
- 一对花括号{}定义了函数的主体,所有函数都必须以大括号开头和结尾,成对出现。
- C程序中的函数体指的是作为该函数一部分的语句。它可以是任何操作、比如搜索、排序、打印等。
- 每一个执行语句后面都会有一个分号";"作为语句结束的标志
- 一行内可以写几条语句,一条语句也可写在几行上。
③ printf()
printf()函数是产生格式化输出的函数,作用是将参数文本输出到屏幕。它名字里面的 f 代表 format (格式化),表示可以指定输出文本的格式。
c
printf("Hello World"); //将字符串输出到控制台,行尾不换行
为了让光标移到下一行的开头,可以在输出文本的结尾,添加一个换行符 \n 。
c
printf("Hello World\n");
④ 标准库、头文件
printf() 是在标准库的头文件 stdio.h
中定义的。要想在程序中使用这个函数,必须在源文件头部引入这个头文件。
c
#include <stdio.h>
何为标准库?
程序需要用到的功能,不一定需要自己编写,C 语言可能已经自带了。程序员只要去调用这些自带的功能就可以了。
C 语言自带的所有这些功能,统称为"标准库"(standard library)
,包含C 内置函数、常量和头文件。
因为它们是写入标准的,到底包括哪些功能,应该怎么使用,都是规定好的,我们直接调用即可。
何为头文件?
不同的功能定义在不同的文件里,这些文件统称为"头文件"(header file)
。如果系统自带某一个功能,就一定会自带描述这个功能的头文件,比如 printf() 的头文件就是系统自带的 stdio.h
。
头文件的后缀通常是 .h
。
预处理命令:#include命令
如果要使用某个功能,就必须先加载其对应的头文件,加载使用的是 #include
命令,声明在各文件模块的开头。
C语言中以 # 号开头的命令称为预处理命令
。顾名思义,在编译器对当前C程序进行编译前执行预处理操作。
格式:
c
#include <头文件名>
举例:
c
#include <stdio.h>
注意:加载头文件的 #include 语句不需要分号结尾
对比写法:
c
#include <stdio.h> //编译系统在系统头文件所在目录搜索
#include "stdio.h"; //编译系统首先在当前的源文件目录中查找 stdio.h,找不到的话。再转向系统头文件所在目录搜索。
stdio.h
是系统提供的一个文件名,stdio
是standard input & output的缩写。
结论:
- 引用系统头文件,两种形式都会可以,
#include <>
效率高。 - 引用用户头文件,只能使用
#include ""
。
常用的C头文件
stdio.h
------ 定义核心输入和输出函数- printf()、scanf()、getchar()、putchar()
stdlib.h
------定义数组转换函数、伪随机网络生成器和内存分配string.h
------定义字符串处理函数stdint.h
------定义精确宽度的整数类型math.h
------定义常用的数学函数- sin()、sqrt()
stddef.h
------定义了几个有用的类型和宏
3.输出
3.1 printf()标准格式
c
printf(格式控制字符串,输出列表);
"格式控制字符串"
是用双引号括起来的一个字符串。包括:- 普通字符:普通字符即需要在输出时原样输出的字符。
- 占位符:由"%"和格式字符组成。这个位置可以用其它值代入。
"输出列表"
是程序需要输出的一些数据,可以是常量、变量或表达式。用于替换占位符的位置。
注意:printf() 参数与占位符是一一对应关系。如果参数个数少于对应的占位符, printf() 可能会输出内存中的任意值。
3.2 占位符
占位符的第一个字符是 %
,第二个字符表示占位符的类型。
printf() 的占位符有许多种类,与 C 语言的数据类型相对应。
字母顺序占位符:
%a :浮点数(仅C99有效)
%A :浮点数(仅C99有效)
%c :char型数据
%d :十进制整数(int)%e :使用科学计数法的浮点数,指数部分的 e 为小写
%E :使用科学计数法的浮点数,指数部分的 E 为大写
%i :整数,基本等同于 %d
%f :浮点数(float)%g :6个有效数字的浮点数。整数部分一旦超过6位,就会自动转为科学计数法,指数部分的 e 为小写
%G :等同于 %g ,唯一的区别是指数部分的 E 为大写
%hd :十进制 short int 类型
%ho :八进制 short int 类型
%hx :十六进制 short int 类型
%hu :unsigned short int 类型
%ld :十进制整数(long)%lo :八进制 long int 类型
%lx :十六进制 long int 类型
%lu :unsigned long int 类型
%lld :十进制 long long int 类型
%llo :八进制 long long int 类型
%llx :十六进制 long long int 类型
%llu :unsigned long long int 类型
%le :科学计数法表示的 long double 类型浮点数
%lf :十进制浮点数(double)%n :已输出的字符串数量。该占位符本身不输出,只将值存储在指定变量之中
%o :八进制整数
%p :指针
%s :字符串
%u :十进制无符号整数(unsigned int)%x :十六进制整数
%zd : size_t 类型
%% :输出一个百分号
举例:
c
//1. %d
int num = 10;
printf("count is %d\n",num); //输出:count is 10
//2. %lf 和 %f
float f = 3.1415926535f; // 单精度浮点数
double d = 3.1415926535; // 双精度浮点数
// 使用 %f 输出单精度浮点数
printf("Float: %f\n", f); //Float: 3.141593
// 使用 %lf 输出双精度浮点数
printf("Double: %lf\n", d); //Double: 3.141593
// 使用 %f 输出单精度浮点数
printf("Float: %.8f\n", f); //Float: 3.14159274
// 使用 %lf 输出双精度浮点数
printf("Double: %.8lf\n", d); //Double: 3.14159265
//3. %c
char level = 'A';
printf("this score level is:%c\n",level); //输出:this score level is:A
//4. %s
printf("%s是我最喜欢的冷门歌手.\n","孙燕姿"); //输出:孙燕姿是我最喜欢的冷门歌手.
//5.多个占位符 输出文本里面可以使用多个占位符
printf("%s有%d部手机\n", "老板", 2); //输出:老板有2部手机
3.3 输出格式
printf() 可以定制占位符的输出格式。
格式1:限定宽度
printf() 允许限定占位符的最小宽度。
c
printf("%5d\n", 123) // 输出为 " 123"
说明:%5d 表示这个占位符的宽度至少为5位。如果不满5位,对应的值的前面会添加空格。
输出的值默认是右对齐,即输出内容前面会有空格;如果希望改成左对齐,在输出内容后面添加空格,可以在占位符的 % 的后面插入一个 - 号。
c
printf("%-5d\n", 123); // 输出为 "123 "
对于小数,这个限定符会限制所有数字的最小显示宽度
c
printf("%12f\n", 123.45); // 输出 " 123.450000"
%12f 表示输出的浮点数最少要占据12位。由于小数的默认显示精度是小数点后6位,所以123.45 输出结果的头部会添加2个空格。
格式2:总是显示正负号
默认情况下, printf() 不对正数显示 + 号,只对负数显示 - 号。如果想让正数也输出 + 号,可以在占位符的 % 后面加一个 + 。
c
printf("%+d\n", 11); // 输出 +11
printf("%+d\n", -11); // 输出 -11
格式3:限定小数位数
输出小数时,有时希望限定小数的位数。举例来说,希望小数点后面只保留两位,占位符可以写成 %.2f 。
c
printf("Number is %.2f\n", 0.8); // 输出 Number is 0.80
这种写法可以与限定宽度占位符,结合使用。
c
printf("%6.2f\n", 0.8); // 输出为 " 0.80"
说明:%6.2f 表示输出字符串最小宽度为6,小数位数为2。整体长度不足 6 位时,右对齐显示。
最小宽度和小数位数这两个限定值,都可以用 * 代替,通过 printf() 的参数传入。
c
printf("%*.*f\n", 6, 2, 0.8);
//等同于
printf("%6.2f\n", 0.8);