C语言中的参数传递机制详解

  

<强> C中的参数传递

  

本文尝试讨论下C中实参与形参的关系,即参数传递的问题。

  

<强> C语言的参数传递

  

  

首先看下列代码:

        # include & lt; stdio.h>      int main () {   int n=1;   printf("实参n的值:% d,地址:% # x \ n”, n, n);   无效的改变(int i);//函数声明   改变(n);   printf("函数调用后实参n的值:% d,地址:% # x \ n”, n, n);   返回0;   }      空变化(int i) {   我printf("形参的值:% d,地址:% # x \ n”,我,和我);   我+ +;   printf("自增操作后形参我的值:% d,地址:% # x \ n”,我,和我);   }      之前      

编译后执行结果如下:

        实参n的值:1、地址:0 x5fcb0c   我形参的值:1、地址:0 x5fcae0   我自增操作后形参的值:2,地址:0 x5fcae0   函数调用后实参n的值:1,地址:0 x5fcb0c      之前      

可以看的到,在调用函数改变时,会在内存中单独开辟一个空间用于存放形式参数,实参n的值会复制给形参我。对于形参的任何操作都不会影响到主调函数中的实参n。这种参数传递方式是便是典型的值传递。

  

上例中的参数类型是int型,实际上,对于整形(int,短,长,长长),浮点型(浮点数、双、双),字符型(char)等基本类型的参数都是值传递。

  

<强>指针参数

  

在下面的例子中,函数的参数类型是一个指针:

        # include & lt; stdio.h>      空变化(int *我){   我printf("形参的值:% # x,地址:% # x \ n”,我,和我);   (我)* + +,//通过指针修改其所指空间的值   我+ +,//让指针指向下一块内存空间   printf("自增操作后形参我的值:% # x,地址:% # x \ n”,我,和我);   }      int main () {   int n=1;   int * p=, n;   printf (" n的值:% d,地址:% # x \ n”, n, n);   p printf("实参的值:% # x,地址:% # x \ n”, p, p);   改变(p);   printf("函数调用后实参p的值:% # x,地址:% # x \ n”, p, p);   printf("函数调用后n的值:% d,地址:% # x \ n”, n, n);   返回0;   }      之前      

编译后执行结果如下:

        n的值:1、地址:0 x5fcb0c   p实参的值:0 x5fcb0c地址:0 x5fcb00   我形参的值:0 x5fcb0c地址:0 x5fcae0   我自增操作后形参的值:0 x5fcb10地址:0 x5fcae0   p函数调用后实参的值:0 x5fcb0c地址:0 x5fcb00   函数调用后n的值:2,地址:0 x5fcb0c      之前      

指针是C语言中的一种特殊类型,它本身占用一定的内存空间,而存储的值却是某个内存地址。上例中,函数变化的参数是指向int型变量的指针,实参p是指向变量n的一个指针,在调用函数改变时,指针型的形参我也会得到一块内存空间,其值由实参p复制而来,都是主调函数中变量n的地址。对于指针类型,一般不会太关注其本身而更多的是考虑它所指向的值,所以,在更改函数内是通过指针来操作指针所指的内容(主调函数中的变量n)。这样,便实现了在被调函数内操作主调函数中数据的效果。

  

虽然通过指针型参数传递可以达到让被调函数内的操作作用于主调函数内数据的效果,但从实参和形参的角度来看,这种参数传递并没有和一般的传递方法有什么本质的区别,也是值传递方式。

  

当参数传递方式是值传递时,形参和实参都存储在各自的内存空间中,相互独立互不影响,它们之间唯一的联系便是在形参初始化时会使用实参的值。

  

<强>数组参数

  

在C语言中,数组名可以看作一个指向数组首元素的指针常量,那么当数组作为参数是又是如何传递呢?实际上,当函数形参是数组类型时,作为形参的数组名便不再代表数组,而是被编译器解析成一个指针。通过下面的例子可以看的出,数组类型的形参只是在函数签名中看上去是一个数组,但在函数体内,它已经彻底沦为一个指针。

        # include & lt; stdio.h>      空白arrArg (int[]的arr) {   arr printf("形参的值:% # x,地址:% # x \ n”,加勒比海盗,和arr);   printf (" sizeof (arr): % d, sizeof (int *): % d \ n”, sizeof (arr), sizeof (int *));   printf (" sizeof (arr [0]): % d, sizeof (int): % d \ n”, sizeof (arr [0]), sizeof (int));   printf(" *加勒比海盗:% d, arr [0]: % d \ n”,加勒比海盗,arr [0]);   printf (" * (arr + 1): % d, arr [1]: % d \ n”, * (arr + 1), arr [1]);   printf (“arr + 1: % # x,, arr [1]: % # x \ n”, arr + 1,, arr [1]);   加勒比海盗+ +;   printf("自增操作后形参arr的值:% # x,地址:% # x \ n”,加勒比海盗,和arr);   printf("自增操作后,*加勒比海盗:% d, arr [0]: % d \ n”,加勒比海盗,arr [0]);   }      int main () {   int []={1,2,3};   printf("实参一个的值:% # x,地址:% # x \ n ", a, a);   printf (" sizeof (a): % d, sizeof ([0]): % d \ n”, sizeof (a), sizeof ([0]));   arrArg(一个);   返回0;   }      

C语言中的参数传递机制详解