我只是在 C 语言中查看指针,当我创建各种案例时,我偶然发现了这个:(使用的 IDE - Code::Blocks
编译器 - GNU GCC)
#include <stdio.h>
#include <stdlib.h>
int main()
{
int a=2;
int *pa;
pa=&a;
printf("1 %u\n", &a );
printf("2 %u\n", pa );
printf("3 %d\n", a );
printf("4 %u\n", &(pa));
//printf("\n4 %u\n", &(*pa)); // output not as expected
printf("End \n");
return 0;
}
这里的输出是:
1 2686748
2 2686748
3 2
4 2686744
结尾
现在,当我将第四个 printf 更改为:
printf("\n4 %u\n", &(*pa));
输出变为:
1 2686744
2 2686744
3 2
4 2686744
结尾
在第二部分中,*pa 应该给出2并且&(*pa)应该给出2686748但是这里之前的值已经改变了!
预期输出应为(对于 &(*pa)):2686748、2686748、2、2686748
请解释一下为什么我没有得到预期的输出以及我哪里出错了?
我故意不在 printf() 中使用 %p 所以请不要让我用它替换 %u 或 %d 。
如果需要,这里是指向 IDEone 的链接(那里也会生成类似的输出):
程序 -这里只是删除/插入注释,你会明白,首先包括两个 printf,然后或者注释掉其中的一个。
忽略包含 stdlib.h 我懒得删除它:P
请尽可能简单:)
组件:
First for:
printf("4 %u\n", &(pa));
// printf("\n4 %u\n", &(*pa));
0x00401334 push %ebp
0x00401335 mov %esp,%ebp
0x00401337 and $0xfffffff0,%esp
0x0040133A sub $0x20,%esp
0x0040133D call 0x401970 <__main>
0x00401342 movl $0x2,0x1c(%esp)
0x0040134A lea 0x1c(%esp),%eax
0x0040134E mov %eax,0x18(%esp)
0x00401352 lea 0x1c(%esp),%eax
0x00401356 mov %eax,0x4(%esp)
0x0040135A movl $0x403024,(%esp)
0x00401361 call 0x401be8 <printf>
0x00401366 mov 0x18(%esp),%eax
0x0040136A mov %eax,0x4(%esp)
0x0040136E movl $0x40302a,(%esp)
0x00401375 call 0x401be8 <printf>
0x0040137A mov 0x1c(%esp),%eax
0x0040137E mov %eax,0x4(%esp)
0x00401382 movl $0x403030,(%esp)
0x00401389 call 0x401be8 <printf>
**here>** 0x0040138E lea 0x18(%esp),%eax
0x00401392 mov %eax,0x4(%esp)
0x00401396 movl $0x403036,(%esp)
0x0040139D call 0x401be8 <printf>
0x004013A2 movl $0x40303c,(%esp)
0x004013A9 call 0x401be0 <puts>
0x004013AE mov $0x0,%eax
0x004013B3 leave
0x004013B4 ret
Second for :
// printf("4 %u\n", &(pa));
printf("\n4 %u\n", &(*pa));
0x00401334 push %ebp
0x00401335 mov %esp,%ebp
0x00401337 and $0xfffffff0,%esp
0x0040133A sub $0x20,%esp
0x0040133D call 0x401970 <__main>
0x00401342 movl $0x2,0x18(%esp)
0x0040134A lea 0x18(%esp),%eax
0x0040134E mov %eax,0x1c(%esp)
0x00401352 lea 0x18(%esp),%eax
0x00401356 mov %eax,0x4(%esp)
0x0040135A movl $0x403024,(%esp)
0x00401361 call 0x401be8 <printf>
0x00401366 mov 0x1c(%esp),%eax
0x0040136A mov %eax,0x4(%esp)
0x0040136E movl $0x40302a,(%esp)
0x00401375 call 0x401be8 <printf>
0x0040137A mov 0x18(%esp),%eax
0x0040137E mov %eax,0x4(%esp)
0x00401382 movl $0x403030,(%esp)
0x00401389 call 0x401be8 <printf>
**here>** 0x0040138E mov 0x1c(%esp),%eax
0x00401392 mov %eax,0x4(%esp)
0x00401396 movl $0x403036,(%esp)
0x0040139D call 0x401be8 <printf>
0x004013A2 movl $0x40303d,(%esp)
0x004013A9 call 0x401be0 <puts>
0x004013AE mov $0x0,%eax
0x004013B3 leave
0x004013B4 ret
Third one for:
printf("4 %u\n", &(pa));
printf("\n4 %u\n", &(*pa));
0x00401334 push %ebp
0x00401335 mov %esp,%ebp
0x00401337 and $0xfffffff0,%esp
0x0040133A sub $0x20,%esp
0x0040133D call 0x401980 <__main>
0x00401342 movl $0x2,0x1c(%esp)
0x0040134A lea 0x1c(%esp),%eax
0x0040134E mov %eax,0x18(%esp)
0x00401352 lea 0x1c(%esp),%eax
0x00401356 mov %eax,0x4(%esp)
0x0040135A movl $0x403024,(%esp)
0x00401361 call 0x401bf8 <printf>
0x00401366 mov 0x18(%esp),%eax
0x0040136A mov %eax,0x4(%esp)
0x0040136E movl $0x40302a,(%esp)
0x00401375 call 0x401bf8 <printf>
0x0040137A mov 0x1c(%esp),%eax
0x0040137E mov %eax,0x4(%esp)
0x00401382 movl $0x403030,(%esp)
0x00401389 call 0x401bf8 <printf>
0x0040138E lea 0x18(%esp),%eax
0x00401392 mov %eax,0x4(%esp)
0x00401396 movl $0x403036,(%esp)
0x0040139D call 0x401bf8 <printf>
**here>** 0x004013A2 mov 0x18(%esp),%eax
0x004013A6 mov %eax,0x4(%esp)
0x004013AA movl $0x40303c,(%esp)
0x004013B1 call 0x401bf8 <printf>
0x004013B6 movl $0x403043,(%esp)
0x004013BD call 0x401bf0 <puts>
0x004013C2 mov $0x0,%eax
0x004013C7 leave
0x004013C8 ret