【C/C++】变量自加/自减运算小白释疑篇

7 篇文章 0 订阅

现在很多非常0基础的初学者都搞不清楚i++和++i的区别,打集训题的同时偶遇此题,想起了五年级时理解i++的痛苦经历,其实说白了就是那时太小,还没理解参数传递、赋值、内存等。我相信这也是一些年纪比较小的初学者会遇到的问题。

于是写此文以试用多种角度解释变量自加运算符间区别,以及实际使用时注意事项。如遇大佬请狠狠批评指正,以免误人子弟。

问题 M: 9.变量自加运算

内存限制:128 MB时间限制:1.000 S

题目描述

对于给定的整数a,输出 a++,a--,++a,--a的值

输入

输入一个整数a

输出

输出 a++,a--,++a,--a的值,每个输出值中间用空格隔开。

样例输入
0
样例输出
0 0 1 -1

题本身基本无需再解释.但此处我想借此题用易于吸收的大白话讲清楚a++,a--,++a,--a的区别.

如果按“字面意思”去赋值输出,那么结果会是这样的:

上面的结果不尽如人意,很明显,这样直接给b,c,d,e赋值是不行的.这也给很多初学者造成了困扰.

同样使人困扰的操作有下:

所以,我们应该模拟一次a++...的运算过程,然后输出对应结果。

自增运算符

所有的C++入门书都会说,i++和++i(i--和--i)的区别在于:

自增运算符:

后置运算符:x++表示在使用x之后,再使x的值加1,即x=x+1;

前置运算符:++x表示在使用x之前,先使x的值加1,即x=x+1.

这个前后之差是非常细微的区别,那么它们怎么执行呢?

举个栗子,我们使x=1;

//x++
x=1;
//使用x
x=x;
//x值+1;
x+1;

//——————————————————————————

//++x
x=1;
//x值+1
x=2;
//使用x
x=x;//x=2

这样看结果是一样的,还是没有区别,原因在于,x两次都是自身使用了x,但实际当有其他变量、一个表达式内有其他运算时,情况就可能不太一样了。(以下详说)

所以一般实际使用时,在如此的单个i变量的for循环里使用两种自加都没有区别:

++i:

i++:

换句话说,如果x不是在自身上被使用的,我们能更直观地看清其中的顺序。

再往白话里说,把x想成一碟原料,找一口火锅a,x++和++x就是做菜顺序。

那我们开始做这两道菜!我们设输入a,x=1,首先做一次a=x++;

没错,a=1!

后来的那个1,根本没有加到a上去!

这是因为刚刚a=x++的时候,先做了一次a=x的赋值运算。之后执行的x=x+1,虽然x已经变化但不影响a。

如果a是一个火锅,那x的碟子先下了菜进去,之后在x的碟子里加了一份菜,当然和火锅a没有关系了。

但++x就不一样了:

是的,a=2。

看上去非常顺理成章,x的碟子在下进火锅a前就加了一份料,下进火锅a,我们很快能看到满盛的2份菜捞出......(写着写着就饿了)

所以只要不下火锅,就在自己的碟子里,++x和x++无论怎么加都是两份菜。

好了,x++和++x的执行顺序问题已经非常直观地说清楚了,接下来就是关于原题的错解原因回答

再贴一次错题:

我记得我初学的时候有个很大的疑惑,就是为什么x++不能打包发给a?

这是该运算符的执行特性导致的。

后置运算符的特点就是先使用变量的值再运算,前置运算符则相反。

实际上当你在a=x++使用了这个后置运算符后,编译器会生成一个临时空间去存放x的值,最后也会返回这个值;然后x++输出的结果就是原值,但此时x本身也已更新。此时再赋值给a。这个过程是不违反运算符优先级顺序的。

顺便贴一张优先级图:

注意,它稍后还有大用!

在使用循环这样变量持续变化的环境下它们的用途比较突出;但是在变量不需要持续变化的单个表达式中使用,它对输出我们想要的值就可能产生干扰,甚至干扰运行速度(因为x++后置运算符需要编译器的临时内存)。

就比如上题,a已经在每次自加运算后更新了自身,内存中的a已经更新。但初学者可能会以为用的还是输入的a值。

输出b/c/d/e

执行运算后系统存储的a

所执行的操作

输入a

/

0

cin>>a;

a=0;

b=a++

0

1

b=a;

a=a+1;

c=a--

1

0

c=a;

a=a-1

d=++a

1

1

a=a+1;

d=a;

e=--a

0

0

a=a-1;

e=a;

所以就错了。

很有意思的另外的一个情况,也会输出不同答案,重新贴一下:

这里又会涉及一个知识点。如果你觉得暂时OK了,那么可以先退出,或者转至文末看我提供的两种方法解答,一种是数组,一种是信竞一本通上的方法改编。

参数传递顺序

在C、C++语言中,参数是自右向左传递的。(本人掌握语言不多,不知道是不是所有语言都是这样,求轻喷,此处只强调C,C++)

无论是在cout流中还是printf函数涉及多变量输出或存在多个运算式需要计算,一律从后往前进行输出,从右往左进行计算。注意,我不是说打印的顺序会颠倒,而是执行顺序

举个栗子,

你最后看到的还是3456,但是编译器是根据6——5——4——3的顺序进行输出的。

好了,回到刚刚输出错解-1 0 0 0的情况:我刚刚说运算符优先级图有大用,这就派上用场来了。

年少初识C语言的我对这张图是非常不上心的,或许是因为当时学习强调编程作为思维培养工具的问题,这些细节并没有得到重视,但如果以后有志于C、C++语言开发,这些也当然是必须掌握的。在此有一口诀:算数运算符>移位运算符>条件运算符>按位运算符>逻辑运算符>赋值。CSDN上已经有了许多大佬总结的口诀,读者可以自行查阅。

所以,查阅这张图我们发现,后置运算符优先于前置运算符输出,从右往左算,则是:

运算:--a——++a——a--——a++

输出:a--——a++——补充--a和++a

也就是说,编译器仍然会先向左传递一次参数,传递即处理了运算符;

然后开始输出。

1.--a

等次

1

2

3

4

传递参数后的a

/

/

/

-1

输出结果

/

/

/

/

执行操作

--a;

2.++a

等次

1

2

3

4

传递参数后的a

/

/

0

/

输出结果

/

/

/

/

执行操作

++a

3.a--

等次

1

2

3

4

传递参数后的a

/

-1

/

/

输出结果

/

0

/

/

执行操作

a--

4.a++

等次

1

2

3

4

传递参数后的a(对应等次)

0

/

/

/

输出结果

-1

0

/

/

执行操作

a++

5.补充输出

等次

1

2

3

4

传递参数后的a(对应等次)

0

/

/

/

输出结果

-1

0

0

0

执行操作

输出

输出

以上说明完毕.

本题正解两则

以上做法利用数组的独立性,使四组数据独立开来;

以上做法直接利用前后置运算符的运算特性.

——————————————————END—————————————————————

  • 5
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

城主_全栈开发

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值