| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 2336 人关注过本帖
标题:请解释一下,我看不懂
只看楼主 加入收藏
匆匆来过
Rank: 1
来 自:广州
等 级:新手上路
帖 子:26
专家分:9
注 册:2015-12-27
收藏
得分:0 
我记得像a=b=c这些问题我们老师都不怎么说,应该是编译器的问题吧

努力打代码
2016-05-30 01:10
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:5 
化简看看:
int main()
{
    int x=10,y=20, z=30;
    printf("%d %d\n", y=z, y==z);
    return 0;
}
显示:30 0,并不是表面想象中的:30 1。
再看看:
int main()
{
    int x=10,y=20, z=30;
    printf("%d %d %d\n", x, y, x=y=z);
    return 0;
}
显示:30 30 30,表面看是不是有点玄?要了解printf的内部处理过程。
问题是:
语句 printf("%d %d %d %d\n",x=y=z,x=y==z,x==(y==z),x==(y==z)) 想表达什么?不容易读得懂的语句。

2016-05-30 07:59
wanglianyi1
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:14
帖 子:647
专家分:2067
注 册:2015-6-18
收藏
得分:0 
回复 10楼 _Strike
这个我也不懂了,只能像水版说的那样,找点资料查看下库函数printf的实现过程再了解吧,不过话说以前好像在哪本书看到过,这样的没有实际意义,只是为了绕语法这样的题没什么用。就像++a++这样的,想弄清楚的话,看看库函数吧.
2016-05-30 08:36
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
探讨一下 printf 的处理过程

C代码:
#include<stdio.h>
main()
{
    int x=10, y=20, z=30;
    printf("%d %d %d\n",x=y=z, x=y==z, x==(y==z));
}

编译码:
图片附件: 游客没有浏览图片的权限,请 登录注册

注释:
    int x=10, y=20, z=30
MOV DWORD PTR SS:[ESP+1C],0A         ; | x = 10
MOV DWORD PTR SS:[ESP+18],14         ; | y = 20
MOV DWORD PTR SS:[ESP+14],1E         ; | z = 30

    x==(y==z) 结果 0
MOV EAX,DWORD PTR SS:[ESP+18]        ; | EAX = y
CMP EAX,DWORD PTR SS:[ESP+14]        ; | y==z
SETE AL                              ; | AL = (y==z)
MOVZX EAX,AL                         ; | EAX = (y==z)
CMP EAX,DWORD PTR SS:[ESP+1C]        ; | x==(y==z)  
SETE AL                              ; | AL = x==(y==z)
MOVZX EAX,AL                         ; | EAX = x==(y==z)

    x=y==z 结果 x=0
MOV EDX,DWORD PTR SS:[ESP+18]        ; | EDX = y
CMP EDX,DWORD PTR SS:[ESP+14]        ; | y==z
SETE DL                              ; | DL = y==z
MOVZX EDX,DL                         ; | EDX = y==z
MOV DWORD PTR SS:[ESP+1C],EDX        ; | x = (y==z),此时x=0

    x=y=z 结果 x=30
MOV EDX,DWORD PTR SS:[ESP+14]        ; | EDX = z
MOV DWORD PTR SS:[ESP+18],EDX        ; | y = z
MOV EDX,DWORD PTR SS:[ESP+18]        ; | EDX = y
MOV DWORD PTR SS:[ESP+1C],EDX        ; | x = y,注意!这时x被修改为30

    printf("%d %d %d\n",x=y=z, x=y==z, x==(y==z));
    结果 printf("%d %d %d\n", x, x, 0);
MOV DWORD PTR SS:[ESP+C],EAX         ; | printf第4个参数x==(y==z)结果 0
MOV EAX,DWORD PTR SS:[ESP+1C]        ; | EAX = x
MOV DWORD PTR SS:[ESP+8],EAX         ; | printf第3个参数x 结果 30
MOV EAX,DWORD PTR SS:[ESP+1C]        ; | EAX = x
MOV DWORD PTR SS:[ESP+4],EAX         ; | printf第2个参数x 结果 30
MOV DWORD PTR SS:[ESP],test.00404000 ; | ASCII "%d %d %d", printf第1个参数 "%d %d %d"
CALL <JMP.&msvcrt.printf>            ; | 执行printf()

    释放分配的内存返回
LEAVE
RETN

可见 printf() 是从右到左处理各个输入参数。
2016-05-30 09:55
_Strike
Rank: 2
等 级:论坛游民
帖 子:133
专家分:72
注 册:2016-3-22
收藏
得分:0 
回复 14楼 吹水佬
非常感谢楼上所有版主的认真解答,谢谢!
2016-05-30 12:45
陆苗
Rank: 2
等 级:论坛游民
帖 子:52
专家分:39
注 册:2016-5-31
收藏
得分:0 
图片附件: 游客没有浏览图片的权限,请 登录注册

visualstudio 输出也是 30 30 0 0;
   哪个才是正确的.

------虚心学习,不懂就问
2016-06-01 13:18
alice_usnet
Rank: 11Rank: 11Rank: 11Rank: 11
等 级:贵宾
威 望:18
帖 子:370
专家分:2020
注 册:2016-3-7
收藏
得分:0 
不要纠结这些问题了,这个叫做未定义行为。。。未定义行为。

未佩好剑,转身便已是江湖
2016-06-01 16:31
吹水佬
Rank: 16Rank: 16Rank: 16Rank: 16
等 级:版主
威 望:451
帖 子:10607
专家分:43186
注 册:2014-5-20
收藏
得分:0 
以下是引用alice_usnet在2016-6-1 16:31:50的发言:

不要纠结这些问题了,这个叫做未定义行为。。。未定义行为。

好象不是“未定义行为”,只是不容易读懂printf要表达什么。
这样看看应该能理解:
#include<stdio.h>
int main()
{
    int x=10, y=20, z=30, xyz;
    printf("%d %d %d %d\n",x=y=z,x=y==z,x==(y==z),x==(y==z));
    printf("等同:\n");
    x=10; y=20; z=30;
    xyz = x==(y==z);
    x = y==z;
    x = y = z;
    printf("%d %d %d %d\n",x, x, xyz, xyz);
    printf("原理:\n");
    x = 10;
    printf("%d %d %d %d\n",x, x++, x++, x++);
    return 0;
}

2016-06-02 10:27
快速回复:请解释一下,我看不懂
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.026638 second(s), 11 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved