C++学习之路——第二天(指针和引用)
指针
1、指针和二维数组
概述:不管是几维数组,当你使用数组名 a 而没有取地址操作符&时,它(a)都会退化为指向其第一层的指针。(一维数组指向首元素的指针,二维数组是第一行数组的指针,三维数组是指向其第一层(也就是第一个二维数组)的指针)
1、错误示范
int a[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
int **p = a; //错误
a value of type "int (*)[4]" cannot be used to initialize an entity of type "int **"
原因:二维数组名(在没有被取地址操作符&作用时)会退化为指向其第一行第一个元素的一级指针,即 a 会被当作 int (*)[4] 类型的值,这是一个指向包含 4 个整数的数组的指针。
2、正确示范
int a[3][4] = { {1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}};
int (*p)[4] = a;
此时 p 为指向包含 4 个整数的(一维)数组的指针。
3、三维数组情况?
int a[2][3][4];
int(*p)[3][4] = a;
a 的类型是 int(*)[3][4],此时 p 指向的是一个三维数组,p[0]指向的是一个二维数组,p[0][0]指向的是一个一维数组。
总结:不管是几维数组,当你使用数组名 a 而没有取地址操作符&时,它(a)都会退化为指向其第一层的指针。(一维数组指向首元素的指针,二维数组是第一行数组的指针,三维数组是指向其第一层(也就是第一个二维数组)的指针)
补充:
int b = 1;
int *p1 = &b;
cout << sizeof(int) << endl; //4
cout << sizeof(p1) << endl; //8
在大多数现代计算机系统中,指针的大小通常是固定的,不论它指向的是什么类型的数据。在 32 位系统中,指针通常是 4 个字节,而在 64 位系统中,指针通常是 8 个字节。我的电脑是 64 位系统,所以 sizeof(p1)是 8。
2、各种指针
int *p
char *p[5]
int (*p) (int a, int b)
1、3 中 p 先和*结合,所以是指针变量,分别指向int类型的变量和函数
2中 p 先和 [5] 结合,所以是指针数组,它的每一个元素是指针型数据
int **p
int (*p)[3]
int *p(int a, int b)
同理,1为(二级)指针变量,即指向指针类型变量的指针、
2为指针变量,指向包含3个元素的一维数组
3为声明一个函数,这个函数的返回值是指向int型变量的指针
简言之,看p先和谁结合
p如果先和结合,即表现出(p)的形式,则p为指针变量,
p如果先和[]结合(指针数组),先和()结合(函数声明,p就是函数名)
3、指向常量的指针和常指针
const char *name = "chen"
不允许修改name指针所指向chen
char s[] = "abcd"
char *const p = s
*p = 'e' //正确
p = p + 1 //错误
常指针,能够修改指针所指向的内容,但是不允许修改指针p