本节内容
1.指针(指针数组、数组指针)
2.二维数组(指针操作与二维数组)
3.结构体、联合体、枚举
一、指针
1.什么是指针?
内存中字节的编号地址称为指针
2.指针的大小?
固定为四字节
3.指针变量的定义
指针变量定义格式为:变量类型* 指针变量名=地址
例如:int* p1=NULL、int* p2=&a;
4.指针的解引用
如下:
5.指针+1能力
我们要首先知道在指针指向一个数组时,指针变量代表数组首元素的地址
指针加一能力可以理解为:指针遍历 同一块 内存
如下
6.常量指针和指针常量
常量指针:在定义指针变量的时候如果前用const修饰,那么就成称该指针为常量指针
例如:const int* p;
指针常量:本质上是一个常量,用指针修饰它(指针指向的地址不能修改,地址的内容可以改变)
例如:int* const p;
7.二级指针
指向一级指针数据的指针
例如:int** q;
这里要知道二级指针解一次引用为一级指针
6.指针数组数组指针
指针数组:指针数组可以简单理解为指针的数组,顾名思义就是存储指针的一个数组
例如:int* p[4];
数组指针:数组指针可以简单理解为数组的指针,顾名思义就是指向一个数组的指针(常出现在二维数组),数组指针指向大小为n个元素的数组
例如:int (*p)[4]; //此处数组指针为指向大小为4个整型元素的数组
7.无类型指针
无类型指针可以指向任意类型变量的地址
例如:void* p;
二、二维数组
1.什么是二维数组?
本质上二维数组是由多个大小相等的一维数组构成。
定义方式为:类型名 数组名[行表达式][列表达式];
例如:int arr[3][4];//arr为三行四列的一个数组
2.在逻辑上二维数组相当于一个x行 * y列的平面图,那如果访问第2行的第y+1列会发生什么情况?
如上所示,访问第2行第5列时,超出了二维数组列范围的大小,超出部分会加入下一行的行中,所以,此处2行5列访问的为3行2列,元素为8。
所以意味着二维数组是逻辑上不相邻但物理上是相邻的
3.二维数组行与列长度求法
行求法:int row=sizeof(arr)/sizeof(arr[0])
行求法:int col=sizeof(arr[0])/sizeof(arr[0][0])
4.二维数组中指针加一能力(数组指针)
一行一行向下偏移
指针定义 int (*p)[2]=&arr[0];
arr[2][3]<=>*(*(arr+2)+3)
三、结构体、联合体、枚举
1.结构体struck
(1)什么是结构体
不同数据类型的集合称为结构体,结构体是一种类型。
(2)结构体的字节对齐问题
1)结构体没有嵌套结构体情况下,结构体内前几个元素的数据类型所占字节数之和是下一个元素类型的整数倍,如果不是给前一个类型补字节,补成下一个类型的整数倍,最大基本类型的整数倍
Ps:数组不是最大基本类型 e.g:char arr[20]的最大基本类型为char型1字节,但它总共占20字节
2)结构体必须是最大基本类型的整数倍
3)如果结构体嵌套,则嵌套后被嵌套结构体的按其第一个数据的类型作为该结构体的最大基本类型(与数组原理相同),最后结构体内总字节大小要为该结构体中最大基本类型的整数倍
4)pragma park(x)函数使 指定对齐方式大小为x
如图所示
2.联合体union
(1)什么是联合体?
联合体和结构体类似,也是一种自己定义的类型,联合体内所存变量共同使用一块内存空间。
(2)联合体的大小
联合体的大小至少是最大成员的大小,当最大成员大小不是最大对齐数的整数倍时,联合体大小就要对齐到最大对齐数的整数倍数
如图
3.枚举enum
(1)什么是枚举?
枚举是一种特殊的数据类型,是一种同类型的集合。
例如: enum ChessType {black,white};
(2)枚举的大小
枚举的底层为整型,所以大小固定为四字节
例如 enum colorType{red,blue,green}; 所以在此枚举中整型0代表红色,1代表蓝色,2代表绿色
0 1 2
enum colorType{red=8,blue,green};
8 9 10
enum colorType{red=8,blue,green=1};
8 9 1