我们在 C 语言中会经常见到 ++ 和 -- 操作符, 笔试题中也经常见到. 下我们就来分析这两个操作符.
++ 和 -- 操作符对应两条汇编指令, 前置时: 变量自增 (减)1 后取变量值; 后置时: 取变量值后变量自增 (减)1.
下来我们来看个示例代码, 代码如下:
- #include <stdio.h>
- int main()
- {
- int i = 0;
- int r = 0;
- r = (i++) + (i++) + (i++);
- printf("i = %d\n", i);
- printf("r = %d\n", r);
- r = (++i) + (++i) + (++i);
- printf("i = %d\n", i);
- printf("r = %d\n", r);
- return 0;
- }
我们分析第 8 行, i++ 执行 3 次, r = 0 + 1 + 2 = 3; i = 3; 第 13 行 r = 4 + 5 + 6 = 15; i = 6; 我们来看看 gcc 下编译的结果是多少
我们看到最后的 r 打印的是 16, 跟我们分析的不一样. 那么我就直接告诉大家答案了, 这块需要去反汇编看看代码是怎么执行的. 通过查看汇编代码, 我们发现在 gcc 中, 它先是自增两次然后相加, 再次自增一次, 再加上 6, 结果就是 16 了. 有兴趣的同学可以自己去反汇编, 看看代码是怎样执行的. 我们再来看看 BCC 这款编译器执行的结果是怎样的
我们发现最后一个 r 和我们分析的一样, 但是第一个 r 为 0, 这是怎么回事呢? 还是得通过反汇编代码来看, 它是这样执行的, 先把 0 拿出了加三次, 再次自增 3 次. 所以第一个 r 为 0, 而 i 为 3.
在 C 语言中只规定了 ++ 和 -- 对应指令的相对执行次序;++ 和 -- 对应的汇编指令不一定连续执行; 在混合运算中,++ 和 -- 的汇编指令可能会被打断执行, 换句话说,++ 和 -- 参与混合运算的结果是不确定的.
我们会在一些笔试题中遇到这样一些题目: 1,++i+++i+++i;2,a+++b; 那么我们在遇到这些题目时该怎样去解答呢? 在 C 语言中它的处理是贪心法, 即: a> 编译器处理的每个符号尽可能多的包含字符; b> 编译器以从左向右的顺序一个一个尽可能多的读入字符; c> 当读入的字符不可能和已读入的字符组成合法符号为止.
我门下来就来分析个示例代码, 代码如下:
- #include <stdio.h>
- int main()
- {
- int i = 0;
- int j = ++i+++i+++i;
- int a = 1;
- int b = 4;
- int c = a+++b;
- printf("i = %d\n", i);
- printf("j = %d\n", j);
- printf("a = %d\n", a);
- printf("b = %d\n", b);
- printf("c = %d\n", c);
- return 0;
- }
我们来分析下, 第 6 行相当于 j = ++i++ ==> 1++, 这样会出错, 因为 1++ 不是个合法的表达式. 第 10 行相当于 c = a+++b ==> c = 1 + 4 ==> c = 5; 这时 a = 2;
我们编译的时候第 6 行出现错误
那么我们在下面加上一句 1++, 看看打印的错误提示是否和上面的一样呢
大家看到两句错误提示一样, 证明我们的分析是对的, 我们屏蔽后再次执行
我们看到 a = 2, c = 5 和我们分析的一样. 那么我们在平时的书写中可以加上空格, 空格可以作为 C 语言中的一个完整符号的休止符, 编译器读入空格后立即对之前读入的符号进行处理. 同时加入空格也可以增强程序的可读性.
通过本次 ++ 和 -- 操作符的学习, 我们总结如下: 1,++ 和 -- 操作符在混合运算中的行为可能不同; 2, 编译器通过贪心法处理表达式中的字表达式; 3, 空格可以作为 C 语言中一个完整符号的休止符, 编译器读入空格后立即对之前读入的符号进行处理. 后面我们会继续对 C 语言的学习.
来源: http://www.bubuko.com/infodetail-2557929.html