C中二级指针与它指向的一级指针之间的秘密(深入++*pptr)

本文详细解释了C语言中二级指针的概念及其使用方法,包括++*pptr与*pptr++的区别,并通过实例说明如何正确使用这些操作。此外还介绍了在处理命令行参数时二级指针的应用技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C语言里二级指针的意思是指向指针的指针,一级指针就是普通的指针,一个二级指针一定是对应着一个一级指针,那么二级指针和这个它对应的一级指针之间有什么秘密呢?


1. 首先明白在二级指针使用中 ++*pptr 与 *pptr++ 之间的区别

首先申明一下,这里的pptr和标题中的一样,都代表着指向指针的指针,是一个二级指针,所以用了两个'p'来表示嘛。接下来看下面的代码:

int main(int argc, char ** argv)
{
	char * ar[5] = {"ruby", "java", "c++", "python", "js"};//定义一个含5个指针元素的指针数组 
	char ** pptr = ar;//定义一个二级指针,并初始化为ar 
	
	printf("pptr = %p\n", pptr);
	printf("*pptr = %p\n", *pptr);
	printf("++*pptr = %p\n", ++*pptr);	
}
程序的输出是:


第一行输出都明白,第二行第三行地址却仅仅加了1,说明第三行是"ruby"中u的地址。

那么换成*pptr++呢?

程序的输出是:


我们发现,地址并没有加1,那是因为*pptr++中,pptr先和++结合,但是它所代表的是自增之前的地址,再用*运算符获取到一个它对应的一级指针,所以打印出来的地址并没有改变。而在++*pptr中,pptr先和*运算符结合,得到它所对应的一级指针,再对这个一级指针++,且是自增之后的地址,所得到的地址自然是加了1。

注意:*pptr++虽然地址没有变,但是它仍然是递增的,增了多少?实际上增的是二级指针,所以结果是404005。


2. 重点:深入++*pptr

先看下面一段代码:

int main(int argc, char ** argv)
{
	char * ar[5] = {"ruby", "java", "c++", "python", "js"};//定义一个含5个指针元素的指针数组 
	char ** pptr = ar;//定义一个二级指针,并初始化为ar 
	char ** pptr_t = ar;//复制一份pptr 
	
	printf("*++*pptr = %c\n", *++*pptr);
	printf("**pptr_t = %c\n", **pptr_t);	
}
输出是多少呢?

有人的答案是:*++*pptr = u, **pptr_t = r

很遗憾,答案是错的,不过答对了一半,*++*pptr = u 是正确的,那么**pptr_t又是多少呢?

肯定会有人疑问,pptr_t不是和pptr开始都一样吗,都是指针数组ar首元素的地址,pptr_t又没有进行别的操作,**pptr_t的值不应该仍然是r吗?

然而正确答案是:*++*pptr = u, **pptr_t = u !

原因在于:++*pptr操作已经将pptr对应的那个一级指针*pptr自增了,直接改变了指针数组中第一个指针元素,它指向的不再是r而是u,当下一次访问这个一级指针上的值时,即**pptr_t的值就是改变后的u了!


3. 应用:在处理命令行参数时遇到的问题

有些操作系统,包括UNIX和MS-DOS,让用户在命令行中编写参数来启动一个程序的执行。当在处理命令行参数时,有些程序允许用户在一个参数中放入多个选项字母,例如下面的一个命令行:

prog -abc name1 name2 name3

-abc是将-a,-b,-c三种选项字母结合在一起,同样拥有三种选项。这交由下面的一段代码来处理:


while (( opt = *++*argv) != '\0')
{
	switch (opt)
	{
		case 'a':
			option_a = TRUE;
			break;
		/*etc. */ 
	}
}

可以看到,程序中运用了++*argv,所以我们要注意的是,使用这种方式 ,命令行参数可能只能处理一次,因为指向参数的指针在内层循环中被破坏,如果多次处理参数,当你挨个访问列表时,对每个需要增值的指针都做一份拷贝。


评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值