摘要:总结了数组的概念,数组大小的计算方法,数组地址和数组名的关系,数组存在的一些盲点,最后用一个BUG实例对数组和指针的一个差别进行了分析。
一、数组的概念
数组是相同类型变量的有序集合,比如我们定义一个数组int a[5],那么这个数组名字就叫a,a就代表数组元素中的第一个元素的起始地址,这个数组里面有五个元素,每个元素都是int类型的,其中a[0],a[1],a[2],a[3],a[4],分别代表数组中的元素的内容,并非数组元素的名字,数组元素没有名字。
二、数组的大小
数组在一片连续的内存空间中存储元素,其中元素的个数,可以显示或者隐式的指定。
比如:int a[5]={1,2}
int b[]={1,2}
其中a有五个元素,如果对其进行了元素的赋值,其他不写出来的都默认填进去0,也就是a[]={1,2,0,0,0},如果显示的指定了大小,但是列表中没有给出元素,那么就会填充随机值,这一点可以利用来初始化数组为0,只需要int a[5]={0};b只含有两个元素,隐式指定列表写了几个元素,就是几个元素。
另外,数组的大小:sizeof(a)
数组的长度(也就是元素的个数):sizeof(a)/sizeof(*a)
三、数组地址与数组名
1.数组名代表数组首元素的地址
2.数组的地址需要用取地址符&才能得到
3.数组首元素的地址值和数组的地址值相同
4.数组首元素的地址和数组的地址虽然值相同,但是意义不同
意义不同是因为,数组地址代表的是一整块存放数组元素内存空间的地址,但是首元素只是代表这个第一个元素的地址,虽然他们的地址相同,但是意义不同。
四、数组名的盲点
1.数组名可以看做一个常量指针,什么意思呢?就是不能作为左值使用,只能作为右值。
2.数组名“指向”的是数组当中首元素的起始地址。
3.在表达式中数组名只能作为左值使用,比如a[5]=b[5],绝对是错误的。
4.只有在下列场合,数组名不能看做常量指针:
数组名作为sizeof()函数的参数
数组名作为取地址运算符的参数
五、BUG实例解析
这个例子主要是为了说明数组和指针的一个区别,在文件test.c中,声明为数组了,但是定义在another.c文件中的时候是定义为一个指针,使用的时候会出现错误。根本原因,是因为指针存在一个寻址过程,而数组没有。具体例子 如下:
<span style="font-size:18px;">test.c
#include <stdio.h>
extern char p[];
int main(void)
{
printf("%s\n",p);
return0;
}
another.c
char* p="hello world!";
最后输出结果:乱码!</span>
为什么呢?其实原因很简单:原本another里面,我们定义了一个char*类型的指针p,p指向一个字符串hello world,p指针里面存放的是hello world字符串的起始地址,在test.c里面,我们将其声明成了数组,在打印的时候,数组直接指出输出p里面的东西,p里面存放的是地址,当然输出乱码了。而指针不同,打定义为指针的时候,会做一次寻址,根据p里面存放的地址,找出指向的内存单元的内容。所以编译器在处理数组的时候和处理指针的时候,有本质区别。所以数组名并不是指针,尤其在外部声明的时候要注意。
这篇帖子就总结到这里,如有不正确地方还请指出,大家共同进步!