1500字范文,内容丰富有趣,写作好帮手!
1500字范文 > C中二级指针与它指向的一级指针之间的秘密(深入++*pptr)

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

时间:2020-12-29 13:10:00

相关推荐

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

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,所以我们要注意的是,使用这种方式,命令行参数可能只能处理一次,因为指向参数的指针在内层循环中被破坏,如果多次处理参数,当你挨个访问列表时,对每个需要增值的指针都做一份拷贝。

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。