二重指针的理解

二重指针一般用的场合:

(1)二重指针指向一重指针的地址。

#include<stdio.h>

int main()

{

int a = 10;

int *P1;

int **P2;

P1 = &a;

P2 = &P1;

return 0;

}

(2)二重指针指向指针数组的地址。

#include<stdio.h>

int main()

{

int *a[4];//指向整形变量的指针数组

int **p;

p = a;//注意这里为什么可以这么赋值?因为a是数组首元素的地址,并且a的首元素为int *类型,所以a便是int *类型的地址,因此可以这么赋值

}

int a=1,*p,**q;
p=&a; p存放变量a的地址
q=&p; q存放指针p的地址
**q=*p=a=1;
q是指针p的地址
*q是指针p的内容,即a的地址
**q是指针p指向区域的内容*p,*p=a

普通的指针存放变量的地址
指向指针的指针存放指针的地址

例:

int a=3, *p, **q;
p=&a;
q=&p;
这样赋值后, *q就是p, **q就是a

例:
#include <stdio.h>
int main(void)
{
        char *q = "a";//"a"是一个字符串,将"a"赋值给字符指针是把第一个字符的地址赋值给q,这句话相当于是:char *q;q="a" 
        char **p = &q;//这句话相当于是:char **p;p=&q;//二重指针p的值是指针q的地址 
        printf("%d\n", *p);//二重指针p加*号,是取内容,意思是指针q的内容,即字符串a的地址 
        return 0;
}
//输出结果是:一串数字,即地址,如果改成%s输出,则输出的是字符a,如果改成%c输出,就要相应的修改参数为变量名,将*p改为:**p ,如下面的例子。
 

例:

#include <stdio.h>
int main(void)
{
        char c='a';
        char *q=&c;
        char **p = &q;//双重指针
        printf("%c\n", **p);
        return 0;
}

例:

#include<stdio.h>
void F1(int *p)
{
    p++;
    *p = 9;
}
 
void F2(int **p)
{
    (*p)++;
}
//以上函数中,接收数据的参量都是p,而不会是*p或者**p
 
int* F3(int *p)
{
    p++;
    return p;
}
 
 
int main(void)
{
    int *p;
    int a[2] = { 4,5 };
    p = a;
    printf("1--------%d\n", *p);//开始值为4
 
    F1(p);
    printf("2--------%d\n", *p);//4
    //由于只是传值,在子函数F1的内部改变复制品的值,并不会改变原品p的值
    //可以理解为用两个变量指向同一个地址,即形参p和实参p指向同一个地址
    //其中形参p++,另外一个实参p并不会受影响
    //但是可以修改指针所指的值,如F1代码中将a[1]的值改为9;
    printf("2`-------%d\n", a[1]);//9
    
    F2(&p);
    printf("3--------%d\n", *p);//9
    //传址,p=&p(指针的地址,即p是指向指针的指针),*p=*(&p)=p;
    //如果要修改指针p,则应该传入指针p的地址(&p),此时进行*p++操作,其实是对实参指针p进行操作
 
    getchar(); getchar();
    return 0;
}
 
//这个例子说明:如果要在子函数中修改主函数传过来的指针的指向,那么主函数应该向子函数传入指针的地址(而非指针本身);
//此时在子函数中进行*操作后可以获得原来指针,而不是原来指针的复制品,之后可以根据需要修改指针。
//或者,将返回值类型改为指针类型,然后返回修改后的指针,给原来主函数的指针,如F3函数,此时在主函数中需要添加p=F3(p)代码。
 

猜你喜欢

转载自blog.csdn.net/wwcxrnsy/article/details/83689639