Pointer
int a = 1;
char b = 2;
int *p = &b; //错误,指针类型与变量类型不符(计算机是倒着寻址,所以读取b时,会读到a的地址)
printf("%d", *p);
int a = 4;
//指针的基类型要和它所指向的变量类型一致
//指针的初始化
int *p = &a; // *p定义时表示地址
printf("%d\n", *p); //定义以后,使用*p中的*则表示指针运算符,将对这块地址中存储的值,进行间接访问。
int b = 12;
p = &b; //p使用的时候表示地址
指针定义之后必须初始化,没有具体指向的指针不能使用。避免野指针。
int *p = NULL; // 定义指针变量以后,初始化指向为NULL(未指向任何一块地址)
指针常见错误用法:
//野指针异常,p1指向随机地址
int *p1;
*p = 10;
//空指针异常,p2没有指向
int *p2 = NULL;
*p2 = 10;
指针与一维数组
int array[] = {1,2,3,4,5};
int *p = array;
printf("a[0] = %d, a[0] = %d\n", array[0], *p);
printf("a[2] = %d, a[2] = %d\n", *(p + 2), p[2]);
for (int i = 0; i < 5; i++) {
printf("%d ", p[i]);
}
array 首元素地址(常量)
*p 首元素的值
p++; 指针p指向下一位
p + 1; 指向下一位,指针p位置不变
*(p + 1) 下一位的值, 等价于 p[1]
指针与二维数组
int arr[2][3] = {1 ,2 ,3 ,4, 5, 6};
int (*pr)[3] = arr; //数组指针,指向二位数组的指针
int *q[3] //指针数组
const修饰符
//对于基本类型, int const 和 const int相同
int const a = 11; //变量 a 只读,不能修改
const int b = 12; // 同上面一样, b 也是被 const修饰的变量(只读)
int a2 = 10;
int a3 = 12;
//const在 * 左边,可以改变指针[指向],不能通过 *p改变指向的[值]
int const *p1 = &a2;
const int *p2 = &a2;
p1 = &a3; //可以改变p1的指向, p1指向a3
*p1 = 15; //但是不能通过*p1修改所指向的变量的值
a3 = 15; //a3可以通过自身修改
//const 在 * 右边,可以改变*p所指向的[值],但是不能改变[指向]
int * const p3 = &a2;
p3 = &a3; //不能改变指向
*p3 = 15; //可以改变值
//[值][指向]都不能改变
int const * const p4 = &a2;
二维数组的地址
//二维数组的地址
int a[3][4] = {{1,2,3,4},{5,6,7,8},{9,10,11,12}};
printf("a = %p \n",a);
//a是二维数组的名字,相当于二维数组首元素(第1个一维小数组a[0])的地址
printf("a + 1 = %p \n", a + 1);
// a + 1 相当于第2个一维小数组a[1]的地址
printf("&a[0] = %p \n", &a[0]);
//a[0]是第1个一维小数组的数组名,所以a[0]是指向第一个元素a[0][0]的指针。&a[0]相当于a[0]升一级,那么&a[0]就是指向第1个一维小数组a[0]的指针
printf("&a[0] + 1 = %p \n", &a[0] + 1);
//&a[0] + 1相当于指向向第2个一维小数组a[1]的指针
printf("*a = %p \n", *a);
//a是二维数组的名字,相当于二维数组首元素(第1个一维小数组a[0])的地址。 *a相当于降一级,因此*a是指向第1个一维小数组的第一个元素a[0][0]的地址
printf("*a + 1 = %p \n", *a + 1);
//*a 是a[0][0]的地址,因此*a + 1是a[0][1]的地址
printf("a[0] = %p \n", a[0]);
//a[0]是第1个一维小数组的数组名,所以a[0]是指向第一个元素a[0][0]的指针
printf("a[0] + 1 = %p \n", a[0] + 1);
//a[0] + 1是指向第一个元素a[0][1]的指针
printf("&a[0][0] = %p \n", &a[0][0]);
//a[0][0]的地址
printf("&a[0][0] + 1 = %p \n", &a[0][0] + 1);
//a[0][1]的地址
预习:
什么是结构体?
结构体如何定义和使用?
什么是结构体数组?
共用体和结构体的区别?
什么情况下使用枚举?
typedef的使用