作者weii (迷惑失道)
看板SFFamily
标题[转录]Re: [问题][C] pointer,++,--,priority
时间Wed Dec 24 10:39:13 2008
※ [本文转录自 C_and_CPP 看板]
作者: ckclark (大资佬) 看板: C_and_CPP
标题: Re: [问题][C] pointer,++,--,priority
时间: Fri Jul 27 17:46:44 2007
※ 引述《GABA (dfasfd)》之铭言:
: 我想问一个
: include <stdio.h>
: main()
: {
: int list[5];
: int *p;
: int i;
: for (i=0; i<5; i++)
: list[i]=i;
: p=list;
: printf("%d, %d, %d\n", *++p, *p++, *(p+1));
: return 0;
: }
: 我跑完的结果是2,0,1
: 可是我不懂为蛇麽 有人可以指导一下吗?
: 感恩!
这种没有定义的行为
就只能看组语说故事罗...
说实在的 COMPILE出怎样的结果都不能说COMPILER错啦
mov DWORD PTR [%rbp-4], 0 # i,
jmp .L2 #
# 这段是for回圈
.L3:
mov %eax, DWORD PTR [%rbp-4] # i.0, i
movsx %rdx, %eax # i.0, i.0
mov %eax, DWORD PTR [%rbp-4] # i, i
mov DWORD PTR [%rbp-48+%rdx*4], %eax # list, i
add DWORD PTR [%rbp-4], 1 # i,
.L2:
cmp DWORD PTR [%rbp-4], 4 # i,
jle .L3 #,
# for 回圈结束
# 首先这边先说明一下
# [%rbp-16] 就是所谓的p这个pointer的位址
#而一些D.194x就当做个暂存的变数吧
lea %rax, [%rbp-48] # tmp67,
mov QWORD PTR [%rbp-16], %rax # p, tmp67
#这边是p=list
mov %rax, QWORD PTR [%rbp-16] # D.1942, p
#把p的值存到rax里
add %rax, 4 # D.1942,
#把rax+=4 也就是rax目前指的是list[1]
mov %ecx, DWORD PTR [%rax] # D.1943,* D.1942
#把list[1]的值存到ecx里
mov %rax, QWORD PTR [%rbp-16] # p, p
mov %edx, DWORD PTR [%rax] # D.1944,* p
#这边就是让list[0](=*p)存到edx里面
add QWORD PTR [%rbp-16], 4 # p,
#p+=4
add QWORD PTR [%rbp-16], 4 # p,
#p+=4
mov %rax, QWORD PTR [%rbp-16] # p, p
#让rax=p
mov %esi, DWORD PTR [%rax] # D.1945,* p
#让esi=*p (相当於list[2])
mov %edi, OFFSET FLAT:.LC0 #,
mov %eax, 0 #,
call printf #
#这里的参数呢
#第一个是edi "%d, %d, %d\n"
#第二个是esi (list[2])
#第三个是edx (list[0])
#第四个是ecx (list[1])
mov %eax, 0 # D.1946,
leave
ret
至於为什麽会这样compile呢
可以仔细观察rax 看起来他就是负责运算++p,p++,p+1这些位址的
而这个顺序是反过来的(从最後一个参数算回来)
再看一遍code
mov %rax, QWORD PTR [%rbp-16] # D.1942, p
add %rax, 4 # D.1942,
mov %ecx, DWORD PTR [%rax] # D.1943,* D.1942
#这三行是算*(p+1)
mov %rax, QWORD PTR [%rbp-16] # p, p
mov %edx, DWORD PTR [%rax] # D.1944,* p
add QWORD PTR [%rbp-16], 4 # p,
#这三行是算*p++
add QWORD PTR [%rbp-16], 4 # p,
mov %rax, QWORD PTR [%rbp-16] # p, p
mov %esi, DWORD PTR [%rax] # D.1945,* p
#这三行是算*++p
mov %edi, OFFSET FLAT:.LC0 #,
不过重点是 没人定义一定要从後面算回来
要是从第一个参数开始算 不就囧了
所以拿来当考题很没道理的
补一下
我的compiler是 gcc 4.1.3 20070601
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 140.112.30.35
1F:→ ckclark:慢了一步 .... 07/27 17:47
2F:推 sunneo:XD 可是我的没有说很清楚 勾错选项 不太好看 07/27 17:47
※ 编辑: ckclark 来自: 140.112.30.35 (07/27 17:56)
3F:推 csihcs:其实结论是什麽结果都有可能,要看 compiler 怎麽做 07/27 18:33
4F:推 archiee:推..... 07/27 21:09
--
你凭什麽爱我...?
又凭什麽要走...!
--
※ 发信站: 批踢踢实业坊(ptt.cc)
◆ From: 220.132.117.169