《C专家编程》笔记(二)——C语言的语言特性

1. 一段代码,第一次执行时的行为与以后执行时不同:

1 generate_initializer(char * string)
2 {
3     static char separator = ' ';
4     printf("%c %s \n", separator, string);
5     separator = ',';
6 }

可用于自动生成列表。

 

2. 函数的可见性

1 function apple() { /* 在任何地方均可见 */ } 
2 extern function pear() { /* 在任何地方均可见 */ } 
3 
4 static function peach() { /* 在这个文件之外不可见 */ } 

 

3. 这个语句p = N * sizeof * q;当中的乘号有几个?一个还是两个?

答案是一个。因为sizeof的操作数是类型名的时候,两边必须加上括号,但操作数如果是变量,则不必加括号。

那这个语句呢:apple = sizeof(int) * p;

是int类型的长度乘以p呢,还是?

 

4. 优先级的问题

*p.f是*(p.f),对p取f偏移作为指针,再解引用。

int *ap[]是int *(ap[]),指针的数组。

int *fp()是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

 

5. 记住,在优先级和结合性规则告诉你哪些符号组成一个意群的同事,这些意群内部如何进行计算的次序始终是未定义的。在这个表达式里:

  x = f() + g() * h();

乘法比加法优先级高,但是f()、g()、h()的调用次序是未定义的。

 

6. gets()函数对读入的字符数未做检查,容易导致缓冲区溢出。所以我们应该用fgets()彻底取代gets()。

char *fgets(char * restrict s, int n, FILE * restrict stream);

 

7. ANSI C规定编译器词法分析中采取maximal munch strategy策略,选取能组成的最长字符序列的方案。

所以z = y+++x就被解释为z = y++ + x;

那么z = y+++++x呢?它被解释为z = y++ ++ +x,引发编译错误。因为y++返回的是右值,而自增操作只支持左值。

 

8. 作者给出了

a //*

//*/ b

这个例子,说在C语言里表示a/b,在C++里表示a。

但是ANSI C的新标准已经将//当成了C的行注释符号。所以这个例子已经不适用。

 

9. 返回一个字符串的几种方案:

  返回一个指向字符串常量的指针;(不能被改写)

  使用全局声明的数组;(浪费空间)

  使用静态数组;(不可重入,且同样耗费空间)

  在函数内显式动态分配内存,保存返回的值;(程序员必须回收内存)

  要求调用者分配内存来保存函数的返回值,同时指定缓冲区的大小(like fgets())。

 

posted @ 2014-11-20 11:49  nipan  阅读(280)  评论(0编辑  收藏  举报