注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。
测试环境:Ubuntu 10.10
GCC版本:4.4.5
一、数组的概念
1)数组是相同类型的变量的有序集合
数组示意图:数组包含5个int类型的数据
note:
1) 数组地址a第一个意思:数组名和数组元素首地址都是同一个位置。
2) 数组地址a第二个意思:数组长度。
二、数组的大小
1) 数组在一片连续的内存空间中存储元素
2) 数组元素的个数可以显示或隐式指定
int a[5] = {1,2}; //显示指定数组大小
int b[] = {1,2}; //隐式指定数组大小
问题:
1. a[2]、a[3]、a[4]的值是多少? a[2]=0,a[3]=0,a[4]=0
2. b包含了多少个元素? 2个元素
编程实验
数组的初始化
27-1.c
#include <stdio.h>
int main()
{
int a[5] = {1, 2}; //剩下的3个元素数值为0
int b[] = {1, 2}; //可以省略索引值,让编译器自动补充大小
printf("a[2] = %d\n", a[2]); //0
printf("a[3] = %d\n", a[3]); //0
printf("a[4] = %d\n", a[4]); //0
printf("sizeof(a) = %d\n", sizeof(a)); //20
printf("sizeof(b) = %d\n", sizeof(b)); //8
printf("count for a: %d\n", sizeof(a)/sizeof(int)); //5
printf("count for b: %d\n", sizeof(b)/sizeof(int)); //2
return 0;
}
操作:
1) gcc 27-1.c -o 27-1.out编译正确,打印结果:
a[2] = 0
a[3] = 0
a[4] = 0
sizeof(a) = 20 //通过数组名a确定整体数组大小
sizeof(b) = 8 //通过数组名b确定整体数组大小
count for a: 5
count for b: 2
分析:
sizeof在编译阶段就计算好数组长度,与运行期无关。
三、数组地址与数组名
1) 数组名代表数组首元素的地址(右值)
2) 数组的地址需要用取地址符&才能得到
3) 数组首元素的地址值与数组的地址值相同
4) 数组首元素的地址与数组的地址是两个不同的概念(单个元素和整个数组)
编程实验
数组名和数组地址
27-2.c
#include <stdio.h>
int main()
{
int a[5] = { 0 };
printf("a = %p\n", a); //数组首元素地址
printf("&a = %p\n", &a); //数组地址
printf("&a[0] = %p\n", &a[0]);//等价于a,都表示数组首元素的地址
return 0;
}
操作:
1) gcc 27-2.c -o 27-2.out编译正确,打印结果:
a = 0xbfd9a45c
&a = 0xbfd9a45c
&a[0] = 0xbfd9a45c
四、数组名的盲点
1) 数组名“指向”的是内存中数组首元素的起始位置(指向是为了方便理解)
2) 数组名不包含数组的长度信息
3) 在表达式中数组名只能作为右值使用
4) 只有在下列场合中数组名不能看做指针常量
- 数组名作为sizeof操作符的参数(表示数组的大小)
- 数组名作为&运算符的参数 (表示数组的地址,类似type (*a)[n])
实例分析
数组和指针并不相同
27-3.c
#include <stdio.h>
int main()
{
int a[5] = {0};
int b[2]; //初始值随机
int* p = NULL;
p = a; //指针p指向数组a
printf("a = %p\n", a); //数组a的首元素地址:0xbfa50ae0
printf("p = %p\n", p); //数组a的首元素地址:0xbfa50ae0
printf("&p = %p\n", &p); //数组a的地址:0xbfa50afc
printf("sizeof(a) = %d\n", sizeof(a)); //20-数组a指定的是数组大小
printf("sizeof(p) = %d\n", sizeof(p)); //4-指针和数组不同,指针存储的是地址
///*
printf("\n");
p = b;
printf("b = %p\n", b); //数组b的首元素地址:
printf("p = %p\n", p); //数组b的首元素地址:
printf("&p = %p\n", &p); //数组b的地址
printf("sizeof(b) = %d\n", sizeof(b)); //8
printf("sizeof(p) = %d\n", sizeof(p)); //4
b = a;
//*/
return 0;
}
操作:
1) gcc 27-3.c -o 27-3.out编译正确,打印结果:
a = 0xbfae408c
p = 0xbfae408c
&p = 0xbfae4080
sizeof(a) = 20
sizeof(p) = 4
b = 0xbfae4084
p = 0xbfae4084
&p = 0xbfae4080
sizeof(b) = 8
sizeof(p) = 4
分析:
sizeof(数组名)=数组大小。
小结
1) 数组是一片连续的内存空间
2) 数组的地址和数组首元素的地址意义不同
3) 数组名在大多数情况下被当成指针常量处理
4) 数组名其实并不是指针,不能将其等同于指针