一:先看代码 vim 13.c
#include <iostream>
#include <cstring>
#ifndef NUM
#define NUM 10
#endif
using namespace std;
int main()
{
int i=0;
int *p = &i ;
int a[NUM]={1,2,3,4,5,6};
// int *q = a;
//int *q = &a; 这样赋值不可以
int *q = &a[0];
cout<<"先输出a[0] a[1] 的地址和内容"<<endl;
cout<<"a[0]地址 "<<&a[0]<<" a[0]内容 "<<a[0]<<endl;
cout<<"a[1]地址 "<<&a[1]<<" a[1]内容 "<<a[1]<<endl;
cout<<"先看看顺序存储的内存分配情况:"<<endl;
for(int n=0;n<NUM;n++)
{
cout<<&*(q++)<<" 对应内容 "<<*q<<endl;
}
cout<<"以上数组输出结束!下面看看a,&a,p,&p的输出。"<<endl;
cout<<"i = "<<i<<endl;
cout<<"p = "<<p<<endl;
cout<<"&p= "<<&p<<endl;
cout<<"*p= "<<*p<<endl;
cout<<"&a= "<<&a<<endl;
cout<<"a = "<<a<<endl;
cout<<"&a[0]= "<<&a[0]<<endl;
cout<<"a[0]="<<a[0]<<endl;
cout<<"q = "<<q<<endl;
cout<<"&q= "<<&q<<endl;
cout<<"发现没有,a 和 &a 一样。"<<endl ;
return 0;
}
二:编译代码 g++ 13.c -o 13
三:查看输出 cyq@cyq-desktop:~/桌面/C$ ./13
先输出a[0] a[1] 的地址和内容
a[0]地址 0xbf901624 a[0]内容 1
a[1]地址 0xbf901628 a[1]内容 2
先看看顺序存储的内存分配情况:
0xbf901624 对应内容 1
0xbf901628 对应内容 2
0xbf90162c 对应内容 3
0xbf901630 对应内容 4
0xbf901634 对应内容 5
0xbf901638 对应内容 6
0xbf90163c 对应内容 0
0xbf901640 对应内容 0
0xbf901644 对应内容 0
0xbf901648 对应内容 0
以上数组输出结束!下面看看a,&a,p,&p的输出。
i = 0
p = 0xbf901658
&p= 0xbf901654
*p= 0
&a= 0xbf901624
a = 0xbf901624
&a[0]= 0xbf901624
a[0]=1
q = 0xbf90164c
&q= 0xbf901650
发现没有,a 和 &a 一样。
四:总结分析
1. 由于,数组连续分配内存,所以可以看到数组中的变量的内存是连续的,因为是int 型,所以地址相差4字节
(进一步说,内存大小按字节分配,字节是最小单位)
数组 a[NUM]中,a的值就是a[0]的地址,而&a与a是一样的。但是,a[0]的内容和a不一样
尽管如此 (&a与a的值是一样的),但是还是不能这样赋值
int *q = &a ;//这是错误的 可能因为a的内容不是int 型吧。用g++会报这样的错:
13.c:17: 错误: 不能将‘int (*)[10]’转换为‘int*’,在 initialization 中
当然可以这样赋值
int *q = &a[0] ;
2.再分析一下,&a和a到底是什么
数组 a,
他仅仅是个标签,根本就没地方存放。
事实上,编译器没有给a分配内存。
所以C语言中的规定是取数组地址的结果是:仍然是其本身。
既 &a 的值和 a一样。
注意:值是一样,类型是不一样的。
------------------------
虽然数组名的确没有存储空间,但把&a规定为跟a的地址值一样并不是这个原因。
数组名是一个右值,本来不符合&的语法的,但是,数组却是一个对象,对一个
数组对象取地址是合理的,C标准委员会经过衡量,认为维护一个对象的完整性
更重要,因此允许&a,只不过,&a的意义,并非对一个数组名取地址,而是对
一个数组对象取地址。
3.再看看这个问题 代码中的 cout<<&*(q++)<<" 对应内容 "<<*q<<endl; 这行。
很多人不理解 q++是什么意思,实际上q++是指,q的内容加一,也就是说q再增加一个q单位。
那么一个q单位是多少,因为我们定义为 int *q = &a[0] ,那么显然,一个q单位大小因该
为4个字节(因为一个int 变量占用4个字节嘛 )
所以如果 q=0xbfe70058 那么 当执行完q++之后 ,q=0xbfe7005c ,前后差4 。
如果不信,可以在代码中加入这行看看
cout<<"sizeof(q)=" <<sizeof(q)<<endl;
cout<<"++q="<<++q<<endl;
当然如果你感兴趣,可以再加一行这个,看看&q
cout<<"sizeof(&q)= "<<sizeof(&q)<<endl;
cout<<"++(&q)= "<<&q+1<<endl;
// cout<<"++(&q)="<<++(&p)<<endl; 这行如果这么写是错误的,用上面一行代替即可。
最后我们再思考一下:
由于数组分配连续内存,那么我们能进一步想到什么呢?
如果在程序中多用数组的话,内存的使用效率会很低(低于用指针链表),如果内存中,有的内存断大小不够一整块内存来分配给数组用,那么这块内存就被浪费掉了。所以这就是数组的一大缺点。当然还有很多,比如增删改查的问题等等。
参考:
http://www.cppblog.com/geforcex/articles/1861.html
http://blog.csdn.net/deerwin1986/archive/2009/08/02/4401621.aspx
http://topic.csdn.net/u/20100801/19/d8cacb5a-cff5-4875-ad37-b42d9b8ab5f9.html?seed=1700787584&r=67419700#r_67419700
声明:本文档可以随意更改,但必须署名原作者
作者:凤凰舞者 qq:578989855