数组
1.数组在内存中的存储
数组是一些某种类型的数据的集合,这些数据在内存中连续存储,相邻的数据之间没有间隔。
某种类型:它可以是指基本的数据类型,路int类型,float类型,char类型,double类型等等,同时也可以是指针,
如果是指针的话,那么这个指针可以指向基本的数据类型,如指向int类型,指向double类型等,还可以指向一个数组,还可以指向一个函数
下面以一个简易的示意图来说明数组(以int类型的数组为例):
声明一个5个元素的int类型的数组(暂不初始化) ---
int arr[5];
那么这5个int类型的数据在内存中的存储方式是这样的(为了便于区别,用了不同的颜色进行表标注,每个方格里面的...表示未定义值):
在机器中,一般来讲,一个int类型的数据占据4个字节的空间,因此,5个int类型的数据需要20字节的内存空间。
在这里有两个概念需要区分:
数组的长度和数组占用的内存空间的长度
数组的长度是数组中元素的个数,我们的示例 -- int arr[5] -- arr的长度就是5
但是,数组arr在内存中的内存空间的长度却不是5,应该是5 x 4 = 20 字节
下面这段代码用于计算,数组在内存中的字节数:
int main() { int arr[5]; printf("%d\n", sizeof(arr)); return 0; }
程序输出结果:
那要如何计算数组元素的个数呢?
可以用数组在内存中的字节数去除以每个元素=的字节数,就是元素的个数:
printf("%d\n", sizeof(arr)/sizeof(int));
2.数组的初始化
在了解了数组在内存中的存储之后,就需要给数组中的每一个元素赋值,以便使用了,数组的初始化有这样一些方法:
1.
int arr[5] = {1, 2, 3, 4, 5};
在声明的时候,给出每个元素的初始化值
2. 部分初始化
int arr[5] = {1, 2, 3};
声明了5个元素,但是只给出了3个值,注意,这三个值是数组arr的前三个元素的值,元素4 和元素5会被编译器默认为初始值为0
3. 不给出数组的长度
int arr[] = {1, 2, 3, 4, 5};
这种初始化方法,编译器会默认数组的长度是5
3. 指针和数组
数组名是一个指针常量,它指向数组的第一个元素,也就是数组第一个元素的地址,可以通过这段代码来进行验证:
int main() { int arr[5] = {1, 2, 3, 4, 5}; printf("arr = %p\n", arr); printf("&arr[0] = %p\n", &arr[0]); return 0; }
程序输出:
我们可以看到,二者的数据是相同的。
现在把数组和指针结合起来,有这样的声明:
int a; int b[10]; int *c;
那么表达式:
b + 3
表示什么意思呢?
因为b是一个指向int类型的指针,所以,3这个值是需要跟句int类型的长度进行调整的,指针加上一个整数得到的是另外一个指针,它所指向的是数组第一个元素后移3个int长度的位置,
那
*(b + 3)
又表示声明意思呢?
*(b + 3) 表示在 (b + 3) 的基础上,进行解引用操作,或者取得那里的值或是把一个新值存于该处。
下面看着两个表达式:
int b[10]; int *c = b + 3;
使用图表表示如下图: