【C语言】一文弄通++i,i++,i--,--i,解决粉丝疑问

前言

前两天粉丝问了我个问题,关于i++,++i,--i,i--的问题,一下子让我想起了自己初学C语言被这个加加减减运算符支配的恐惧。

不过当时好像是为了考计算机二级,面对了这些变态的题。

我:???大意了呀,万万没想到,这个坑这么大

粉丝的问题如下:

不过,身为拯救万千少女的美男子(pia,别做梦了,哪里来的妹纸,没有妹纸的话,能给个富婆吗,我不想努力了)

废话不多说,赶紧进入正题咯,今天就给大家捋一捋这个加加减减运算符

一、加加减减运算符

++是自增运算符,变量调用自增运算符之后,值会+1

--是自减运算符,变量在调用自减运算符之后,值会-1

举个例子,看下面代码帮助大家理解,自增自减运算符的基本使用

#include <stdio.h>
int main(){
    int i_baiyu=66;//声明一个整型变量 i_baiyu 并且赋值为66
    i_baiyu++;//这里的效果相当于 i_baiyu = i_baiyu +1
    printf("i_baiyu++之后的值为:%d",i_baiyu);//这里输出 67
    ++i_baiyu; //这里的效果相当于 i_baiyu = i_baiyu +1
    printf("++i_baiyu之后的值为:%d",i_baiyu);//这里输出 68
    
    i_baiyu--;//这里的效果相当于 i_baiyu = i_baiyu - 1
    printf("i_baiyu--之后的值为:%d",i_baiyu);//这里输出 67
    --i_baiyu; //这里的效果相当于 i_baiyu = i_baiyu - 1
    printf("--i_baiyu之后的值为:%d",i_baiyu);//这里输出 66
    return 0;
}

大家可以看到上面的代码,其实自增运算符,自减运算符,放在变量前面跟放在变量后面的区别并不大。从运算结果可以发现,仅从i_baiyu的值来看,++ i_baiyu和i_baiyu ++最终的i值是一样的,都是i_baiyu自增加了1。

但是其实还是有一点小区别的

i_baiyu++是在每次使用完 i_baiyu 后自动+1 ,

另外一种是++ i_baiyu 区别于第一种,是在使用 i_baiyu 前自动+1

示例代码如下:

#include <stdio.h>
int main() {
    int i_baiyu = 66;
    printf("i_baiyu的值为:%d\n", i_baiyu);
    int i_x = i_baiyu++;//执行完该语句i_x的值为66,i_baiyu的值变成67
    printf("i_x的值为:%d,i_baiyu的值为:%d\n", i_x, i_baiyu);
    int i_y = ++i_baiyu;//执行完该语句i_y的值为68,i_baiyu的值为68
    printf("i_y的值为:%d  i_baiyu的值为:%d\n", i_y, i_baiyu);
}

二、粉丝的问题

就当一切都看起来渐入佳境的时候,粉丝的问题来了

为什么他的程序,执行后的结果是【8,8,7,8,-9,-8】

按照咱们上面的理论,不应该是,【9,9,8,8,-8,-7】

代码如下:

#include<stdio.h>
#include<stdlib.h>
int main()
{
    int i = 8;
    printf("%d\n%d\n %d\n%d\n %d\n%d\n",++i,i--,i++,--i,-i--,-i++);
    system("pause");
    return 0;
}

出现上面的问题是因为这道题目里面除了上面一个加加减减运算符之外,还有一个坑,那就是printf()函数的参数计算顺序

三、printf()函数参数计算顺序

#include<stdio.h>
int test01() {
    printf("这是test01\n");
    return 1;
}
int test02() {
    printf("这是test02\n");
    return 2;
}
int test03() {
    printf("这是test03\n");
    return 3;
}
int main()
{
    printf("%d---%d---%d", test01(), test02(),test03());
}

由输出结果可以看出,printf()函数的参数计算顺序是从右往左开始计算,而输出的值的顺序则是从左往右输出的

这样子粉丝的问题就迎刃而解了?

我们从左往右开始计算之后会发现,值是【9,8,7,7,-9,-8】

这个的值,还是跟编译器计算出来的值不一样。先算后用的最高境界,就是等所有运算完了之后,再取最终的值来用。(这里这么解释不是到对不对,如果有误,还请各位批评指正。)

综上所述,实际上粉丝问题程序的流程如下:

  1. -i++ 先用后算,-8
  2. -i--先用后算,-9
  3. --i 先算,此时i的值为7
  4. i++先用后算,i为7,执行后i的值为8
  5. i--先用后算,i为8,执行后,i的值为7
  6. ++i,先算后用,i为8,这里第三步时的--i位置的i值也为8
  7. 输出结果【8,8,7,8,-9,-8】

懂汇编的同学也可以看一下这程序对应的反编译代码,也印证了printf()函数的参数运算顺序是从右往左的

总结

终于,把粉丝的问题给搞懂了,也水了一篇博客出来。

有一说一,弄懂加加减减运算符怎么用就好了,像printf()的参数里带了一大堆的++i,--i这种骚操作,正常人在编程的时候也不会用上,真的除了学校考试跟考计算机二级C语言时,才会有这种变态的题。

特别感谢这位粉丝的提问,让我重新感受了被加加减减运算符支配的恐惧。

最后,感谢一下身边帮忙的小伙伴,有1_bit大神,二当家的白帽子,程序猿小贺,安之ccy,小丞同学,漏了名字的就评论留言下,在评论感谢你们~

如果觉得有帮助的话,欢迎一键三连支持一下我,您的支持,是我持续创作的动力