C++学习笔记四之指针的基础概念(进阶)

179 阅读6分钟

指针的基础概念(进阶)

昨日回顾

#include <iostream>
using namespace std;
/*
	指针的概念、定义、内存大小、
	指针运算符:(&,*)、指针偏移
	void*  0地址
	
	指针与数组(一维数组、二维数组、字符数组):

	指针变量赋值:
	1.相同类型变量的地址
	2.相同类型的指针变量
*/
int main()
{
	int n[5] = { 5, 4, 3, 2, 1 };
	int *pn = n;//一维数组名的值等价于&n[0]
	/*
		遍历数组的各种方式
	*/
	//1.利用下标访问数组元素
	for (int i = 0; i < 5;i++)
	{
		cout << n[i] << endl;//等价于*(n+i)
	}
	//2.利用指针访问数组元素
	for (int i = 0; i < 5;i++)
	{
		cout << *(pn + i) << endl;
	}
	for (int i = 0; i < 5; i++)
	{
		cout << *(n + i) << endl;
	}
	//3.利用指针访问数组元素
	for (int i = 0; i < 5; i++)
	{	
		cout << pn << endl;
		//pn改变指向
		cout <<*pn++ << endl;//++优先级>*
	}
	cout << pn << endl;

	for (int i = 0; i < 5; i++)
	{
		//cout << *n++ << endl;//错误,n是常量。不能自加
	}
	pn = n;
	for (int i = 0; i < 5; i++)
	{
		(*pn)++;//等价于n[0]++
	}
	for (int i = 0; i < 5; i++)
	{
		cout << n[i] << endl;
	}
	//求数组的内存大小
	cout << sizeof(n) << endl;//20
	//求指针的内存大小
	cout << sizeof(pn) << endl;//4
	cout << sizeof(&n[0]) << endl;//4

	pn = &n[5];
	cout << pn[-2] << endl;//等价于*(pn-2)



	return 0;
}

数组指针及定义

  • 数组指针:指向数组的指针 &组名
  • 定义: 类型 (*指针变量名)[大小];
    • 类型:指针变量指向数组的类型
    • 大小:指针变量指向数组的大小
int n[3][4] = {
		{1,2,3,4},
		{8,7,6,5},
		{9,10,11,12}
	};
	//定义一个数组指针的变量    &数组名
	int (*pn)[4]= n;//等价于&n[0]
	for (int i = 0; i < 3;i++)
		{
			//每一个一维数组的首地址
			cout << n + i << endl;//&n[i]
			//每一个一维数组的第一个元素的首地址
			cout << *(n + i) << endl;//n[i]
		}
	
	for (int i = 0; i < 3; i++)
	{
		for (int j = 0; j < 4;j++)
		{
			//n[i][j]等价于*(*(n+i)+j)
			cout << *(*(n + i)+j) << endl;//n[i]
		}
	}

	//检测数组的内存
	cout << &n[0][0] << endl;
	cout << &n[1][0] << endl;
	cout << &n[2][0] << endl;

	cout << n << endl;
	cout << &n[0] << endl;

	cout << n[0] << endl;
	cout << n[1] << endl;
	cout << n[2] << endl;


	int m[5];
	//&m[0]
	cout << m << endl;//数组第一个元素的首地址
	cout << &m << endl;//取数组的首地址
	cout << m + 1 << endl;//1个单位=int型大小
	cout << &m + 1 << endl;//1个单位=数组的大小
	

指针数组与二级指针

  • 指针数组:数组中每一个元素都是指针
    • 类型 *数组名[大小];
  • 二级指针:类型 **指针变量;
//求字节大小方法:三种类型的指针和指针数组  指针指向的类型(*取内容(如果为指针,去*号,如果为数组,去维数(从左往右)))
//定义一个数组指针,指针指向一个3行4列的int的二维数组
	int(*p)[3][4];
	cout << sizeof(p) << endl;//4   
	cout << sizeof(*p) << endl;//48  int(*p)[3][4]; -> int p[3][4]; 4*3*4
	cout << sizeof(**p) << endl;//16 int(*p)[3][4]; -> int p[4];    4*4
	cout << sizeof(***p) << endl;//4 int(*p)[3][4]; -> int p;		4

	int* (*p1)[4][5][6];
	cout << sizeof(p1) << endl;//4
	cout << sizeof(*p1) << endl;//4*4*5*6  int* (*p1)[4][5][6] -> int* p1[4][5][6]  4*4*5*6
	cout << sizeof(**p1) << endl;//4*5*6   int* (*p1)[4][5][6] -> int* p1[5][6]     4*5*6
	cout << sizeof(***p1) << endl;//4*6    int* (*p1)[4][5][6] -> int* p1[6]	    4*6
	cout << sizeof(****p1) << endl;//4	   int* (*p1)[4][5][6] -> int* p1;			4
	cout << sizeof(*****p1) << endl;//4    int* (*p1)[4][5][6] -> int  p1;			4

	//p2是一个3行4列二维数组,每一个元素都是指针(数组指针),该指针指向一个三维数组(该三维数组每一个元素都是int*型).
	int* (*p2[3][4])[4][5][6];
	cout << sizeof(p2) << endl;//4*3*4			int* (*p2[3][4])[4][5][6] -> int *p2[3][4] 4*3*4
	cout << sizeof(*p2) << endl;//4*4			int* (*p2[3][4])[4][5][6] -> int *p2[4]	  4*4
	cout << sizeof(**p2) << endl;//4			int* (*p2[3][4])[4][5][6] -> int *p2	  4
	cout << sizeof(***p2) << endl;//4*4*5*6;	int* (*p2[3][4])[4][5][6] -> int* p2[4][5][6] 4*4*5*6
	cout << sizeof(****p2) << endl;//4*5*6;		int* (*p2[3][4])[4][5][6] -> int* p2[5][6]	  4*5*6
	cout << sizeof(*****p2) << endl;//4*6		int* (*p2[3][4])[4][5][6] -> int* p2[6]	  4*6
	cout << sizeof(******p2) << endl;//4		int* (*p2[3][4])[4][5][6] -> int* p2	  4
	cout << sizeof(*******p2) << endl;//4		int* (*p2[3][4])[4][5][6] -> int  p2	  4


	int n[2][3];
	int *pn = n[0];//n[0]等价于 &n[0][0]
	int(*p3)[3]=n;//n等价于 &n[0]
	//int **pp = &n;//错误
	int **pp = &pn;//pn是int*型 pp指向的类型是int*

练习代码

int a[3][4] = {
		{ 1, 2, 3, 4 },
		{ 8, 7, 6, 5 },
		{ 9, 10, 11, 12 }
	};
	int * arr[3][4] = {
		NULL
	};
	//三种类型的指针和指针数组  指针指向的类型(*取内容(如果为指针,去*号,如果为数组,去维数(从左往右)))
	int *p1 = a[0];//p1是一个指针
	int **p2 = &p1;//p2是一个二级指针
	int(*p3)[4] = &a[0];//p3是一个数组指针,指向一个int型的一维数组
	int*(*p4)[4] = arr;//p4是一个指针,指向一个一维的数组,其数组内的每个元素都是int *型
	int*(*p5)[3][4] = &arr;//p5是一个指针,指向一个二维数组,其数组内的每个元素都是int *型
	int*(*p6[3])[3][4];		//p6是一个一维数组,每一个元素都是指针,其指向一个3*4的二维数组,数组内的每个元素都是int *型
	int*(**p7[3])[3][4];	//p7是一个一维数组,每一个元素都是二级指针,其指向一个3*4的二维数组,数组内的每个元素都是int *型
	int **(**p8[3])[3][4];	//p8是一个一维数组,每一个元素都是二级指针,其指向一个3*4的二维指针数组,数组内的每个元素都是int *型

	
	double** (**p9[3][4])[5][6];
	cout << sizeof(p9) << endl;//4*3*4
	cout << sizeof(*p9) << endl;//4*4
	cout << sizeof(**p9) << endl;//4
	cout << sizeof(***p9) << endl;//4
	cout << sizeof(****p9) << endl;//4*5*6
	cout << sizeof(*****p9) << endl;//4*6
	cout << sizeof(******p9) << endl;//4
	cout << sizeof(*******p9) << endl;//4
	cout << sizeof(********p9) << endl;//8