一个C语言的小问题
本帖最后由 拈花小仙 于 2014-3-28 20:23 编辑#include <stdio.h>
int main()
{
int a = {1,2,3,4,5,6,7,8,9,10};
printf("%p\n",&a);
printf("%p\n",a);
printf("%p\n",a + 1);
printf("%p\n",&a + 1);
printf("%d\n",sizeof(a)); //这里a不是代表数组首元素地址吗?,为什么是40
printf("%d\n",sizeof(&a));
return 0;
}
输出结果:
0017FDE4
0017FDE4
0017FDE8
0017FE0C
40
4
这题几个朋友说法不一,请不要看了结果后用个人理解,给个准确的定义来解释一样,谢谢!
嗯............,其实说白了,就是与VC的入栈顺序有关吧!VC的入栈顺序是自右往左的,所以数组的最后一个元素就是栈中的第一个元素,而数组的第一个元素就是栈中的最后一个元素,根据栈的后进先出原理,那么数组的第一个元素的大小,其实就是栈的偏移大小。 我用VC++6.0 两个都是 40 本帖最后由 oggplay 于 2014-3-28 20:21 编辑
sizeof(a)求的是数组大小,我的编译器定义为4*10=40
如果你的系统是32位的,最后一项肯定是4
oggplay 发表于 2014-3-28 20:19 static/image/common/back.gif
sizeof(a)求的是数组大小,我的编译器定义为4*10=40
如果你的系统是32位的,最后一项肯定是4
看结果我也知道是数组大小了,可a+1只移动4个字节,而&a却移动40个字节呢? 我也一样,两个都是40,其实这个40我想是这样的,这些数据都是在栈中的,而VC的入栈顺序是自右往左的,所以当最后一个元素进栈的时候,也就是数组的第一个元素,这样,一个数据时4个字节,那么10个的话,就是40个,而数组名指向的也是数组的第一个元素,而第一个元素在栈中就是第40个元素啊!而且不管是a或&a它都指向的是同一个地址!
下面是反编译的情况,你看一下就明白了:
4: int a = {1,2,3,4,5,6,7,8,9,10};
00401028 mov dword ptr ,1
0040102F mov dword ptr ,2
00401036 mov dword ptr ,3
0040103D mov dword ptr ,4
00401044 mov dword ptr ,5
0040104B mov dword ptr ,6
00401052 mov dword ptr ,7
00401059 mov dword ptr ,8
00401060 mov dword ptr ,9
00401067 mov dword ptr ,0Ah
5: printf("%p\n",&a);
0040106E lea eax,
00401071 push eax
00401072 push offset string "%p\n" (00422020)
00401077 call printf (00401120)
0040107C add esp,8
6: printf("%p\n",a);
0040107F lea ecx,
00401082 push ecx
00401083 push offset string "%p\n" (00422020)
00401088 call printf (00401120)
0040108D add esp,8
青玄 发表于 2014-3-28 20:23 static/image/common/back.gif
我也一样,两个都是40,其实这个40我想是这样的,这些数据都是在栈中的,而VC的入栈顺序是自右往左的,所以 ...
我不懂汇编,能用C的标准或定义解释下吗?{:7_174:}
#include <stdio.h>
int main()
{
int a = {1,2,3,4,5,6,7,8,9,10};
int *p = a;
printf("%d (十进制打印a的首地址)\n", &a); //这是打印a数字的首地址
printf("%p\n",&a); //%p一般以十六进制整数方式输出指针的值
printf("%p\n",*p); //这条为验证上面的结论
printf("%p\n",a); //以十六进制整数方式打印a的首地址
printf("%p\n",a + 1); //以十六进制整数方式打印a +4的首地址
printf("%p\n",&a + 1); //以十六进制整数方式打印(a +sizeof(a))的首地址 (sizeof(a) = 40 = 4 * 10)
printf("%d\n",sizeof(a)); //a代表数组首元素地址,为什么是40(上面的语句证明了a中有10个整型数据,所以为40)
printf("%d\n",sizeof(&a)); //&a ==a都是表示a数组的首地址,呵呵!
return 0;
}
//我又来了,你看看我的解释怎么样?呵呵!程序已经注释和验证了!! sizeof(&a) 不知道可不可以。 无名侠 发表于 2014-3-28 20:34 static/image/common/back.gif
sizeof(&a) 不知道可不可以。
最后一个是&a的输出结果,可a和&a的区别被这题搞乱了,我现在不知哪个代表整个数组,哪个代表数组首元素地址了 青玄 发表于 2014-3-28 20:35 static/image/common/back.gif
嗯............,其实说白了,就是与VC的入栈顺序有关吧!VC的入栈顺序是自右往左的,所以数组的最后一个元 ...
那么a是首元素地址,&a是整个数组的地址吗?这个问题出在sizeof这个关键字上吗? 拈花小仙 发表于 2014-3-28 20:36 static/image/common/back.gif
最后一个是&a的输出结果,可a和&a的区别被这题搞乱了,我现在不知哪个代表整个数组,哪个代表数组首元素地 ...
不知道该作何解释。 本帖最后由 oggplay 于 2014-3-28 20:45 编辑
青玄 发表于 2014-3-28 20:23 static/image/common/back.gif
我也一样,两个都是40,其实这个40我想是这样的,这些数据都是在栈中的,而VC的入栈顺序是自右往左的,所以 ...
通过你的反汇编我明白了,你的编译器在调用printf函数时一直在压栈,而我的编译器直接调用了变量地址,从未压过栈,也就是说我的变量并不在堆栈中。哈哈。看来是编译器不同的缘故。 都是高手:cry
页:
[1]