短路与断路
逻辑或‘||’运算符从左向右开始计算,当遇到条件为真时停止计算,整个表达式为真,只有当所有条件为假时逻辑式才为假。
逻辑与‘&&’运算符从左向右开始计算,当遇见条件为假时停止计算,整个表达式为假,只有当所有条件为真时逻辑式的值才为真。
左移与右移运算符
左操作数必须为整数类型;
char与short作为左操作数时被隐式转换为int后进行移位操作,右操作数的范围必须为[0,31];
左移运算符‘<<’将运算数的二进制位左移,最高位补符号位,高位丢弃,低位补零
右移运算符‘>>’将运算符的二进制位右移,最高位补符号位,低位丢弃,高位补零
当左移或者右移操作数超过范围,我们就不能确定编译器会做什么。
++和–
(i++)+(i++)+(i++)在C语言中是一个灰色地带,不同的编译器对这语句有不同的解释。++与—参与混合运算的结果是不确定的,我们要避免这种事。
编译器读入符号规则:
编译器从左向右的尽可能多的读入字符,直到当读入的字符不可能与已读入的字符组成合法符号为止。
例如:
++i+++i+++i; //编译出错,因为这条语句被编译器解释为((++i)++)……处理完了++i后为(1++),而常量是不能进行自增运算的
a+++b; //编译通过,这条语句被编译器解释为(a++)+b
空格的意义
空格在C语言中可以作为一个完整符号的休止符,编译器在读入空格后立即对之前读入的符号进行处理
三目运算符
三目运算符返回的是一个值,不是变量。
灵活运用三目运算符的一个实例:*(a < b ? &a : &b)= 3;
三目运算符(a ? b : c;)的返回类型:通过隐式转换b和c中的较高类型,当b和c不能隐式转换成一种类型时将编译出错。
逗号表达式
逗号表达式用于将多个表达式连接为一个表达式,逗号表达式的值为最后一个表达式的值。
逗号表达式的前n-1个式子可以没有返回值。
逗号表达式按照从左向右的顺序计算每个子表达式的值
编译过程
-
预处理:处理所有的注释,以空格代替;将所有的#define删除,并展开所有的宏定义;处理条件编译指令#if、#ifdef、#ilef、#else、#endif;处理#include,展开被包含的文件;保留编译器需要使用的#pragma指令。
-
编译:对预处理文件进行词法分析、语法分析与语义分析;
:词法分析 分析关键字、标识符、立即数等是否合法
:语法分析 分析表达式是否遵守语法规则
:语义分析 在语法分析的进一步基础上分析表达式是否合法
分析结束后进行代码优化生成汇编代码文件。
- 汇编:汇编将汇编代码转换成目标文件,每条汇编语句都被编译成对应的机器指令。
注意:此时的目标文件仍然不能被电脑执行
- 链接:链接源文件中使用到的各种库文件,将各个目标文件与动态库文件打包成可执行文件。静态链接:由链接器在链接时将库的内容直接加入到可执行程序中;动态链接:可执行文件在运行时才动态加载库链接。库的内容不会进入到可执行程序