首页 > 代码库 > C语言中容易被忽略的细节(第一篇)
C语言中容易被忽略的细节(第一篇)
前言:本文的目的是记录C语言中那些容易被忽略的细节。我打算每天抽出一点时间看书整理,坚持下去,今天是第一篇,也许下个月的今天是第二篇,明年的今天又是第几篇呢?……我坚信,好记性不如烂笔头。
1、 在C语言中,符号之间的空白(包括空格符、制表符或换行符)将被忽略。但一个符号的中间不能有空白,否则可能被解释为另一个或几个符号。以下两种写法是等价的:
//写法1 if (x > big) big = x; //写法2 if ( x > big ) big = x ;
2、编译器将程序分解为符号的“贪心法”(大嘴法)
从左到右逐个字符读入,如果该字符可能会组成一个符号,那么再读入下一个字符,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分;如果可能,继续读入下一个字符,重复上述判断,直到读入的字符组成的字符串已经不再可能组成一个有意义的符号为止。例如:
(1)a---b 与 a -- - b的含义相同,与a - -- b的含义不同。
(2)n-->0的含义是n-- > 0。
3、如果一个整型常量的第一个字符是数字0,那么该常量将被视为8进制数。例如:010实际表示为十进制中的8,它与10不同。
4、用单引号引起的一个字符实际上代表一个整数,整数的值等于该字符在编译器采用的字符集的序列值。例如:’a’的含义与0141(八进制)或97(十进制)严格一致。用双引号引起的字符串,代表的是一个指向无名数组起始字符的指针,该数组被双引号之间的字符以及一个额外的2进制值为0的字符’\0’初始化。
5、a++为什么不能作为左值?
a++和++a的具体实现为:
//a++的实现 int temp; temp = a; a = a + 1; return temp; //++a的实现 a = a + 1; return a;a++返回的是编译器自动分配的临时变量temp,这个temp并不是程序中定义的可寻址变量的引用,不能作为左值。而++a返回变量的引用。例如:
(1)i++ = 5,是错误的。++i = 5,是正确的。
(2)a+++++b,是错误的。因为它等价于a ++ ++ + b,即(a++)++ + b,a++不能作为左值,++运算需要左值。
(3)++a+++b,同样是错误的。
6、转义序列
有些字符具有特殊含义,想要将它们输出到终端上,一般有两种方式:使用转义序列或直接引用ASCII码值。
(1)转义序列:用反斜线(\)后跟一个特定转义字符组成的。常见转义序列如下表:
(2)直接引用ASCII码值:在字符串中可使用\o、\oo或\ooo(o为八进制数),\xh(h为16进制数)表达特殊字符。
7、输入 EOF 的方法:Windows/MS DOS 环境下,Ctrl+Z。Unix/Linux环境下,Ctrl + D。OS/400环境下,F4。
8、如何得到类型的类型转换符?
把声明中的变量名和声明末尾的分号去掉,再将剩余的部分用一个括号整个“封装”起来。例如:
(1)float (*h)();h是一个指向返回值为浮点类型的函数指针。(float (*)())表示“指向返回值为浮点类型的函数指针”的类型转换符。
(2)将常数0转型为“指向返回值为void的函数函数指针”类型的写法:(void (*)())0。
9、函数指针的调用形式
例如:void (*fp)();有两种调用形式:(*fp)()、fp()。fp()这种写法只是一种简写形式。
10、运算符的优先级
关键:任何一个逻辑运算符的优先级低于任何一个关系运算符;移位运算符的优先级比算术运算符要低,但是比关系运算符要高。
C语言中容易被忽略的细节(第一篇)