《C专家编程》读书笔记
第二章 这不是Bug,而是语言特性
2.1 这管语言特性何事,在Fortran里这就是Bug呀
------------------------------------------------
malloc(strlen(str)+1); //注意字符串结尾的‘\0’字符
------------------------------------------------
一个'L'的NUL用于结束一个ACSII字符串,
两个'L'的NULL用于表示什么也不指向(空指针)。
-------------------------------------------------
2.2 多做之过
switch语句的fall through会带来麻烦,fall through指:若case后无break,程序将继续执行下个case/default(有的话)的内容。
switch语句中尽量避免使用标签,否则将产生意想不到的麻烦。
软件信条:缺省采用“fall through”,97%的情况下都是错误的。
另外,注意,break语句事实上跳出的是最近的哪层虚幻语句或switch语句,不能用来跳过if语句。
------------------------------
ANSI C特性:相邻的字符串常量将被自动合并成一个字符串的约定。
旧风格:
1 printf( " A favorite children's book \ 2 is 'muffy Gets It: the hilarious tale of a cat,\ 3 a boy, and his machine fun'");
新风格:
1 printf( “A second favorite children's book" 2 "is 'Thoms the tank engine and the Naughty Enginedriver who" 3 "tied down Thomas's boiler safety value'");
然而,这种自动合并意味着字符串数组在初始化时,如果不小心漏掉了一个逗号,编译器将不会发出错误信息,而是悄无声息地把两个字符串合并在一起。
---------------------------------------------------
使一段代码第一次执行时的行为与以后执行不同。这种方法能是分支和条件检测减少到最小程度。
1 generate_initializer(char * string) 2 { 3 static char separator = ' '; 4 printf( "%c %s \n", separator, string); 5 separator = ','; 6 }
在第一次执行时,函数首先打印一个空格,然后打印一个初始化字符串。所有初始化字符串(如果有的话)的前面将加上一个逗号。
“第一次执行的前面加个空格”相比“最后一次执行,省略逗号后缀”对程序而言更简单了。
----------------------------------------------------------------------
2.3 误做之过
C语言中的符号重载
符号 | 意义 |
static |
在函数内部,表示该变量的值在各个调用间一直保持延续性 在函数这一级,表示他在其他地方定义 |
extern |
用于函数定义,表示全局可见(属于冗余) 用于变量,表示它在其他地方定义 |
void |
作为函数的返回类型,表示不返回任何值 在指针声明中,表示通用指针类型 位于参数列表中,表示没有参数 |
重载存在问题:第一条语句中一个乘号还是两个?
1 p = N * sizeof * q; 2 r = malloc(p);
答案是:一个。因为当sizeof的操作数是个类型名(如int)时,两边必须加上括号(这常常使人误以为它是个函数),但操作数如果是个变量,则不必加括号。
所以,它是把指针q指向的东西(即*q)作为操作数,它返回q所指向对象的类型的字节数,便于malloc函数分配内存。
-----------------------------------------------------
C语言运算符优先级存在的问题
优先级问题 | 表达式 | 实际结果 |
.的优先级高于* ->操作符用于消除这个问题 |
*p.f |
等效于p->f *(p.f) |
[]高于* | int *ap[] |
安排是个元素为int指针的数组 int*(ap[]) |
函数()高于* | int*fp() |
fp是个函数,返回int* int*(fp()) |
==和!=高于位操作符 | (val & mask != 0) | val & (mask != 0) |
==和!=高于赋值符 | c = getchar() != EOF | c = (getchar() != EOF) |
算术运算高于以为运算符 | msb<<4+lsb | msb << (4 + lsb) |
逗号运算符在所有运算符中优先级最低 | i = 1, 2 | (i = 1), 2 |
...