• C语言参数传递(值传递、地址传递)+二级指针


    参数传递

    C语言参数传递一般分为:值传递和地址传递(本质上只有值传递

     

    (注意:C语言中没有引用传递,C++才有引用传递,因为很多C语言环境是用C++编译器编译,使得C看起来支持引用传递,导致很多网上很多blog都把引用传递归为C语言参数传递的一类,

    当使用Microsoft Visual C++ 2010 Express或VC6之类的编译器时使用引用传递就无法编译通过)

     

    值传递:

    形参是实参的拷贝,改变形参的值并不会影响外部实参的值。从被调用函数的角度来说,值传递是单向的(实参->形参)

     

     1 #include <stdio.h>
     2 
     3 void swap(int x, int y);
     4 
     5 main()
     6 {  
     7     int a = 10, b = 20;
     8 
     9     swap(a, b);
    10     printf("a=%d
    b=%d
    ", a, b);
    11 
    12     return 0;
    13 }
    14 void swap(int x, int y)
    15 {
    16     int t;
    17 
    18     t = x;
    19     x = y;
    20     y = t;
    21 }

     上述代码运行后a、b的值并未改变

     

    地址传递:

    形参为指向实参地址的指针,当对形参的指向操作时,就相当于对实参本身进行的操作

     1 #include <stdio.h>
     2 
     3 void swap(int *x, int *y);
     4 
     5 main()
     6 {  
     7     int a = 10, b = 20;
     8 
     9     swap(&a, &b);
    10     printf("a=%d
    b=%d
    ", a, b);
    11 
    12     return 0;
    13 }
    14 void swap(int *x, int *y)
    15 {
    16     int t;
    17 
    18     t = *x;
    19     *x = *y;
    20     *y = t;
    21 }

     上述代码执行后a和b值交换,a=20、b=10

     

    易错点补充:

     1 #include <stdio.h>
     2 
     3 void swap(int *x, int *y);
     4 
     5 main()
     6 {  
     7     int a = 10, b = 20;
     8     int *pp = &a;
     9     int *kk = &b;
    10     swap(pp, kk);
    11     printf("a=%d
    b=%d
    ", *pp, *kk);
    12 
    13     return 0;
    14 }
    15 void swap(int *x, int *y)
    16 {
    17     int *t;
    18 
    19     t = x;
    20     x = y;
    21     y = t;
    22 }

     请读者想一下,上述代码执行后a和b的值是否交换,为什么?

    上述代码看起来像交换了指针pp和kk的指向,实际上并没有

    代码的运行结果a=10、b=20,运行结果是a和b的值并没有改变,因为这时使用的实参pp,kk是值传递,传递的是指针的值,以指针pp来说,指针的值是变量a的地址,

    指针的值传入后用形参int *x和int *y接收,这里x和pp虽然都指向变量a的地址,但指针x和pp自身的地址并不相同(意思是x拷贝了一份pp的值),意味着你能改变变量a的值,但是不能改变pp的值(这里与值传递相似)

    为了更加直观,清晰的看出值的交换,这里添加一些代码来显示内存和变量的值

     1 #include <stdio.h>
     2 
     3 void swap(int *x, int *y);
     4 
     5 main()
     6 {
     7     int a = 10, b = 20;
     8     int *pp = &a;
     9     int *kk = &b;
    10 
    11     printf("a的地址%p----b的地址%p
    
    ", &a, &b);
    12     printf("pp的值%p----kk的值%p
    ", pp, kk);
    13     printf("pp的地址%p----kk的地址%p
    
    ", &pp, &kk);
    14     swap(pp, kk);
    15     printf("a = %d
    b = %d", *pp, *kk);
    16 
    17     return 0;
    18 }
    19 void swap(int *x, int *y)
    20 {
    21     int *t;
    22     
    23     printf("x的值%p----y的值%p
    ", x, y);
    24     printf("x的地址%p----y的地址%p
    ", &x, &y);
    25 
    26     t = x;
    27     x = y;
    28     y = t;
    29 }

    从pp和x的地址可以看出,x和pp是两块不同的内存区域,x在swap函数内执行完后并不会对pp值产生任何影响,相当于复制了一份pp的值,如下图

    (灵魂画手已上线)

    传入指针的值虽然不能对指针的值进行修改,但是可以通过地址直接对a的值进行修改也可以实现交换,代码如下

     1 #include <stdio.h>
     2 
     3 void swap(int *x, int *y);
     4 
     5 main()
     6 {
     7     int a = 10, b = 20;
     8     int *pp = &a;
     9     int *kk = &b;
    10 
    11     swap(pp, kk);
    12     printf("a = %d
    b = %d", *pp, *kk);
    13 
    14     return 0;
    15 }
    16 void swap(int *x, int *y)
    17 {
    18     int t;
    19     
    20     t = *x;
    21     *x = *y;
    22     *y = t;
    23 }

     传入指针的值和和传入变量的地址在数值上是一样的,但是一个是传值传递一个地址传递,如下图

     

    (灵魂画手已经上线)

    二级指针

    上面提到的参数传递方式有,传入变量的值,传入变量的地址,传入指针的值三种参数传递方式

    下面介绍第四种,传入指针的地址,上面第二种(传入变量的地址)和第三种(传入指针的值)传递方式使用的用来接收参数的形参都是int *类型的指针

    这里因为传入的是指针的地址,所以要使用二级指针int **x,因为传入的指针的地址,实现值的交换的方式就有两种一种是直接对变量的值进行修改,另一种就是对指针的值进行修改

    第一种:直接对变量值进行修改

     1 #include <stdio.h>
     2 
     3 void swap(int **x, int **y);
     4 
     5 main()
     6 {
     7     int a = 10, b = 20;
     8     int *pp = &a;
     9     int *kk = &b;
    10 
    11     swap(&pp, &kk);
    12     printf("a = %d
    b = %d", *pp, *kk);
    13 
    14     return 0;
    15 }
    16 void swap(int **x, int **y)
    17 {
    18     int t;
    19     
    20     t = **x;
    21     **x = **y;
    22     **y = t;
    23 }

    第二种:对指针的值进行修改

     1 #include <stdio.h>
     2 
     3 void swap(int **x, int **y);
     4 
     5 main()
     6 {
     7     int a = 10, b = 20;
     8     int *pp = &a;
     9     int *kk = &b;
    10 
    11     swap(&pp, &kk);
    12     printf("a = %d
    b = %d", *pp, *kk);
    13 
    14     return 0;
    15 }
    16 void swap(int **x, int **y)
    17 {
    18     int *t;
    19 
    20     t = *x;
    21     *x = *y;
    22     *y = t;
    23 }

    注意swap函数里用int *来交换指针的值,而不能用int **来进行交换,读者可自行修改代码验证想一下为什么?

    下面是二级指针示意图

    (灵魂画手已上线)

    若有疑问,欢迎留言

  • 相关阅读:
    linux 中输出匹配行的下一行
    linux中sed命令删除匹配行及其下一行
    linux中常见的文件类型
    linux中grep命令i匹配以制表符开头的行
    linux中输出匹配行及其后的若干行
    linux中如何删除文本开头的多个空格和tab键
    linux中删除匹配行及其后的若干行
    普通用户修改个人密码:sudo : is not in the sudoers file. This incident will be reported.
    一坨iBatis 的代码。
    ubuntu误删除Desktop文件夹,导致桌面默认路径更改
  • 原文地址:https://www.cnblogs.com/lanhaicode/p/10342932.html
Copyright © 2020-2023  润新知