由此我们看到,数组作为参数与指针作为参数并没有什么区别,因为编译器会自动将形参中的数组名转换为一个指针。所以,以下面代码中的两个函数签名是等效的:
void func(int arr[]){
}
void func(int * p){
}
实际上,如果我们同时定义了它们,编译器会报“redefinition”错误而无法编译。
此外需要注意的是,虽然我们可以将形参声明成一个数组,但在编译器看来它只是一个指针而已,因此形参中有关数组长度的信息会被自动忽略,在实际调用时实参数组的长度与形参指定的数组长度没有任何关系,而且在函数内也无法通过 sizeof(arr)/sizeof(arr[0]) 得到数组的长度。
//形参arr的指定长度5无意义,会被编译器忽略,未防止误解建议不写
void arrArg(int arr[5]){
// sizeof(arr)是指针类型的大小而非数组大小,因此len不是数组长度
int len = sizeof(arr)/ sizeof(arr[0]);
}
自定义类型参数
数组这种“组合”类型在作为参数传递时被解析为指针方式传递,那么当结构体(struct)、共同体(union)以及枚举类型作为参数传递时是否也是如此呢?
枚举类型本质上是int,所以当形参被声明为枚举类型时,在编译器看来就是int型,以下面代码中的两个函数签名是等效的,编译器会报“redefinition”错误:
enum week{ Mon, Tues, Wed, Thurs, Fri, Sat, Sun };
void func(enum weekday){}
void func(int i){}
下面是结构体和共同体分别作为参数时的示例:
#include <stdio.h>
struct Date{
int year;
int month;
int day;
};
void changeStruct(struct Datedate){
printf("形参date的地址:%#xn", &date);
date.year ++;
date.month = 12;
date.day = 31;
printf("形参date的值:%d-%d-%dn",date.year,date.month,date.day);
}
union Data{
int i;
float f;
double d;
};
void changeUnion(unionDatadata ){
printf("形参data的地址:%#xn", &data);
printf("形参data的值,d.i:%d, d.f:%f, d.d:%fn",data.i,data.f,data.d);
data.d = 2017.4;
printf("函数调用后,形参data的值,d.i:%d, d.f:%f, d.d:%fn",data.i,data.f,data.d);
}
int main(){
printf("结构体参数传递示例:n");
struct Datedate = {2017,4,2};
printf("实参date的地址:%#xn", &date);
printf("实参date的值:%d-%d-%dn",date.year,date.month,date.day);
changeStruct(date);
printf("函数调用后,实参date的值:%d-%d-%dn",date.year,date.month,date.day);
printf("共用体参数传递示例:n");
unionDatadata={.i=2017};
printf("实参data的地址:%#xn", &data);
printf("实参data的值,d.i:%d, d.f:%f, d.d:%fn",data.i,data.f,data.d);
changeUnion(data);
printf("函数调用后,实参data的值,d.i:%d, d.f:%f, d.d:%fn",data.i,data.f,data.d);
return 0;
}










