c语言学习笔记(15) 数组基础

摘要:总结了数组的概念,数组大小的计算方法,数组地址和数组名的关系,数组存在的一些盲点,最后用一个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文件中的时候是定义为一个指针,使用的时候会出现错误。根本原因,是因为指针存在一个寻址过程,而数组没有。具体例子    如下:

test.c
#include 
 
extern char p[];
 
int main(void)
{
    printf("%s\n",p);
    return0;
}
 
another.c
char* p="hello world!";
 
最后输出结果:乱码!

    为什么呢?其实原因很简单:原本another里面,我们定义了一个char*类型的指针p,p指向一个字符串hello world,p指针里面存放的是hello world字符串的起始地址,在test.c里面,我们将其声明成了数组,在打印的时候,数组直接指出输出p里面的东西,p里面存放的是地址,当然输出乱码了。而指针不同,打定义为指针的时候,会做一次寻址,根据p里面存放的地址,找出指向的内存单元的内容。所以编译器在处理数组的时候和处理指针的时候,有本质区别。所以数组名并不是指针,尤其在外部声明的时候要注意。

    这篇帖子就总结到这里,如有不正确地方还请指出,大家共同进步!

 

你可能感兴趣的:(C)