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

2020-01-06 17:11:25王旭

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)。这样,便实现了在被调函数内操作主调函数中数据的效果。