函数参数传递

 
测试例子:
 

#include <stdio.h>
void print(char *arr)
{
    printf("%#x %#x %#x\n", &arr, arr, arr[0]);
}
int main()
{
    char arr[5] = "abcd";
    printf("%#x %#x %#x\n", &arr, arr, arr[0]);
    print(arr);
    return 0;
}

输出:

0xbf849b8b 0xbf849b8b 0x61
0xbf849b70 0xbf849b8b 0x61

对于第2,3个输出,很多人都能理解,但对第1个输出为什么不同,很多人还没有理解,认为是函数指针作为参数,进行地址传递,&arr也应该是一样的,这样想是因为对函数参数传递的实质还没有认识清楚。

不论是指传递还是地址传递,机制都是一样的,形参接收到实参传递过来的值进行使用。

当为值传递时:

实参a ----> 形参b: b接受了a值,对b的修改,不会影响到a。

当为地址传递时:

实参*a ---> 形参*b:b接受了a的值,此时a,b两个指针变量指向同一内存单元。对b的修改,不会影响到a,但对b指向的内存单元的修改,会导致a指向的内存单元也发生变化(因二者指向同一个内存单元)。

地址传递误区:有人认为地址传递时,b跟a就完全一样了,使用b就是在使用a(在C++的确有这样的机制,即引用),其实不然,在C中并没有引用机制,变量a在调用的函数域内不可见,需要分配一个变量b来接受a传过来的参数,然后使用b,正是这个误区导致很多人对上述例子的输出不解。

如果还对谭浩强版C语言书上一个例子(交换两个变量的值)有印象但还没有理解的,可以再回想一下。

#include <stdio.h>
void swap(int *a, int *b)
{
     int *tmp = a;
     a = b;
     b = tmp;
}

void swap2(int *a, int *b)
{
     int tmp = *a;
     *a = *b;
     *b = tmp;
}
int main()
{
    int a = 3, b = 5;
    swap(&a, &b);  //并不能交换两个变量的值
//  swap2(&a, &b);
    printf("%d %d\n", a, b);
    getchar();
    return 0;
}


总而言之,值传递与地址传递仅仅是传递的变量类型不同,前者传递普通的变量,后者传递指针变量,而其传递机制是一样的。  
posted @ 2013-04-19 14:05  ydzhang  阅读(182)  评论(0编辑  收藏  举报