学习C(九)
数组:
我们可以将数组看做一个存放指定类型数据的容器,这个容器被划分为n个连续的模块,每一个模块存储了一个指定类型的数据
举例说明:当声明一个整型变量的时候,系统会为该变量分配4个字节的内存空间,这4自己内存空间地址绝对连续(0x01~0x04)
当声明一个能够存放整型数据的数组的时候,系统会以4个字节为1个模块,然后确定需要n个模块,最终将4 n个字节的内存空间分配给该数组。同理这4n个字节的内存也是绝对连续
什么叫做向数组内存放数据:所谓的存放,其实就是将已知的数据赋值给数组中某一个特定的地址上去。
数组的声明及定义:
数组类型+数组名[数组的容量] = {具体存放的数据,如果有多个数据,则使用逗号隔开}
等号前面为数组的声明部分,后面为数组的定义部分
数组名:就是一个变量名,随意选取,但是注意变量名的命名规则
数组类型的确定:完全取决于所存放数据的数据类型,如果存放的数据是int型,那么该数组就是int型,如果存放的是int 型,那么该数组就是int型
数组的容量:这里的容量就是刚才所说的n个模块中的n,也就是说该数组最多能存放n个数据
举例说明:声明一个 整型数组 arr
① int arr[5] = {1,3,5,7,9};
声明整型数组arr,他的容量为5个模块,并为他分配20个字节的内存空间,最后将他的每一个模块分别初始化赋值为1,3,5,7,9
② int arr[5] = {1};
声明整型数组arr,他的容量为5个模块,并为他分配20个字节的内存空间,最后将他的首个模块初始化赋值成1,剩余模块初始化赋值为0
③ int arr[5] = {0};
声明整型数组arr,他的容量为5个模块,并为他分配20个字节的内存空间,最后将他所有的模块全都初始化赋值为0
④ 当声明数组的时候,如果没有声明数组的容量,则此时必须定义该数组。因为如果为声明容量,则系统不知道应该分配给该数组多少内存空间,所以只能通过数组实际定了多少个模块来分配内存空间。也就是说此时数组的容量完全取决于定义的数据的数量
⑤ 当使用一个变量去声明数组的容量的时候,此时不能定义数组
因为:在编译阶段,编译器不会知道该变量的值,所以可能出现定义的数据数量超过声明的数组容量。这样的矛盾只有在运行阶段才会被计算机发现。所以为了避免这种情况的出现,编译器就禁止这样的情况出现。
普通的变量,变量名就能代表他管理的内存空间上存放的数据
数组名代表什么?
!!!一个指针,指向了一片内存地址,无论该地址多大,这个指针永远只能指向首个字节的地址
数组名其实就是一个指针,作为指针,他就指向了该数组所管理的内存空间的首个元素的地址,首个元素的地址也只能是首个元素的首字节的地址:
当一个数组名单独出现的时候,他既可以代表整个数组,也可以 退化 成一个指针,指向了首地址。
既然数组名在不取地址的情况下,单独出现都会退化成一个指针,那么数组之间就不能整体相互赋值
当数组名退化成指针后,该指针只能指向该数组,不能更改指向。
指针之间相互赋值本质在修改操作对象,不是修改操作的数据
指针和数组的关系:指针可以完全的代表数组,但是数组不能完全的代表一个指针。
数组的访问方式:既然已经将需要保存的数据,存放入了数组,那么,如何访问这些已经存放的数据
数组的访问方式: 数组名[指定下标位置n] 就能访问到从首个模块开始,向后移动n个模块中的值。注意,首个模块为第0个模块
所以,这里的[]拥有两个功能:
①向前/前后移动模块的功能
②取值(*)功能
我们把针对整个数组的访问,称为数组的遍历
遍历:从头到尾,对每一个数据访问且只放一次的操作。
!!!在所有数组问题中,如果没有思路,先遍历
在针对数组的操作中,有以下几个常规操作(注意,这些操作是针对数据结构的)
①向数据结构中添加数据: 增
②从数据结构中移除数据: 删
③修改数据结构中特定的数据: 改
④查询数据结构中特定的数据: 查
⑤对整个数据结构进行特定化的排序:排
⑥遍历整个数据结构: 遍历
以上6个功能,都需要封装成函数来实现。
通常情况下编写的顺序为:⑥④① 后面顺序随意
/*
数组的声明及定义
*/
#include<stdio.h>
int main(){
int arr[] = {1,2};//直接赋值给数组arr,此时[]内不用指明数组长度
int vol = 5;
int arr2[vol];//此时的变量vol必须是已经定义了的
return 0;
}
#include<stdio.h>
/*
用指针操作指向数组
*/
int main(){
int arr[5] = {1,3,5,7,9};//0x01 ~ 0x20
printf("%p\n",arr);//arr指向0x01~0x04这个模块,那么其实arr指向了这个模块的首字节地址,也就是0x01
printf("%p\n",&arr);//&arr指向了0x01~0x20这个模块,那么也只能指向这个模块的首字节地址,也就是0x01
int* p = arr;
printf("%d\n",p[4]);
return 0;
}