指针与函数传参
普通变量作为函数形参
#include <stdio.h> //&a和&b不同,说明a和b不是同一个变量(在内存中a和b是独立的2个内存空间) //但是a和b是有关联的,实际上b是a赋值得到的。 void func1 (int b) { //在函数内部,形参h的值等于实参a printf("b = %d\n",b); printf("in furc1, &b = %p\n",&b); } int main(void) { int a = 4; printf("&a = %p\n",&a); func1(a); return 0; }
VC++6.0编译如下
(1)函数传参时,普通变量作为参数时,形参和实参名字可以相回也可以不同,实际上都是用实参来替代相对应的形参的。
(2)在子函数内部,形参的值等于实参,原因是函数调用时把实参的值复制给了形参
(3)这就是很多书上写的“传值调用”(相当于实参做右值,形参做左值)
数组作为函数形参
#include <stdio.h> void func2(int a[]) { printf("sizeof(a) = %d\n",sizeof(a)); printf("in func2,a = %p\n",a); } int main(void) { int a[3] = {0}; printf("sizeof(a) = %d\n",sizeof(a)); printf("a = %p\n",a); func2(a); return 0; }
VC++6.0编译如下:
第一行的sizeof(a)是sizeof(数组名),得到的就是整个数组所占的内存空间,第三行的就是sizeof(数组a的起始地址),可见两个起始地址是一样的
(1)数组名作为形参传参时,实际传递是不是整个数组,而是数组的首元素的首地址(也就是整个数组的首地址。因为传参时是传值,所以这两个没区别)。所以在子函数内部,传进来的数组名就等于是一个指向数组首元素首地址的指针。所以sizoof得到的是4.
(2)在于函数内传参得到的数组首元素首地址,和外面得到的数组首元素首地址的值是相同的。很多人把这种特性叫做“传址调用”(所谓的传址调用就是调用子函数时传了地址(也就是指针),此时可以通过传进去的地址来访问实参。)
(3)数组作为函数形参时,[ ]里的数字是可有可无的。为什么?因为数组名做形参传递的实际只是个指针,根本没有数组长度这个信息。
指针作为函数形参
#include <stdio.h> void func3(int *a) { printf("in func3,sizeof(a) = %d\n",sizeof(a)); printf("in func3,a = %p\n",a); } void func2(int a[]) { printf("in func2,sizeof(a) = %d\n",sizeof(a)); printf("in func2,a = %p\n",a); } int main(void) { int a[3] = {0}; //printf("sizeof(a) = %d\n",sizeof(a)); printf("a = %p\n",a); printf("\n"); func2(a); func3(a); return 0; }
VC++6.0编译如下:
(1)只有一句话:和数组作为函数形参是一样的.这就好像指针方式访问数组元素和数组方式访问数组元素的结果是一样的。