免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 2700 | 回复: 11
打印 上一主题 下一主题

[C] 数组名和指针 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-11-09 13:42 |只看该作者 |倒序浏览
先看一道题:
int  main()
{
    int a[5] = {1,2,3,4,5};
    int *p  = (int *) (&a+1);
   
    printf("%d %d", *(a+1), *(p-1));
    return 0;
}
程序输出 2 5 。
我在网上看到一篇文章说数组名是一个常量,它的内容就是数组的首地址。
*(a+1)就是数组第二个元素,(&a+1)中的&a取出来的也是数组首地址啊,
为什么带有类型信息?
同样,将数组作为参数传到一个函数里:
int  foo (int []a) 与  int foo(int (&a)[] )也不同,前者里的a只是一个指针,是
实参的拷贝,不带有数组信息,sizeof(a) =4;
后者带有数组信息,sizeof(a)=20。
为什么&a会带有类型信息??

论坛徽章:
0
2 [报告]
发表于 2008-11-09 14:08 |只看该作者
(&a+1)中的&a取出来的也是数组的地址,不是数组的首地址,int *p  = (int *) (&a+1);其中P指向数组的最后一个地址的下一个地址
*(p-1)就是数组最后一个元素!

论坛徽章:
0
3 [报告]
发表于 2008-11-09 14:09 |只看该作者
不知道这样回答对不对,但我认为是这样的!

论坛徽章:
1
射手座
日期:2013-08-21 13:11:46
4 [报告]
发表于 2008-11-09 14:48 |只看该作者
原帖由 legend1860 于 2008-11-9 14:08 发表
(&a+1)中的&a取出来的也是数组的地址,不是数组的首地址,int *p  = (int *) (&a+1);其中P指向数组的最后一个地址的下一个地址
*(p-1)就是数组最后一个元素!


正解.

(&a+1)直接就偏移了5个int*的距离,然后强制转换成int*,p-1便指向了数组的末尾.

    .file    "tmp.c"
    .def    ___main;    .scl    2;    .type    32;    .endef
    .section .rdata,"dr"
LC0:
    .ascii "%d %d\0"
    .text
.globl _main
    .def    _main;    .scl    2;    .type    32;    .endef
_main:
    leal    4(%esp), %ecx
    andl    $-16, %esp
    pushl    -4(%ecx)
    pushl    %ebp
    movl    %esp, %ebp
    pushl    %ecx
    subl    $52, %esp
    call    ___main
    movl    $1, -28(%ebp)
    movl    $2, -24(%ebp)
    movl    $3, -20(%ebp)
    movl    $4, -16(%ebp)
    movl    $5, -12(%ebp)
    leal    -28(%ebp), %eax
    addl    $20, %eax
    movl    %eax, -8(%ebp)
    movl    -8(%ebp), %eax
    subl    $4, %eax
    movl    (%eax), %edx
    leal    -28(%ebp), %eax
    addl    $4, %eax
    movl    (%eax), %eax
    movl    %edx, 8(%esp)
    movl    %eax, 4(%esp)
    movl    $LC0, (%esp)
    call    _printf
    movl    $0, %eax
    addl    $52, %esp
    popl    %ecx
    popl    %ebp
    leal    -4(%ecx), %esp
    ret
    .def    _printf;    .scl    2;    .type    32;    .endef

论坛徽章:
0
5 [报告]
发表于 2008-11-09 15:14 |只看该作者
我知道结果是如何来的,但我想知道的是&a+1为什么会偏移5个int?
难道&a得到的是指向数组的指针?又好像说不通,因为&是取地址符,是不是说地址类似一种类型,带有类型信息呢?

论坛徽章:
1
射手座
日期:2013-08-21 13:11:46
6 [报告]
发表于 2008-11-09 15:58 |只看该作者
原帖由 vanC 于 2008-11-9 15:14 发表
我知道结果是如何来的,但我想知道的是&a+1为什么会偏移5个int?
难道&a得到的是指向数组的指针?又好像说不通,因为&是取地址符,是不是说地址类似一种类型,带有类型信息呢?


因为a是一个int[5]
&a就是int[][5]了,&a+1就变成了就是指向了[1][0].

我的猜测

论坛徽章:
0
7 [报告]
发表于 2008-11-09 17:21 |只看该作者
什么叫“带有类型信息”?看不懂。
数组名是一个常指针,恒指向数组的第一个元素。
常常有人把指针叫做地址。指针确实有点类似于地址,但它是逻辑意义上的地址。当你将指针加1时,编译器知道,在计算地址时,该加1,还是加4,还是加8。不用你操心。

论坛徽章:
0
8 [报告]
发表于 2008-11-09 17:26 |只看该作者
原帖由 legend1860 于 2008-11-9 14:08 发表
(&a+1)中的&a取出来的也是数组的地址,不是数组的首地址,int *p  = (int *) (&a+1);其中P指向数组的最后一个地址的下一个地址
*(p-1)就是数组最后一个元素!

yes

论坛徽章:
0
9 [报告]
发表于 2008-11-09 19:24 |只看该作者
&a + 1 == &a + 1 * sizeof(a) ??

论坛徽章:
0
10 [报告]
发表于 2008-11-09 19:32 |只看该作者

回复 #9 izhier 的帖子

编译器产生的执行代码不一样。对于*(a+1)执行代码是从a开始,向后移动1个int,然后取出其中的int;而对于(&a+1),取出a首地址,然后在其上加上1*sizeof(a),最后取出对应内存中内容。

[ 本帖最后由 waternie 于 2008-11-9 19:54 编辑 ]
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP