鱼C论坛

 找回密码
 立即注册
查看: 4960|回复: 21

求教,问答模块找不到了,发这里了,是++--的问题

[复制链接]
发表于 2011-2-5 22:21:54 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 nbceshi 于 2011-2-5 22:39 编辑

#include <stdio.h>

void main()
{
        int i,q;
        i = 5;
        q = (++i)+(++i)+(++i);                          /*计算完i=8*/
        printf("%d\n",q);                                   
        printf("%d,%d,%d\n",++i,++i,++i);       /*计算完i=11*/
        printf("%d,%d,%d\n",i--,i--,i--);             /*计算完i=8*/
}
为什么q=22?,不是6+7+8=21吗?
为什么第9行显示11,10,9?但为什么第十行答案是11,11,11?
++i是先计算再赋值可以理解,--i先赋值再计算的话,第十行不是应该是9,10,11?
实在搞不懂。
书上的例4.5
#include <stdio.h>

void main()
{
        int i,q;
        i = 8;
        printf("%d\n%d\n%d\n%d\n%d\n%d\n",++i,--i,i++,i--,-i++,-i--);
}
也是这样奇怪,计算结果是8,7,8,8,-8,-8。书上答案却是8,7,7,8,-7,-8。
再请教个技巧问题,我输入符号等字符的时候打字特慢,得看键盘按组合键,要不容易按错,有没什么技巧?我看视频上小甲鱼老师打的好快。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-6 14:27:34 | 显示全部楼层
本帖最后由 demon 于 2011-2-6 14:29 编辑

这个也是我很头疼的问题,
昨天学完第二章,现在只解决了第一个问题!

q = (++i)+(++i)+(++i);                  
这里因为有两个+运算符,按左结合性自左向右运算,所以变成如下
q = ((++i)+(++i))+(++i);     
(++i)+(++i) 这里由于++i,所以i自增后在进行运算,自增2次,即变成 7+7==14
在与第三个(++i)计算,变成了  14+8

为什么第9行显示11,10,9?
这个不难懂,书上已经解释过,大多数编译器对于函数参数是自右向左运算的!

但为什么第十行答案是11,11,11
因为这里是i--,即先用i的值,最后i自减3次

4.5还不懂!!! - -
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-6 14:31:20 | 显示全部楼层
4.5我也明白了,与你之前问的一样,
为什么第9行显示11,10,9?
这个不难懂,书上已经解释过,大多数编译器对于函数参数是自右向左运算的!

自右向左运算,如果是自左向右运算,貌似你的答案还是不对!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-6 14:39:32 | 显示全部楼层
本帖最后由 demon 于 2011-2-6 14:44 编辑

自左向右的结果应该为这样,
9,8,8,9,-8,-9
最后i的值还为8

如果不对,还望斧正,哈哈

以上实验环境,均为VC++6.0
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-7 11:30:05 | 显示全部楼层
这个问题试着用反汇编的角度来思考一下会好点的。参照一下这个帖子吧。http://fishc.com/dz/viewthread.php?tid=81&extra=page%3D1,小甲鱼特别供稿的。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2011-2-7 20:14:38 | 显示全部楼层
感谢dmon的解答。
第9行我奇怪的是第十行结果是3个值都先调用了i的值,但第9行却是计算了一个调用一个,而不是先i自增3次后再3个值都调用i的值。
我的理解是C语言设计上上i++先全部调用值后再统一自增,而++i是一个一个来。不知道我这理解对不对。
4.5的例子,你电脑显示9,8,8,9,-8,-9?我的电脑显示8,7,8,8,-8,-8。也是Visual C++ 6.0,WndowsXP,CPU是32的。
还有版主大人的反汇编难以理解啊。:L
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-7 20:52:12 | 显示全部楼层
本帖最后由 demon 于 2011-2-7 20:54 编辑

4.5的例子这个是编译器的问题,书上有说的,你学第三张,小甲鱼也有讲过!
因为printf();这个函数里的参数++i,--i,i++,i--,-i++,-i-- 是从右向左来计算,
Tubor C2.0 和VC++6.0都是从右向左计算!
你可以运行下面的代码,就知道我为什么得出9,8,8,9,-8,-9这个结果了

#include <stdio.h>

void main(){
        int i;
        i = 8;
        printf("%d\n",++i);
        printf("%d\n",--i);
        printf("%d\n",i++);
        printf("%d\n",i--);
        printf("%d\n",-i++);
        printf("%d\n",-i--);
}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-7 22:10:27 | 显示全部楼层
++i  即先自增在运算  i=i+1;
i++  即先取值在自增,我的理解是取值参与表达式运算后,在自增
最后i的值都一样,只是表达式的值不一样!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2011-2-8 00:35:41 | 显示全部楼层
谢谢demon,我清楚VC++6.0是从右到左计算的,你误解我的疑惑了。
例4.5
#include <stdio.h>

void main()
{
        int i,q;
        i = 8;
        printf("%d\n%d\n%d\n%d\n%d\n%d\n",++i,--i,i++,i--,-i++,-i--);
}
计算机给出了8,7,8,8,-8,-8。
如果把程序写成
#include <stdio.h>

void main()
{
        int i;
        i = 8;
        printf("%d\n",-i--);
        printf("%d\n",-i++);
        printf("%d\n",i--);
        printf("%d\n",i++);
        printf("%d\n",--i);
        printf("%d\n",++i);
}
则结果和书上的一样了,结果是8,7,7,8,-7,-8。
我怀疑VC++6.0在同一句里碰到i++,i--只是套用值,并不进行计算,碰到++i,--i才进行计算,我为了求证
我把例4.5改了下
#include <stdio.h>

void main()
{
        int i;
        i = 8;
        printf("%d\n%d\n%d\n%d\n%d\n%d\n",++i,--i,i++,i--,-i--,-i--);
}
倒数第二个改成-i--,然后计算机给出的答案还是8,7,8,8,-8,-8.和没改是一样的。如果把程序写成
#include <stdio.h>

void main()
{
        int i;
        i = 8;
        printf("%d\n",-i--);
        printf("%d\n",-i--);
        printf("%d\n",i--);
        printf("%d\n",i++);
        printf("%d\n",--i);
        printf("%d\n",++i);
}
则答案变成了(我仍然按原例子的排列顺序吧)6,5,5,6,-7,-8.
我琢磨是不是VC++6.0对i--,i++的计算软件设计有问题,我们是不是需要在以后多打几行代码来避免这个问题,又或是我的理解有误?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-8 09:14:41 | 显示全部楼层
我琢磨是不是VC++6.0对i--,i++的计算软件设计有问题,我们是不是需要在以后多打几行代码来避免这个问题,又或是我的理解有误?

VC6.0对++,--的设计没有问题(因为这个设计符合c99标准,C99标准对于这个问题本来就允许编译器提供多种实现策略)。

对于这个问题,必须多打几行。事实上,在同一个语句中,对于同一个变量,不能出现一次以上的(++,--等操作),否则在不同编译器上的结果就很有可能不一样。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-8 09:57:07 | 显示全部楼层
《C程序设计 第三版》_谭浩强
这本书P85页上面有说,C语言对此并无统一规定,不同的系统处理方法不同,
这是使用C语言会出问题的地方,我们应该避免,
可惜我上传不了附件!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
 楼主| 发表于 2011-2-8 11:35:46 | 显示全部楼层
谢谢两位,懂了。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-8 19:50:55 | 显示全部楼层
根据反编译可以知道,请看下面的代码↓
q=(++j)+(++j)+(++j);
0040129D mov ecx,dword ptr [ebp-8]
004012A0 add ecx,1
004012A3 mov dword ptr [ebp-8],ecx
004012A6 mov edx,dword ptr [ebp-8]
004012A9 add edx,1
004012AC mov dword ptr [ebp-8],edx
004012AF mov eax,dword ptr [ebp-8]
004012B2 add eax,dword ptr [ebp-8]
004012B5 mov ecx,dword ptr [ebp-8]
004012B8 add ecx,1
004012BB mov dword ptr [ebp-8],ecx
004012BE add eax,dword ptr [ebp-8]
004012C1 mov dword ptr [ebp-10h],eax

dword ptr [ebp-8]的内容就是j的值。
dword ptr [ebp-10h]的内容就是q的值。

第几步     ecx    edx    eax    q
   1:        5     0        0       5
   2:        6     0        0       5
   3:        6     0        0       6
   4:        6     6        0       6
   5:        6     7        0       6
   6:        6     7        0       7
   7:        6     7        7       7
   8:        6     7        14     7
   9:        7     7        14     7
   10:      8     7        14     7
   11:      8     7        14     8
   12:      8     7        22     8
   13:      8     7        22     22

注:每一步对应每一个指令,最后一步把eax的值赋给q,所以q的值为22。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-10 10:08:10 | 显示全部楼层



    不同编译器的汇编结果不一样,如VC6的汇编结果和gcc的汇编结果就不一样。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-11 18:06:20 | 显示全部楼层
这种问题不好说,不同的机器结果都不一样
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-2-11 18:08:26 | 显示全部楼层
如VC6的运行的结果和gcc的就不一样
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-9-10 15:14:35 | 显示全部楼层
这个不知道是什么无奈啊!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-9-18 03:32:20 From FishC Mobile | 显示全部楼层
其实是这样的:编译器只能记住前两次的++(前缀)结果。
例如:
i=3;
(++i)+(++i)+(++i);
分析:前两次i变成了5,只能保存到此,之后的加加运算,依次加一。算式结果:5+5+6;
用手机一时间说不明白,现在设备不全,等有时间,我发上详细点的说明。
欢迎分享,讨论你知道的部分知识。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2011-9-18 06:58:53 | 显示全部楼层
看贴不回贴 都什么习惯呀?

                               
登录/注册后可看大图























                               
登录/注册后可看大图

防辐射服什么时候穿合适
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
发表于 2012-9-25 21:57:08 | 显示全部楼层
本帖最后由 画个圈圈叉死你 于 2012-9-25 21:59 编辑

我是在vc++6.0中做的程序
请看程序:
/* 程序1 */
#include <stdio.h>
void main()
{
        int i,;
        i = 8;
        printf("%d\n%d\n%d\n%d\n%d\n%d\n",++i,--i,i++,i--,-i++,-i--);
}
计算机给出了8,7,8,8,-8,-8


如果把程序写成、
/* 程序2*/
#include <stdio.h>
void main()
{
        int i;
        i = 8;
        printf("%d\n",-i--);
        printf("%d\n",-i++);
        printf("%d\n",i--);
        printf("%d\n",i++);
        printf("%d\n",--i);
        printf("%d\n",++i);
}
结果是 -8,-7,8,7,7,8


如果在前面添加一个i,即
printf("%d\n%d\n%d\n%d\n%d\n%d\n%d\n",i,++i,--i,i++,i--,-i++,-i--);
则结果为8,8,7,8,8,-8,-8

如果再做修改,如下:
/* 程序3*/
#include <stdio.h>
void main()
{
        int i;
        i = 8;
        printf("%d\n%d\n%d\n%d\n%d\n%d\n%d\n",i,++i,--i,i++,i--,-i++,-i--);
printf("%d\n",i);
}
结果为8,8,7,8,8,-8,-8,8

若改为
#include <stdio.h>
void main()
{
        int i;
        i = 8;
        printf("%d\n%d\n%d\n%d\n%d\n%d\n%d\n",i,++i,--i,i++,i--,-i++,-i++);
printf("%d\n",i);
}
结果为8,8,7,8,8,-8,-8,10

所以可以看出:
1.在单个printf中是自右向左按顺序运算的。
2.当运算遇到++(--)后置时,只提取i值而暂时不进行自增(减)。
3.当运算遇到++(--)前置时,进行自增(减)并提取表达式的值。
4.当printf中所有参数输出完毕,再运算尚未自增(减)的后置





想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-11-25 07:35

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表