关于c中 指针数组、数组指针、二级指针的理解与证明

起因

对于 指针数组、数组指针、二级指针 这三个概念有点混淆,就花了一些时间证明。并且解释了一下关于这三种情况下的 *(p+1) 到底指向哪里的问题。

语法示例

int* pointerArr[5];	//指针数组,存放指针的数组

int (*arr) [5];		//数组指针,指向数组的指针

int ** pp;				//二级指针

*(p+1)情况

指针数组

意义

表示取出 第二个位置的 int* 数据而已,并未对这个位置的指针取值。
注意*的位置,是修饰前面的int,
表示这是一个一维数组,只是存储的类型是int
指针类型,仅此而已

跨越字节

int*类型,一个变量在64位下占用8字节
这里只是跳跃数组中一个元素,所以只跳跃8字节

代码示例
int main() {
	
	int a = 10;
	int b = 20;

	int * pointerArr[2];
	pointerArr[0] = &a;
	pointerArr[1] = &b;

	//只是取出 第二个位置的 int* 数据而已,并未对这个位置的指针取值
	cout << "*(pointerArr + 1) = " << *(pointerArr + 1) << endl;
	cout << "pointerArr[1] = " << pointerArr[1] << endl;
	
	//取出数组中,第2个位置的指针,指向的值
	cout <<"*pointerArr[1]="<< *pointerArr[1] << endl;
	return 0;
}

数组指针

意义

本身是数组指针,*p时代表原数组,(p)[index] 对数组中元素取值,而(p+1) 此时是表示,跳过一个int[5] 的长度,指向下一个int[5]的数组,因为p此时修饰的是 int[5] 类型,
就像 int *q,q修饰的是int类型一样

跨越字节

跳过了 int[5] 长度的字节,也就是 一整个数组,大概是 5*sizeof(int)

注意

对于数组指针来说,*(p+1) 这种跳跃,仅在二维数组时有意义,不然你跳跃了一个数组,跳到哪个地方去呢?一维数组紧挨着的内存,不一定是可读的内存

代码示例
int main() {
	
	int arr[3] = { 10,20,30 };
	int(*p)[3] = &arr;

	//*p 表示得到原本的数组的地址
	//*p +1 表示原本&arr[1],还不是值
	// *(*p+1) 表示对原本的数组取1下标的值 arr[1]
	cout << "(*p)[0]=" << (*p)[0] << endl;
	cout << "(*p)[1]=" << (*p)[1] << endl;
	cout << "*(*p+1)=" << *(*p + 1) << endl;

	//*(p+1) 此时是表示,跳过一个int[3] 的长度,指向下一个int[3]的数组
	//因为p此时修饰的是 int[3] 类型,
	//就像 int *q,q修饰的是int类型一样


	//跳跃仅对二维数组有意义

	int secondArr[2][3] = {
		{1,2,3},
		{4,5,6}
	};
	int(*secondP)[3] = &secondArr[0];//实际上,应该看做是secondArr[0] 这个数组的首地址

	//此时指向了 secondArr[1] 这个数组
	secondP++;

	//遍历secondArr[1] 这个数组
	for (size_t i = 0; i < 3; i++)
	{
		cout << (*(secondP))[i] << endl;
	}
	return 0;
}

二级指针

意义

*(p+1) 对于二级指针来说,是跳过了一个 int 的内存,指向下一个int,仅对于 数组情况下,才有意义

跨越字节

p修饰的类型是int*,那么自增之后就是跳过一个 int*,在64位情况下指针占用8字节,因此是跳过8字节

代码示例
int main() {

	
	int a =10;
	int b = 20;
	int *one = &a;//一级指针
	int **second = &one;//二级指针

	
	//*second = one
	//**second = *one = a
	cout << "**second=" << **second
		<< ",*one=" << *one
		<< ",a=" << a << endl;


	//*(p+1) 对于二级指针来说,仅在数组情况下有意义

	int*  arr[2];//*修饰int,因此故意写在前面
	arr[0] = &a;
	arr[1] = &b;

	int* * p = &arr[0];

	//通过*(p+1)得到b的地址
	int * bAddr = *(p + 1);

	//访问变量b的值
	cout <<  "b="<<b
		<<  ", *bAddr="<<*bAddr
		<< ", *arr[1]="<<*arr[1]
		<< endl;

	return 0;
}
  • 6
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值