第10章 指针和数组
——《C Primer Plus》的搬运工,仅记录自己觉得重要的内容,方便以后参考
10.1指针和数组
10.1.1初始化数组
#define N
const int arr[N];//数组为只读的状态,不可以修改值
初始列表元素少于定义的元素个数,元素自动补0
sizeof(arr)=N · (数据类型占用的字节数)
10.1.2指定初始化器
可以初始化指定的元素,未指定的元素补0
int arr[6]={[5]=211};
初始化指定位置,后面的值初始化按顺序初始化
int arr[6]={[2]=1,3};//表示[2]=1,[3]=3
10.1.3给元素数组赋值
不允许一个数组给另一个数组赋值(两个数组名=)
10.1.5指定数组的大小
可以允许变长数组
int n=5;
int arr[n];
10.3指针和数组
数组名,和数组首元素的内存地址,都是常量,不可以被修改
指针增加,增加的是一个存储单元,+1 表示指向下一个元素的地址,递增它所指向类型的大小
内存中每个字节都有一个地址编号
10.4函数、数组和指针
int* a=int a[];//仅在函数原型和函数定义头中使用
10.5指针操作
两个指针相减得到的是元素的相差个数
创建一个指针时,系统只分配了存储指针本身的内存,并未分配存储数据的内存,因此必先初始化指针
10.6保护数组中的数据
10.6.1对形式参数使用const
int sum(const int arr[],int n);//函数不修改arr指向的数组中的内容
10.6.2const的其他内容
- const 修饰数组
const int days[MONTHS];
- 指向const的指针
const double* pd=rates;//double rates[5]
把pd指向的double类型的值声明为const,指针不能修改所指向的值;如10.6.1对形式参数使用const
但是 rates[5] 没有声明为 const,所有仍然可以用过其他方式对数组进行修改
把const数据和非const数据的地址初始化为指向const的指针是合理的;即const 指针修饰const数据和非const数据
但是不能把const指针指向非const数据
- 指针常量
不能指向别处的地址
double* const pc=rates;//doube rates[5]
- 创建指针时使用两次const
表示即不能修改地址,也不能修改指向的值
10.7指针和多维数组
int zippo[4][2];
zippo(的值)是数组首元素的地址,
zippp==&zipop[0];
zippo[0]的值和它首元素的地址相同
zippo[0]==&zippo[0][0]
zippo==&zippo[0]; zippo[0]==&zippo[0][0];
*zippo==zippo[0]==&zippo[0][0];
**zippo==*zippo[0]==zippo[0][0];
10.7.1指向多维数组的指针
int arr[4][2];
int (*pz)[2];//表示指向一个数组的指针,被指向的数组有两个int型的值
pz=arr;
int **p;//表示的是一个指向指针的指针
不能用p=arr;//arr[4][3]
但是*p=arr[0]可以
10.7.2指针的兼容性
避免指针嵌套
避免用普通指针指向const数据
10.7.3函数和多维数组
int arr[3][4];
func(arr);
void func(int (*pt)[4]);
void func(int pt[][4]);
10.9复合字面量
匿名数组
(int [2]){1,2};
匿名数组不能先创建后使用,只能在使用的同时创建
int* p;
p=(int [2]){1,2};
int sum(const arr[],int n);
sum((int []){1,2,3,},6);
int (*pt)[2];
pt=(int [2][2]){{1,2},{3,4}}
——所有代码仅表示关键步骤,可能无法正常运行