C语言中++、-- 及编译器的贪心法

本文深入探讨C语言中自增自减运算符的使用及潜在陷阱,通过实例分析表达式求值顺序和编译器行为,揭示运算符的正确使用方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言中的++、–即自增、自减是很令人头疼的。
刚好看到一个问题,一起分析一下。

int i = 3;
(++i) + (++i) + (++i);

你觉得这个表达式的值是多少?
如果你觉得是15,那完了,你c语言学的跟我一样,太烂了。
我去查了一下,有说是16,还有说是18的。分析了一下,好像都有道理。
如果是都先做完括号内的,那答案就是18了。
但编译器如果认为前两个括号做完,然后会认为后面是加号,和前面一样的,前面两个便可以先进行计算,结果就是16。
分析完了,就直接去运行看结果吧,我使用了gcc和g++编译,结果都是16。后来问大佬,查资料,据说这是c语言的灰色地带,没有明确规定,结果会因编译器规则不同而不同。

继续看另一段代码:

#include <stdio.h>

int main()
{   
    int i = 0;
    int j = ++i+++i+++i;//报错1
    
    int a = 1;
    int b = 2;
    int c = a+++b;
    
    int* p = &a;
    
    b = b/*p;//报错2
      
    return 0;
}

你觉得j的结果是多少?
实际是这里会报错,

[Error] lvalue required as increment operand

说左值不可以增运算,为什么报这错呢?因为编译器是贪心法阅读代码:
编译器处理的每个符号应该尽可能多的包含字符
编译器以从左向右的顺序一个一个尽可能多的读入字符
当即将读入的字符不可能和已读入的字符组成合法符号为止
所以看上面的j那一行可分析到一次读,会一直读到++i++为止,我们知道++i返回是值,值自然不可以进行运算,所以报错。我们通常应该加上括号,已明确运算顺序。

修改之后,再编译,发现上面的第二个报错,这个又为什么报错呢,如果用ide编辑代码,就会发现从/*开始都认为是注释了。就是我们之前提到的编译器的贪心法了,认为是注释开头了。

对此,通常编程规范中都会有规定,对于运算都明确加括号以明确运算顺序。另外就是我们会发现,使用很多ide编程的时候,在我们例如加上结束符之后,会帮我们格式化,这时你都会发现运算对象和运算符之间都会有空格,其实这不光光是美观,编译器会识别空格,知道这里是读入结束。
了解了这些知识,修改上面的代码:

#include <stdio.h>

int main()
{   
    int i = 0;
    int j = ++i+ ++i+ ++i;
    
    int a = 1;
    int b = 2;
    int c = a+++b;
    
    int* p = &a;
    
    b = b/ *p;
      
    return 0;
}

不光看的清晰,编译运行完美了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值