—-想了解C语言中的参数传递机制详解分享的全部内容且更多的C语言教程关注<计算机技术网(www.ctvol.com)!!>
C中的参数传递
C语言中的参数传递机制详解分享尝试讨论下C中实参与形参的关系,即参数传递的问题。
C语言的参数传递
值传递
首先看下列代码:
#include <stdio.h> int main(){ int n = 1; printf("实参n的值:%d,地址:%#xn", n, &n); void change(int i);//函数声明 change(n); printf("函数调用后实参n的值:%d,地址:%#xn", n, &n); return 0; } void change(int i){ printf("形参i的值:%d,地址:%#xn",i,&i); i++; printf("自增操作后形参i的值:%d,地址:%#xn",i,&i); }
编译后执行结果如下:
实参n的值:1,地址:0x5fcb0c 形参i的值:1,地址:0x5fcae0 自增操作后形参i的值:2,地址:0x5fcae0 函数调用后实参n的值:1,地址:0x5fcb0c
可以看到,在调用函数 change 时,会在内存中单独开辟一个空间用于存放形式参数 i ,实参 n 的值会复制给形参 i 。对于形参的任何操作都不会影响到主调函数中的实参 n 。这种参数传递方式是便是典型的值传递。
上例中的参数类型是int型,实际上,对于整形(int、short、long、long long)、浮点型(float、double、long double)、字符型(char)等基本类型的参数都是值传递。
指针参数
在下面的例子中,函数的参数类型是一个指针:
#include <stdio.h> void change(int * i){ printf("形参i的值:%#x,地址:%#xn",i,&i); (*i)++;//通过指针修改其所指空间的值 i++;//让指针指向下一块内存空间 printf("自增操作后形参i的值:%#x,地址:%#xn",i,&i); } int main(){ int n = 1; int * p = &n; printf("n的值:%d,地址:%#xn", n, &n); printf("实参p的值:%#x,地址:%#xn", p, &p); change(p); printf("函数调用后实参p的值:%#x,地址:%#xn", p, &p); printf("函数调用后n的值:%d,地址:%#xn", n, &n); return 0; }
编译后执行结果如下:
n的值:1,地址:0x5fcb0c 实参p的值:0x5fcb0c,地址:0x5fcb00 形参i的值:0x5fcb0c,地址:0x5fcae0 自增操作后形参i的值:0x5fcb10,地址:0x5fcae0 函数调用后实参p的值:0x5fcb0c,地址:0x5fcb00 函数调用后n的值:2,地址:0x5fcb0c
指针是C语言中的一种特殊类型,它本身占用一定的内存空间,而存储的值却是某个内存地址。上例中,函数change的参数是指向int型变量的指针,实参p是指向变量n的一个指针,在调用函数change时,指针型的形参i也会得到一块内存空间,其值由实参p复制而来,都是主调函数中变量n的地址。对于指针类型,一般不会太关注其本身而更多的是考虑它所指向的值,所以,在change函数内是通过指针来操作指针所指的内容(主调函数中的变量n)。这样,便实现了在被调函数内操作主调函数中数据的效果。
虽然通过指针型参数传递可以达到让被调函数内的操作作用于主调函数内数据的效果,但从实参和形参的角度来看,这种参数传递并没有和一般的传递方法有什么本质的区别,也是值传递方式。
当参数传递方式是值传递时,形参和实参都存储在各自的内存空间中,相互独立互不影响,它们之间唯一的联系便是在形参初始化时会使用实参的值。
数组参数
在C语言中,数组名可以看作一个指向数组首元素的指针常量,那么当数组作为参数是又是如何传递呢?实际上,当函数形参是数组类型时,作为形参的数组名便不再代表数组,而是被编译器解析成一个指针。通过下面的例子可以看出,数组类型的形参只是在函数签名中看上去是一个数组,但在函数体内,它已经彻底沦为一个指针。
#include <stdio.h> void arrArg(int arr[]){ printf("形参arr的值:%#x,地址:%#xn", arr, &arr); printf("sizeof(arr):%d, sizeof(int *):%dn",sizeof(arr), sizeof(int *)); printf("sizeof(arr[0]):%d,sizeof(int):%dn", sizeof(arr[0]), sizeof(int)); printf("*arr:%d,arr[0]:%dn", *arr, arr[0]); printf("*(arr+1):%d,arr[1]:%dn", *(arr+1), arr[1]); printf("arr+1:%#x,&arr[1]:%#xn",arr+1, &arr[1]); arr++; printf("自增操作后形参arr的值:%#x,地址:%#xn",arr, &arr); printf("自增操作后,*arr:%d, arr[0]:%dn",*arr, arr[0]); } int main(){ int a[] = {1,2,3}; printf("实参a的值:%#x,地址:%#xn",a,&a); printf("sizeof(a):%d,sizeof(a[0]):%dn",sizeof(a),sizeof(a[0])); arrArg(a); return 0; }
编译后执行结果如下:
实参a的值:0x5fcb00,地址:0x5fcb00 sizeof(a):12,sizeof(a[0]):4 形参arr的值:0x5fcb00,地址:0x5fcae0 sizeof(arr):8, sizeof(int *):8 sizeof(arr[0]):4,sizeof(int):4 *arr:1,arr[0]:1 *(arr+1):2,arr[1]:2 arr+1:0x5fcb04,&arr[1]:0x5fcb04 自增操作后形参arr的值:0x5fcb04,地址:0x5fcae0 自增操作后,*arr:2, arr[0]:2
可以看出,虽然形参arr被声明为int型数组,但在函数内部,arr已不再拥有数组的性质,而拥有了指向int型的指针的性质:
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/487913.html