• 第17课 ++和--操作符分析


    1. ++和—操作符对应的两条汇编指令

    (1)前置++或--:变量自增(减)1,然后取变量值

    (2)后置++或--:取变量值,然后变量自增(减)1

    【实例分析】一对令人头疼的兄弟

    #include <stdio.h>
    
    int main()
    {
        int i = 0;
        int r = 0;
    
        r = (i++) + (i++) + (i++);
    
        printf("i = %d
    ", i); //i等于3
        printf("r = %d
    ", r); //vc下r=0,gcc也等于0
    
        r = (++i) + (++i) + (++i);
    
        printf("i = %d
    ", i); //i等于6
        printf("r = %d
    ", r); //vc下r=18,gcc下等于16,java下等于15;
        return 0;
    }

    2. C标准对++和—运算符的规定

    (1)C语言中只规定了++和—对应指令的相对执行次序(即两条汇编指令的前后顺序是有规定的,但不一定要紧紧相邻!

    (2)但他们的汇编指令不一定连续运行,在混合运算中,其汇编指令可能被打断执行。(即上述两条汇编指令中间可能会被其他指令穿插进来,从而导致这两条指令不能连续、紧凑地执行)。

      ▲++和—参与混合运算,结果是不确定的。

    3. 笔试面试中的“奇葩”题

    4. 贪心法:++、--表达式的阅读技巧

    (1)编译器处理的每个符号应该尽可能多的包含字符

    (2)编译器从左到右一个字符一个字符地读入,如果该字符可能组成一个符号,那么再读入下一个字符,判断已经读入字符组成的字符串是否可能是一个符号的组成部分;如果可能,继续读入下一下字符。

    (3)重复上述判断,直到读入的字符组成的字符串已不再可能组成一个有意义的符号。

    (4)空格可以作为C语言中一个完整符号的休止符,当编译器读入空格后立即对之前读入的符号进行处理。

      ▲理解贪心法的关键:当读取的字符串还是一个有意义的符号(或表达式时)并不会停止读入,而是继续读入下一个字符,直至完全不再可能组成一个有意义的符号为止。

    【实例分析】贪心法阅读示例

    #include <stdio.h>
    
    int main()
    {
        int i = 0;
    
        //处理过程:读入第1个字符+,加号是有意义的,因为他可以与其他符号再组成(如组成++
        //或加另一个变量,因此读取并不会停止),于是继续读入第2个字符+,编译器发现是
        //一个自增运算符,会继续读入后面的变量i,得++i。这时这个符号仍是有意义的。
        //但根据贪心法,还会再读入一个字符,即++i+,表示++i后面
        //会加上一个数,这也是有意义的。所以会再读入第5个字符,这里发现己经读入的字符串
        //己经不再可能变成一个有意义符号。所以会停止读入字符转向去处理之前读读入的这个子
        //表达式,这时会先++i,即得到1,然后++,即1++,所以便会出错。
        int j = ++i+++i+++i;
    
        int a = 1;
        int b = 4;
        int c = a+++ b; //读到a++是有意义的,会再读入一个字符+,仍有意义,会再次读入b,即(a++) + b
    
        int* p = &a;
    
        b = b/*p; //读到“b/”是有意义的,因为b可以去除一个数。所以会继续读到b/*,这时发现这个
                  //字符串不可能再任何意义了,所以停止读取。但b/*这个表达式是非法的,所以编译器
                  //会报错。同时/*会组成多行注释的开始,所以编译会把/*会面的内容当成注意的内容。
    
        printf("i = %d
    ", i);
        printf("j = %d
    ", j);
        printf("a = %d
    ", a);
        printf("b = %d
    ", b);
        printf("c = %d
    ", c);
    
        return 0;
    }

    5. 小结

    (1)++和—操作符在混合运算中的行为可能不同

    (2)编译器通过贪心法处理表达式中的子表达式

    (3)空格可以作为C语言中一个完整符号的休止符

    (4)编译器读入空格后立即对之前读入的符号进行处理。

  • 相关阅读:
    整数m去掉n位后剩下最大(小)值
    蛇形矩阵(二)
    Kibana源码启动报错记录--ENOSPC
    Kibana问题记录:yarn test 运行报错 error Trailing spaces not allowed no-trailing-spaces
    Vim 编辑器中全选操作
    Ubuntu系统中连接TFS的Git地址注意事项
    Ubuntu系统升级遇到问题记录
    Kibana6.2.x 插件理解
    Kibana问题搜集---下载源码,执行npm install 报错
    Kibana6.2.2源码入口
  • 原文地址:https://www.cnblogs.com/5iedu/p/5324332.html
Copyright © 2020-2023  润新知