这不是bug,而是语言特性
Posted 悄然拔尖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了这不是bug,而是语言特性相关的知识,希望对你有一定的参考价值。
分析编程语言缺陷的一种方法是把所有的缺陷归于3类:不该做的做了,该做的没做,该做但做得不合适。
在使用switch case时,如果使用缺省的 fall through,请一定在旁边注释,因为97%的情况需要使用break,break跳出的是最近的那层循环或者switch语句。
下面代码,第一次调用和之后调用会出现不同:
1 #include<stdio.h> 2 3 void generate_initializer(const char * string) 4 { 5 static char separator=\' \'; 6 printf("%c %s\\n",separator,string); 7 separator=\',\'; 8 } 9 int main(void) 10 { 11 char *p="hi,guy,would you want strengh!"; 12 generate_initializer(p); 13 generate_initializer(p); 14 generate_initializer(p); 15 return 0; 16 }
所以,static使用要走点心。
太多的缺省可见:
定义c函数时,不管你加不加extern修饰,函数名都是全局可见的,这是缺省状态,除非你用static修饰。
一个文件要么全局可见,要么对其他文件不可见。在C语言中,对信息可见性的选择就是这么有限。如果别人问你C语言什么让你觉得难,你可以回答不支持很多特性,千万别回答指针就好^_^。
C语言中的重要符号重载:
static:用在函数内部,表示变量的值在各个调用间一直保持延续性,这句话有点拗口,用通俗一点的话语就是,static修饰的局部变量,只初始化一次,而且它的值会一直保存。
用来修饰一个函数时,表示该函数只对本文件可见。
extern:用于修饰变量时,表示变量在其他地方(外部文件)定义了
用于函数的时候表示全局可见,属于冗余的,因为函数缺省状态就是全局可见的。
当sizeof的操作数是类型名时,两边必须加上括号(这通常让人误以为它是一个函数),但操作数如果是变量则不必加括号。sizeof是运算符。
优先级可以查看c和指针81页和c2p 最后一页。
现在有如下表达式:
apple=sizeof(int)*p;你觉得这个表达式应该如何解读?
A:这里又很多种可能的解释,但是为了不误导或者留下误导的索引,直接分析了。
sizeof ,强制转化的括号()和解引用*的优先级相同,所以,要是解释为:解引用指针p强制转换成int再sizeof肯定是不对的,为什么呢?它们三个的结合性都是从右向左的,所以sizeof(int)已经结合,要是*p再结合,编译器必然要报操作符错误,我们可以再加上一个乘号*,这样就明了了。
1 #include<stdio.h> 2 3 int main(void) 4 { 5 char tmp=\'a\'; 6 char *p=&tmp; 7 int res; 8 res=sizeof(int)**p; 9 printf("%d\\n",res); 10 return 0; 11 }
要是不加一个操作符乘号*上去,会报错:
从这里我们可以知道,上面的写法是sizeof(int),其中括号不表示强制转化,表示聚组功能,优先级比sizeof还高。
三个尤其注意的优先级问题:
1.==和!=的优先级高于&或|
2.算术运算高于一维运算:msb<<4+lsb 等价于msb<<(4+lsb)
3.逗号运算符优先级最低,比赋值都低:i=1,2 等价于(i=1),2
空格——最后的领域:
“\\”反斜杠,用在宏上时,后面不要接空格,应该直接换行,
#include<stdio.h> #define my 111\\ 0 #define you 111\\ 0 int main(void) { printf("%d\\n%d\\n",my,you+1); return 0; }
预编译之后,111和0之间还是有空格的,所以反斜杠让我们书写宏的时候可以在多行操作,但是不能用于连接字符,因为会多出空格,同样,在多出空格不会影响代码的时候,反斜杠“\\”后面也不应该加空格,应该直接换行。
#include<stdio.h> int main(void) { char a[]="abc\\ d"; printf("%u\\n",sizeof(a)); char b[]="abcd"; printf("%u\\n",sizeof(b)); return 0; }
多出一个空格,这个是转义回车造成的。
同样,在z=y+++++x;这样的表达式中,我们需要空格,不然编译器无法解析上面的代码,应该手动空格分离为:
z=y++ + ++x;这样编译器才知道上面意思。在这样的表达式中,ANSI C规定了一种逐渐为人熟知的”maximal munch strategy”(最大一口策略)。这种策略表示如果下一个标记有超过一种的解决方案,编译器将选取能组成最长字符序列的方案,例如:z=y+++x;会被编译器分解成z=y++ + x;因为第一个+之后,后面还有一个+,可以组成最长字符++.但是上面那个z=y+++++x;不手动加空格就不能被编译器正常分解,编译器正常分解成z=y++ ++ +x;这样会报错。
以上是关于这不是bug,而是语言特性的主要内容,如果未能解决你的问题,请参考以下文章