数组与指针之二——二级指针之一

定义是这样:

多级指针(二级指针),C语言多级指针的用法详解 (biancheng.net)

这是针对变量,且是一级一级的取的。但是我们经常要面对数组,用到二级指针。如前面第一篇所述,对一维数组名取地址,则表示数组地址,再对其求值,则表示首元素的地址,所以按说对一维数组名取地址就是二级指针,可以定义一个二级指针,然后将一维数组名取地址赋值给它。

但是,实际写程序发现会报错:

编辑器就报错了。编译:

可见,虽然&a是指向指针的指针,但如第一篇所述,它确是指向4个元素数组的指针,也就是指向一个行数组的首个元素,是有限制的,类型是int (*)[4],并不表示是指向一个int变量的地址,即int **。

那么,按说,因为数组第一个元素是int型,我对数组第一个元素取地址后再取地址,应该是二级指针int**了吧?尝试:

pp = &(&a[0]);

编译报错:

这里用了两个&号,表示取两次地址,含义 上是没错的,这报错,是C语法的问题,是将前面一个&当成与操作,所以需要左值是变量或者函数调用形式,而右边只有括号里的&是真取了地址,所以报C2440,无法从int*转换为int**。

那么,这种赋值是不行的么?难道说二级指针不能指向数组的么?非也!这里就有个神奇的讲究了。其实就是和参考文章中一样,也就是一般二级指针赋值一样,分两次赋值就可以啦!

int a[4] = {1,3,5,4};
int** pp;  // 二级指针 
int* p;
p = &a[0];
pp = &p;

这种其实是多此一举了,还不如直接用p,因为其实pp表示存第一个元素的地址的地址,pp+1这种操作已经和原数组没什么关系了。程序:



#include <stdio.h>

int main()
{
	int a[4] = {1,3,5,4};
	int* p;
	int** pp;
	
	printf("a=%d\n", a);
	printf("&a=%d\n", &a);
	printf("*a=%d\n", *a);
	printf("a+1=%d\n", a + 1);
	printf("&a+1=%d\n", &a + 1);
	printf("*a+1=%d\n", *a + 1);

	p = &a[0];//a代表数组首元素地址
	pp = &p;
	printf("p=%d\n", p);
	printf("pp=%d\n", pp);
	printf("*p=%d\n", *p);
	printf("*pp=%d\n", *pp);
	printf("**pp=%d\n", **pp);

	printf("p+1=%d\n", p + 1);
	printf("pp+1=%d\n", pp + 1);

	printf("*(p+1)=%d\n", *(p + 1));
	printf("**(pp+1)=%d\n", **(pp + 1));  // 这行编译不报错,但运行报错,非法访问内存空间

	return 0;
}

运行到倒数第二个printf:

a=177208296
&a=177208296
*a=1
a+1=177208300
&a+1=177208312
*a+1=2
p=177208296
pp=177208344
*p=1
*pp=177208296
**pp=1
p+1=177208300
pp+1=177208352
*(p+1)=3

 

注意看*(p+1),即可表示下一个元素,但是**(pp+1),并不是表示第二个元素值,而是因为pp+1这个地址不允许访问而执行出错!

将上面程序中的p初始化赋值语句改为:

p = a;

结果是一样的。其实也是,因为一维数组名就是首元素的地址。

所以,重点来了,对于一维数组,这种二级指针其实是多此一举了,那么对于二维数组呢?应该是刚刚好了吧?

下篇讨论吧~

  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值