鱼C论坛

 找回密码
 立即注册
查看: 2258|回复: 13

一个C语言的小问题

[复制链接]
发表于 2014-3-28 18:28:48 | 显示全部楼层 |阅读模式
10鱼币
本帖最后由 拈花小仙 于 2014-3-28 20:23 编辑

#include <stdio.h>
int main()
{
    int a[10] = {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的入栈顺序是自右往左的,所以数组的最后一个元素就是栈中的第一个元素,而数组的第一个元素就是栈中的最后一个元素,根据栈的后进先出原理,那么数组的第一个元素的大小,其实就是栈的偏移大小。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-3-28 18:28:49 | 显示全部楼层
嗯............,其实说白了,就是与VC的入栈顺序有关吧!VC的入栈顺序是自右往左的,所以数组的最后一个元素就是栈中的第一个元素,而数组的第一个元素就是栈中的最后一个元素,根据栈的后进先出原理,那么数组的第一个元素的大小,其实就是栈的偏移大小。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-3-28 20:00:12 | 显示全部楼层
我用VC++6.0 两个都是 40
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-3-28 20:19:20 | 显示全部楼层
本帖最后由 oggplay 于 2014-3-28 20:21 编辑

sizeof(a)求的是数组大小,我的编译器定义为4*10=40
如果你的系统是32位的,最后一项肯定是4
抓图7.png
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-3-28 20:22:40 | 显示全部楼层

看结果我也知道是数组大小了,可a+1只移动4个字节,而&a却移动40个字节呢?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-3-28 20:23:14 | 显示全部楼层
我也一样,两个都是40,其实这个40我想是这样的,这些数据都是在栈中的,而VC的入栈顺序是自右往左的,所以当最后一个元素进栈的时候,也就是数组的第一个元素,这样,一个数据时4个字节,那么10个的话,就是40个,而数组名指向的也是数组的第一个元素,而第一个元素在栈中就是第40个元素啊!而且不管是a或&a它都指向的是同一个地址!
下面是反编译的情况,你看一下就明白了:
4:        int a[10] = {1,2,3,4,5,6,7,8,9,10};
00401028   mov         dword ptr [ebp-28h],1
0040102F   mov         dword ptr [ebp-24h],2
00401036   mov         dword ptr [ebp-20h],3
0040103D   mov         dword ptr [ebp-1Ch],4
00401044   mov         dword ptr [ebp-18h],5
0040104B   mov         dword ptr [ebp-14h],6
00401052   mov         dword ptr [ebp-10h],7
00401059   mov         dword ptr [ebp-0Ch],8
00401060   mov         dword ptr [ebp-8],9
00401067   mov         dword ptr [ebp-4],0Ah
5:        printf("%p\n",&a);
0040106E   lea         eax,[ebp-28h]
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,[ebp-28h]
00401082   push        ecx
00401083   push        offset string "%p\n" (00422020)
00401088   call        printf (00401120)
0040108D   add         esp,8



QQ截图20140328202110.png

想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-3-28 20:25:47 | 显示全部楼层
青玄 发表于 2014-3-28 20:23
我也一样,两个都是40,其实这个40我想是这样的,这些数据都是在栈中的,而VC的入栈顺序是自右往左的,所以 ...

我不懂汇编,能用C的标准或定义解释下吗?{:7_174:}
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-3-28 20:34:13 | 显示全部楼层
#include <stdio.h>
int main()
{
    int a[10] = {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;
}
//我又来了,你看看我的解释怎么样?呵呵!程序已经注释和验证了!!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-3-28 20:34:31 | 显示全部楼层
sizeof(&a) 不知道可不可以。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-3-28 20:36:01 | 显示全部楼层
无名侠 发表于 2014-3-28 20:34
sizeof(&a) 不知道可不可以。

最后一个是&a的输出结果,可a和&a的区别被这题搞乱了,我现在不知哪个代表整个数组,哪个代表数组首元素地址了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

 楼主| 发表于 2014-3-28 20:40:27 | 显示全部楼层
青玄 发表于 2014-3-28 20:35
嗯............,其实说白了,就是与VC的入栈顺序有关吧!VC的入栈顺序是自右往左的,所以数组的最后一个元 ...

那么a是首元素地址,&a是整个数组的地址吗?这个问题出在sizeof这个关键字上吗?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-3-28 20:41:01 | 显示全部楼层
拈花小仙 发表于 2014-3-28 20:36
最后一个是&a的输出结果,可a和&a的区别被这题搞乱了,我现在不知哪个代表整个数组,哪个代表数组首元素地 ...

不知道该作何解释。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-3-28 20:41:07 | 显示全部楼层
本帖最后由 oggplay 于 2014-3-28 20:45 编辑
青玄 发表于 2014-3-28 20:23
我也一样,两个都是40,其实这个40我想是这样的,这些数据都是在栈中的,而VC的入栈顺序是自右往左的,所以 ...

通过你的反汇编我明白了,你的编译器在调用printf函数时一直在压栈,而我的编译器直接调用了变量地址,从未压过栈,也就是说我的变量并不在堆栈中。哈哈。看来是编译器不同的缘故。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2014-3-30 10:04:33 | 显示全部楼层
都是高手:cry
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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

GMT+8, 2024-11-23 23:40

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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