分类: C/C++
2012-05-21 17:34:41
<
1. 当你需要注释点一段代码时,用#if……#endif 比用注释要好;因为当用注释来从逻辑上删除一段代码,如果被删除的代码中有”/*”或”*/”字符讲或影响注释结果;(Pointers on C Page4)
2. C语言的四种基本数据类型:整型,浮点型,指针,聚合类型(数组和结构等)。(Page29)
3. 字符常量的数据类型总是int;(Page31)
4. 字符串常量(如:”HelloWorld”),在ANSI C标准中对字符串常量的修改行为的未定义的。它允许相同字符串常量存储于一个实体串,所以对字符串常量做修改时很危险的,因为这将会殃及程序的同他与此相同的常量值。(Page34)
5. 应该使用typedef而不应该使用#define来创建一个新的类型名,因为后者无法正确处理指针类型。例如:#define def_pchar char *;
def_pchar a,b;在宏扩展后的b只是个字符型而非字符指针。(Page38)
6. Int const *pci; /*指向常整型的指针*/
Int * const cpi; /*指向整型的常型指针*/
说明:类似于const的修饰符遵循左结合优先的原则;(Page39)
7. 在ANSI C标准中 把函数形参的作用域设定为函数最外层的作用域(即为整个函数体)。(Page41)
8. 数据的存储类型分为:普通内存,运行时堆栈,时间寄存器。(Page43)
9. static: 当static关键用于修饰标示符的属性时,标示符的链接属性从external改为internal,但标示符的存储类型和作用域不受影响。即表明标示符为文件内访问。
当static 用于代码块内部(“{ }”花括号中为代码块),static关键字用于修改变量的存储类型,即从自动变量修改为静态变量。(Page45)
10. C语言中没有布尔类型,条件判定为整型代替,其规则为:
零未假,任何非零值皆为真!!(Page78)
11. 当定义结构体的时候必须注意内存对齐,比如:
struct struct_test
{
int b;
char a[3];
};
与
struct struct_test
{
char a[3];
int b;
};
Sizeof(struct_test)的值都是8.因为需要考虑内存对齐。(Page92)
12. 注意:对指针进行间接访问(*p操作),必须对指针进行初始化。(Page12)
13.一种比较好的函数定义风格:
类型
函数名( 形参列表 )
函数代码块
如:
Void
Function( void )
{
Do samething
}
因为这样的编程风格可以使我们在使用视觉或某些工具追踪代码时更容易找到函数名。(Page117)
14. C 语言中数组并不完全等价于指针,比如:
指针和数组不等价情况举例:
int iArrary[10], *pi;
sizeof( iArrary ) == 40, 而sizeof( pi ) = 4 ; ( sizeof 操作符或单目操作符&的操作数为数组名时,sizeof(数组名)返回数组的长度,sizeof ( 指针)返回指针变量的字节宽度; &( 数组名 ) 返回数组的首地址,而不是某个指针常量值的指针,而&( 指针 )返回指向该指针变量的指针 );(Page142)
指针和数组等价情况举例:
int strlen( char *string );
int strlen( char string[] );
这两个指针等价只是当前上下文环境中,编译器会将string[]解析成一个指针。这样做只是为了让函数形参更直观,在这两个函数体内部执行sizeof( string ) 的返回值都是4,说明strng [] 被解析成了指针。(Page152)
15. 当一个函数需要重复调用很多次,并且函数中有需要初始化的数组成员变量,此时每次调用都会对数组进行初始化,从效率上讲这个不值得。可以将数组申明成static 这样数组的初始化只需在程序的第一次运行时执行一次。(Page153)
16. 区分两个不同的字符串初始化方式:
char message1[] = “Hello”;
char *message2 = “hello”;
其中char message1[] = “Hello”,等价于char message1[] = {‘H’,’e’,’l’,’l’’,’0’,’\0’};是一个数组的初始化,message1被申明为一个字符数组;而char *message2 = “hello”,是一个指针的初始化,message2此时为一个指针初始化指向一个常量字符串;(Page153)
17.关于字符串的讨论:
库函数 strlen 的函数原型如下:
size_t strlen( char const *string );
其中size_t 为函数的返回值类型,它在stddef.h被定义为一个无符号整型。而在表达式中使用无符号数可能导致不可预料的结果。举例如下:
If ( strlen( x ) >= strlen( y ) ) ……
If ( strlen( x ) – strlen( y ) >= 0 )……
但是事实上他们是不相等的。第一条语句执行正常。而第二条语句将会永远为真,strlen的结果是个无符号数,所以strlen( x ) – strlen( y ) 也是无符号数,而无符号数是永远 >=0的。(Page176)
18. 对于如下字符串处理函数:
char *strncpy( char *dst, char const *src, size_t len );
char *strncat( char *dst, char const *src, size_t len );
char *strncmp( char *dst, char const *src, size_t len );
如果strlen( src ) 的值小于len, dst数组就用额外的NULL字节填充len长度,如果strlen( src ) 大于或者等于len , 那么只有len个字符被原样复制到dst中。注意:他的结果将可能不会以NULL字节结束。 所以strncpy,strncat的调用结果可能不是一个字符串 。
处理办法如下:
char buffer[BSIZE];
…….
strncpy(buffer,someStr,BSIZE);
buffer[BSZIE - 1] = ‘\0’; (Page180)
19. struct
{
int a;
char b;
} x;
struct
{
int a;
char b;
} y[20] , *z;
这两个声明会被编译器当做两个截然不同的类型,即使他们的成员列表完全相同。因此,变量 y 和 z 与 x 的类型不同,所以, z = &x 是非法的。(Page196)
20.void* malloc( size_t size ) 函数的一些讨论:
a. malloc 的参数是以字节为单位的.
b. malloc 所分配的是一块连续的内存。
c. 基于b,malloc调用有失败的可能,所以每次对malloc的返回指针都要进行NULL检测,这个很重要。(Page222)
21. free( void * ); free 不能释放非堆内存。 同时free( p ); p 所指向的地址没有改变。在 必要的时候需要将p置空;free(p) ; p = NULL;( 学习心得 )
22. errno 是C语言中库函数执行过程中的错误代号,但是需要注意的是,只有当库函数失败时,errno 才会被设置。当函数成功运行时,errno 的值不会被修改。这个意味着我们不能通过测试errno 的值来判断是否有错误发生。反之,只有当被调用的函数提示有错误发生时检测errno 才有意义。(Page298 注:暂存的内容只能恢复到当前文章的编辑器中,如需恢复到其他文章中,请编辑该文章并从暂存箱中恢复;或者直接复制以上内容,手工恢复到相关文章。