《C语言核心技术》小结
时间:2010-06-28 来源:RobinKQin
1、字符常量可以包含多个字符,如'Xy',但在不同的编译器中,执行的结果是未定的。
字符常量的默认值是int,除非前置L,标识此字符常量的类型为宽字符类型wchar_t。
2、\r 表示回车:将现行位置移到目前行的开端。
3、两个整数的算术运算,会先对两个整数进行整数提升,如果提升之后,操作数依然具有不同的类型,继续进行下面的转换:
a)若以操作数是无符号类型T,其等级大于等于另一个操作数,那么另一个操作数会被转换为T类型;
b)否则,若一个操作数具有有符号类型T,其等级大于另一个操作数,且T足以表示另一个操作数类型的所有可能值,则另一个操作数会被转换为T;若T 不足以表示另一个操作数类型,则2个操作数都会被转换为与T等价的无符号类型。
4、有符号、无符号整数类型转换为另一种有符号整数类型,可能会发生上溢,最终结果由实现版本自行决定,可能导致信号的产生。
5、求余运算的结果与左边操作数的符号一致。
6、异或运算具有交换性,对于无符号整数b而言,b = b^mask^mask;利用该特性,可以不需要使用第三个临时变量即可交换两个整数的值:a^=b;b^=a,a^=b。
7、ptr是一个指针,不管ptr是不是左值,&*ptr都一定不会是左值。
8、点运算符的左操作数并非一定是左值,如
struct 结构体 函数名(); //函数的返回值不是左值!
printf(“成员 %%s\n",函数名().成员名。
9、C99标准中新增了长度可变数组。
10、函数无法返回函数与数组,但返回值可以是指针,指向一个函数或数组。
11、函数默认的存储类型是extern。
12、register只能用于修饰函数参数,会让编译器尽可能快速存取此变量。
13、把数组名做为函数自变量参数时,数组名会自动被转换为指针。
14、C99中新增inline函数,告诉编译器,任何地方只要调用此函数,就直接把机器码插入到调用的地方。这样提高程序的执行效率,但翻译单元 只要用到某个inline函数,就必须重新定义,故此函数经常写入头文件中。
15、volatile告知编译器,此对象不只能被程序本身所修改,甚至也可能会被处理器或事件修改。
16、获得成员和结构其实地址之间的位偏差,可以利用stddef.h头文件中的offsetof宏:
offsetof(struct type,member) 返回值是size_t
17、C99允许弹性结构成员,即最后一个成员属于不完整的数组类型,如:
typedef struct {
int len;
float array[];/*弹性结构成员*/
}DynArray_t;
该结构体有如下特性:
1)sizeof(DynArray_t) = offsetof(DynArray_t,array);
2)不允许初始化该成员;
3)该成员通过赋值操作无法被复制,如DynArray_t dal = *otherdal。
18、C99含stdbool.h头文件,可用于处理bool、true、false。
19、对象的生存周期分为三类:自动的(auto、register)、静态的、已分配的(allocated);
标识符的链接可以是三类:外部(external)、内部(internal)、没有(none)。
20、被声明为register的对象,不可以进行取地址运算。
21、具有“无连接”的标识符包括:
1)lable name ;2)结构体声明name ; 3)typedef name ;
4)函数参数名 ; 5)在函数体内,并且没有extern修饰符的对象标识符;
22、一般地,静态对象被存储在程序内存的数据区域,自动对象被存储在堆栈中,已分配对象是程序执行时通过malloc()、calloc()、 realloc()获取的内存。
23、静态对象有两种:
1)函数外面定义的对象(其对应的标识符可以是extern、static或没有);
2)函数内定义的对象,但是用static存储类修饰符的对象;
24、具有静态生存周期的所有对象,都是在程序开始执行之前就被实现创建和初始化,其寿命覆盖整个程序的一生。
25、malloc(size_t size):分配连续的内存区域,体积大于等于size,内容尚未决定。
calloc(size_t count,size_t size):分配不少于count * size 的内存空间,每个字节都初始化为0.
26、void *memcpy(void * restrict dest,const void * restrict src,size_t n);
这里的restrict限定指针所指向的对象只会通过该限定指针来存取。
另外,对于第二个参数,如果是个字符串常量,且n大于(该字符串长度+1),则dest在[(该字符串长度+1),n]之间的内存是不可预见的。
27、对于malloc、realloc、calloc出来的地址,用free是没有返回值的,程序无法得知是否成功释放。
28、 assert.h只定义类函数宏assert(),此宏测试是否表达式的值为非0值。
如果在包含assert.h之前定义了 NDEBUG宏,那么调用assert()就不起作用了。
29、complex.h:复数数学函数的原型及相关宏。
30、 ctype.h:单个字符进行分类与转换。
31、errno.h:errno 是标识符声明为int类型的状态变量。
32、 setjimp.h:声明longjump()
33、函数,定义jmp_buf数组类型和setjmp()类函数宏。
setjmp()可 以把当前的运行环境(至少包括临时寄存器和堆栈)存储在一个jmp_buf类型的变量中,以后只要使用longjmp()就可以返回到这个点上。
33、 freopen:改变既有文件指针所指向的文件,最常见的用途是重新定向标准的I/O流——stdin\stdout\stderr。
34、 getchar()的效果等效于getc(stdin)。
35、gets(char *) 没有提供限制输入长度的任何方法,建议使用fgets()替代。
36、double modf(double x,double * inpart);把一个浮点数分割成整数部分和小数部分。
37、trunc()把一个浮点数往靠近0的方向取近似值到整数。
38、编译时 -Dname=[definition],在源代码和头文件内都不可以定义name宏。