二级指针传参修改地址
bigfly Lv4

最近通过复习数据结构的相关知识对指针传参问题又有了更深的理解,在此记录以下

指针传参遇到的问题:

为什么有时候传参一级指针就可以,但有时候却需要二级指针?

1
2
3
一级指针:是一个指针变量,指向一个普通变量,并保存该普通变量的地址;

二级指针:是一个指针变量,指向一个一级指针,并保存该一级指针的地址;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>

int array[4]={1,2,3,4};

void test(int *t)
{
t++;
printf("t=%p\n",t);
}

int main()
{
int *p=array;
printf("p=%p\n",p);
test(p);
printf("p=%p\n",p);

}
1
2
3
4
输出结果为:
p=0x207030
t=0x207034
p=0x207030

这里有两个点:

  1. 一个指针占四个字节(32位机器)

  2. 虽然在test中对t进行++ 操作,但是并不会改变main中p的地址,因为在test(p)中传入的是p 此时的p就是一个int 型,值位0x207030数,只有当但当用 形参 int *t去接受 p 在test函数中 0x207030 才会被当作地址。而且只是在test函数中被当作地址。所以在test()函数中 对传入的参数进行++操作并不会影响到main函数中指针p的地址。虽然无法改变p的地址,但可以改变p中存放的值。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    #include <stdio.h>

    int array[4]={1,2,3,4};

    void test(int *t)
    {
    *t = 5;//改变传入地址中的值是一级指针传参的基本功能
    //t=0x114455;
    }

    int main()
    {
    int *p=array;
    printf("p=%p\n",p);

    test(p);
    printf("p=%p\n",p);

    printf("%d %d %d %d\n",array[0],array[1],array[2],array[3]);

    }

遇到问题:

​ 如果想要通过test()函数来修改p的地址应该如何操作呢?

解决方法:

​ 二级指针传参,不但可以改变一级指针所指的内容(如上代码中的作用),也可以改变一级指针的地址。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <stdio.h>

int array[4]={1,2,3,4};

void test(int **t)
{

*t = 0x114455;//改变一级指针的地址
//**t =5;//改变一级指针所指的对象
}

int main()
{
int *p=array;
printf("p=%p\n",p);

test(&p);
printf("p=%p\n",p);

printf("%d %d %d %d\n",array[0],array[1],array[2],array[3]);

}

如上代码,在main() 传入的是指针的地址,所以形参要用二级指针接收,此时在test()函数中 *t相当于对 **t进行解引,而 * *t=&p(一级指针的地址给了二级指针),解引相当于拿到二级指针 * *t中的内容也就是&p (p的地址),那么就可以通过 *t = 0x114455;去改变p的地址,也可以通过 * *t去改变一级指针所指的对象。

总结:

​ 不能通过一级指针传参来修改传入指针的地址,因为传入的p相当于一个变量,而在test()对这个和地址长的一样的变量进行修改,并不会影响到main()中p的地址。二级指针传参能解决这一问题的本质就是二级指针传入的是一个地址 ,既然传入的是地址那就能在test()中对地址进行改变。