1. 编程机制
用c语言编写程序时,编写的内容被储存在文本文件中,该文件被称为源代码文件。
编译器将源代码转换为中间代码,链接器将目标代码、系统的标准启动代码和库代码合并为可执行文件。对于库代码,链接器只会把程序中要用到的库函数代码提取出来。
目标文件和可执行文件都是由机器语言指令组成的,然而,目标文件中只包含编译器为你编写的代码翻译的机器语言代码,可执行文件中还包含你编写的程序中使用的库函数和启动代码的机器代码。
2. 知识点
1.
# include <stdio.h>
这一句的作用相当于把stdio.h文件中的所有内容都输入该行所在的位置。
2. 注释:/* */ 或 //,前者多行或单行,后者只支持单行(C99新增)
3. int num; 声明把特定标识符与计算机内存中特定的位置联系起来,同时也确定了储存在某位置的信息类型或数据类型
4. 在C语言中,实际参数,简称实参,是传递给函数的特定值;形式参数,简称形参,是函数中用于储存值的变量。
5. 函数原型(prototype)是C90标准新增的。C标准建议,要为程序中用到的所有函数提供函数原型。
6. 有些数据类型在程序运行期间可能会改变或被赋值,这些称为变量;有些数据类型在程序使用之前已经预先设定好了,在整个程序的运行过程中没有变化,这些称为常量。
7. C语言的数据类型关键字:
最初K&R给出的关键字 | C90标准添加的关键字 | C99标准添加的关键字 |
int | signed | _Bool |
long | void | _Complex |
short | _Imaginary | |
unsigned | ||
char | ||
float | ||
double |
8. 字 (word)是设计计算机时给定的自然储存单位。
9. C语言基本数据类型
a. int: ISO C规定int的最小取值范围为-32768~32767
b. 不同的进制要使用不同的转换说明。以十进制显示数字,使用%d;以八进制显示数字,使用%o;以十六进制显示数字,使用%x。另外,要显示各进制数的前缀0,0x和0X,必须分别使用%#o,%#x,%#X。
# include <stdio.h>
int main(void){
int x = 100;
printf("dec = %d, octal = %o, hex = %x\n", x, x, x);
printf("dec = %d, octal = %#o, hex = %#x\n", x, x, x);
return 0;
}
10. C语言提供3个附属关键词修饰基本整数类型:short、long和unsigned。
- short int 类型,或者简写为short,占用的存储空间可能比int类型少,常用于较少数值的场合以节省空间。与int类似,short是有符号类型的。
- long int 或者 long占用的存储空间可能比int多,适用于较大数值的场合。与int类似,long是有符号类型的。
- long long int 或 long long (C99标准加入)占用的存储空间可能比long多,适用于更大数值的场合,该类型至少占64位。与int类似,long long是有符号类型。
- unsigned int或者unsigned只用于非负值的场合。
- 在任何符号类型前面那添加关键字signed,可强调使用有符号类型的意图。
对于程序中的整数值,编译器会尝试int, unsigned int, long, unsigned long, long long 和 unsigned long long 类型进行储存。
打印unsigned int类型的值,使用%u转换说明;打印long类型的值,使用%ld转换说明。如果系统中int和long的大小相同,使用%d就行。
在x和o前面可以使用l前缀,%lx表示以十六进制格式打印long类型整数,%lo表示以八进制格式打印long类型整数。注意,虽然C允许使用大写或小写的常量后缀,但是在转换说明中只能使用小写。
在C语言中,用单引号括起来的单个字符被称为字符常量。
11. 可移植类型:stdint.h和inttypes.h
- 精确宽度整数类型(exact-width integer type):int32_t表示整数类型的宽度刚好是32位
- 最小宽度类型(minimum width type):保证所表示的类型一定是至少有指定宽度的最小整数类型,int_least8_t
- 最快最小宽度类型(fast minimum width type): 可使计算达到最快的类型集合,int_fast8_t被定义为系统中对8位有符号值而言运算最快的整数类型的别名
- 最大整数类型:intmax_t可储存任何有效的有符号整数值,uintmax_t表示最大的无符号整数类型
# include <stdio.h> # include <inttypes.h> int main(void){ int32_t me32; me32 = 45933945; printf("First, assume int32_t is int: "); printf("me32 = %d\n", me32); printf("Next, let's not make any assumptions. \n"); printf("me32 = %" PRId32 "\n", me32); return 0; }
12. C标准规定,float类型必须至少能表示6位有效数字,且取值范围至少是10^-37~10^37。通常系统储存一个浮点数要占用32位。其中8位用于表示指数的值和符号,剩下24位用于表示非指数部分及其符号。double类型和float类型的最小取值范围相同,但至少必须能表示10位有效数字。
在代码中,可以用多种形式书写浮点型常量,其基本形式是:有符号的数字(包括小数点),后面紧跟e或E,最后一个有符号数表示10的指数。正号可以省略。可以没有小数点或指数部分,但是不能同时省略两者。可以省略整数部分或者小数部分,但是不能同时省略两者。
不能在浮点型常量中间加空格。
默认情况下,编译器假定浮点型常量是double类型的精度。
float some;
some = 2.0 * 4.0;
通常,2.0和4.0被储存为64位的double类型,使用双精度进行乘法运算,然后将乘积截断成float类型的宽度。这样做虽然计算精度更高,但是会减慢程序的运行速度。
在浮点数后面加上f或F后缀可覆盖默认设置,编译器会将浮点型常量看作float类型。使用l或L后缀使得数字成为long double类型。没有后缀的浮点型常量是double类型的。
C99标准添加了一种新的浮点型常量格式——用十六进制表示浮点型常量,即在16进制数前加上十六进制前缀(0x或0X),用p或P分别代替e和E,用2的幂代替10的幂,即p计数法。
0xa.1fp10 = (10+1/16+15/256)*2^10
注意,并非所有的编译器都支持C99的这一特性。
13. 打印浮点值
printf() 函数使用%f转换说明打印十进制计数法的float和double类型浮点数,用%e打印指数计数法的浮点数。如果系统支持16进制格式的浮点数,可用a或A分别代替e和E。打印long double类型要使用%LF,%Le, %La转换说明。
# include <stdio.h>
int main(void){
float a = 32000.0;
double b = 2.14e9;
long double c = 5.32e-5;
float d = 0xa.1fp10;
printf("%f can be writtern %e\n", a, a);
printf("%f can be writtern %e\n", b, b);
printf("%Lf can be writtern %Le\n", c, c);
printf("%f can be writtern %e\n", d, d);
return 0;
}
14. 浮点值的上溢和下溢
当计算导致数字过大,超过当前类型能表达的范围时,就会发生上溢。C语言规定,在这种情况下会给toobig赋一个表示无穷大的特定值,而且printf() 显示该值为inf或infinity。
下溢:损失了类型全精度的浮点值称为低于正常(subnormal)的浮点值。
15. 复数和虚数(C99标准支持)
C语言有3种复数类型:float _Complex, double _Complex和long double _Complex。float _Complex类型的变量应包含两个float类型的值,分别表示复数的实部和虚部。
C语言的3种虚数类型是float _Imaginary, double _Imaginary和long double _Imaginary
如果包含complex.h头文件,便可用complex代替_Complex,用imaginary代替_Imaginary,还可以用I代替-1的平方根
16. 类型大小
sizeof是C语言的内置运算符,以字节为单位给出指定类型的大小。C99和C11提供%zd转换说明匹配sizeof的返回类型。一些不支持C99和C11的编译器可用%u或%lu代替。
17. 参数和陷阱
用%d显示float类型的值,其值不会转化为int类型。
18. 转义序列示例
# include <stdio.h>
int main(void){
float salary;
printf("\a Enter your desired manthly salary:");
printf(" $_______\b\b\b\b\b\b\b");
scanf("%f", &salary);
printf("\n\t$%.2f a month is $%.2f a year.", salary, salary * 12);
printf("\rGee! \n");
return 0;
}
19. 刷新输出
printf() 何时把输出发送到屏幕上?最初,printf() 语句把输出发送到一个叫缓冲区(buffer)的中间存储区域,然后缓冲区的内容再不断被发送到屏幕上。C标准明确规定了何时把缓冲区的内容发送到屏幕:当缓冲区满,遇到换行字符或需要输入的时候(从缓冲区把数据发送到屏幕或文件被称为刷新缓冲区)。还有一种刷新缓冲区的方法是使用fflush() 函数。