二级指针
所谓二级指针,就是指向指针的指针,即该指针的值是另外一个一级指针的地址。与此类似,如果一个指针中存放的是二级指针的地址,那么该指针就是三级指针,与此类推。
char c;
char *pch = &c;//pch为一级指针
char **ppch = &pch;//ppch为二级指针,存放这一级指针的地址
printf(“%c”, **ppch);
printf(“%p,%p,%p”, pch, ppch, *ppch);
如上图所示,pch是一级指针,存放着变量c的地址;ppch是二级指针,存放这一级指针pch的地址。只要画出了上面的关系图,那么一次*运算,就是向右移动一次,两次*运算,就是往右移动两次,即*pch即为c,*ppch为pch,**ppch即为c。
如果指针做实参,那么传实参的指针(地址),就必须使用二级指针。通俗的说,要改变指针的值,必须传指针的指针(地址)(二级指针)
int main(void)
{
char *p = NULL;//p是指针,做为实参,初始值为NULL
get_memory();//通过该函数,为p分配一块内存。如何定义get_memory函数和传参p?
strcpy_s(p, 100,”hello world”);
printf(“%s\n”, p);
free(p);
p=NULL;
}
因此get_memory函数设计如下:
1,传指针的指针(二级指针):
void get_memory(char **p)
{
*p=(char *)malloc(100);
}
调用方式:
get_memory(&p);
2,传指针的引用:
void get_memory(char *&p)
{
p=(char *)malloc(100);
}
调用方式:
get_memory(p);
利用指针与函数的知识,分析下面代码的输出:
int i = 0, j = 20, *p1 = &i, *p2 = &j;
void f(int **ptr1, int *ptr2)
{
int *tmp = ptr2;
**ptr1 *= 10;
*ptr2 *= 10;
ptr2
= *ptr1;
*ptr1 = tmp;
}
请问调用f(&p1,
p2)之后i,
j, p1, p2的值各是什么?
分析与解答:
首先我们画出程序执行过程中调用f()函数时堆栈的情况如下图所示:
图
程序执行栈
第1句int *tmp = ptr2;即tmp = &j,tmp指针指向了变量j。
第2句:**ptr2 即*(*ptr2)即*p1 即 i。**ptr2 *= 10 即为i *= 10 即为0;所以i 的值为0。
第3句*ptr2 *= 10 即为*p2_ *= 10即为j *= 10即为 200;所以j的值为200。
第4句ptr2 = *ptr1则为p2_ = *ptr1即为p2_ = p1;
第5句*ptr1 = tmp则为p1 = tmp = &j
因此答案为:
i = 0
j = 200
p1 = &j
p2 = &j
可以通过下面的程序来验证一下:
#include <stdio.h>
void f(int **ptr1, int *ptr2)
{
int *tmp = ptr2;
**ptr1 *= 10;
*ptr2 *= 10;
ptr2 = *ptr1;
*ptr1
= tmp;
}
int main(void)
{
int i = 0, j = 20, *p1 = &i, *p2 = &j;
f(&p1, p2);
printf("i = %d, j = %d, &i = %x, &j = %x, p1 = %x, p2 =
%x\n",
i, j, &i, &j, p1, p2);
return 0;
}
仔细检查上面的函数的输出,看它是否与计算结果一致。实践是检验真理的唯一标准。写一个实验程序去验证推理,是程序员的一个好习惯。