| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 493 人关注过本帖, 1 人收藏
标题:对数组名取地址
只看楼主 加入收藏
yjk5006
Rank: 1
来 自:山东
等 级:新手上路
帖 子:5
专家分:2
注 册:2015-7-4
结帖率:0
收藏(1)
已结贴  问题点数:20 回复次数:3 
对数组名取地址
int a[5]={1,2,3,4,5};

int b[100];

一个数组名代表的是数组中第一个元素的位置,通过数组名我们可以访问数组,先看下面两个问题

问题一:
看到一篇文章这么写的。。
int array[10];
int (*ptr)[10];
ptr=&array;//这里说明&array是指向数组的指针,但为什么&array是指向数组的指针?
答一:
对数组名取地址在C标准里面是未定义的行为。由于数组名是右值,而&操作符要求操作数具有具体的内存空间,换言之就是一个变量,因此对数组名取地址本来就是非法的,早期的编译器明确规定这是非法的。不过不知道什么原因,现在的编译器多数把&array定义为一个值跟array相同,类型是一个指向数组的地址,注意了,是地址,不是指针。之所以是指向数组的地址,是因为array是一个数组名,它就代表了int array[10]这个数组。而ptr也是定义为一个指向具有10个int数的数组的指针,因此&array能被赋予ptr。
 
问题二:
对于数组b[],b是数组的地址,但b不算变量,有没有一个地方存放b?而且b是不
是存放的就是自己所在的地址。因为我碰到了如下的问题:
定义一个指针数组
char *a[2];
那么a的值和&a的值是不是应该一样?
答二:
数组名是符号地址常量,在编译时求值并存在编译器的符号表里面,其值就是个内存地址;所以你说的有没有一个地方存放b,可以认为程序没有给其分配空间,数组名只是代表了那个数组空间;与指针不一样,指针指向一块空间,同时指针本身也存储在某个空间;可以认为数组名存在在符号表里,符号表是编译器用的,我们管不到;a和&a值是一样的,本来对常量取地址是非法的,但是标准组织没有定对数组名取地址是非法还是合法,所以因编译器而异,VC是合法的。


然后我们来看一段测试Demo




源码copy to clipboard打印?
01.#include <stdio.h>  
02.int main()  
03.{  
04.         int a[5]={1,2,3,4,5};  
05.         int b[100];  
06.         int *ptr=&a+1;  
07.         printf("%d,%d\n",*(a+1),*(ptr-1));  
08.    printf("sizeof(b)=%d\n",sizeof(b));  
09.    printf("sizeof(&b)=%d\n",sizeof(&b));  
10.}  



结果如下



为什么ptr-1的大小是5呢?是否你也像我一样认为是2,1呢?

对指针进行加1操作,得到的是下一个元素的地址,一个类型为T的指针移动,以sizeof(T)为移动单位,

如果ptr=a+1,那么最终输出*(ptr-1)肯定是2,1

但是ptr=&a+1,为什么就是2,5呢?

虽然前面我们讲对数组取地址不合法,但是我们这样做在编译器看来确实获得了数组a的首地址,&a 是一个指向 int[5] 的指针。但是这时候ptr相当于int *[5],也就是指向了一个含有五个元素的数组,这也就不难解释为什么第二个打印出来&b的大小也是400了,sizeof(b)打印出来的是b数组的大小。sizeof(&b)同样也是。

为此我们将他们的地址打印出来查看




源码copy to clipboard打印?
01.#include <stdio.h>  
02.int main()  
03.{  
04.         int a[5]={1,2,3,4,5};  
05.         int b[100];  
06.         int *ptr=&a+1;  
07.         printf("%d,%d\n",*(a+1),*(ptr-1));  
08.    printf("sizeof(b)=%d\n",sizeof(b));  
09.    printf("sizeof(&b)=%d\n",sizeof(&b));  
10.    printf("a的地址%d\n",a);  
11.    printf("&a的地址%d\n",&a);  
12.    printf("&a+1的地址%d/n",&a+1);  
13.    printf("ptr-1的地址%d/n",ptr-1);  
14.}  


 

不难看出,&a+1的地址是&a地址再加5*sizeof(int);它的运算单位是int (*)[5]

最后ptr-1,ptr-1的单位是ptr的类型,因此ptr-1的位置刚好是a[4],他在内存中的分布位置是和&a+1相邻的

[ 本帖最后由 yjk5006 于 2015-7-4 22:46 编辑 ]
搜索更多相关主题的帖子: 编译器 文章 空间 元素 
2015-07-04 00:37
hjx1120
Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15
来 自:李掌柜
等 级:贵宾
威 望:41
帖 子:1314
专家分:6927
注 册:2008-1-3
收藏
得分:7 

说了这么多,讲了这么多!
代码碎片中的\n 出卖了你


2015-07-04 07:13
T_MACC
Rank: 4
等 级:业余侠客
威 望:8
帖 子:99
专家分:211
注 册:2015-4-14
收藏
得分:7 
printf(\n)
 \n折磨写的
2015-07-04 16:39
实际应用
Rank: 5Rank: 5
等 级:职业侠客
威 望:2
帖 子:89
专家分:341
注 册:2015-5-30
收藏
得分:7 
不明白你想干啥
想晒你的学习笔记,还是想向大家求问
2015-07-04 22:01
快速回复:对数组名取地址
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.015358 second(s), 7 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved