C中的参数传递

前言
     像C#这种高级语言使用得久了,有点觉得离底层的知识越来越远了,就像在dreamweaver的设计器中拼命地将一个表格拉来拉去调整大小,却不懂得直接编写HTML一样。基于“基础决定走得多远”的指导,我这段时候放下了.NET放下了C#,定下决心将C和数据结构系统地学一遍。
     在学线性表的时候,被C的参数传递给撞了一下头,习惯了C#,突然看到C的指针,一下子转不过弯来:
struct WEEKDAY
{
    char name[10];
    struct WEEKDAY *next_day;
} ;
int main()
{
    void del(struct WEEKDAY *p_day);
    void change(struct WEEKDAY week_day);
    //以下代码省略...
}
     同是操作一个结构体,为什么有的函数的形参是这个结构体的指针,而有的函数的形参却是这个结构体类型变量?它们两者有什么不同?
     原来,不同于C#的参数传递方式,C#有引用传递和值传递,而C中只有一种方式,就是值传递。就算是通过传入指针变量的方式来达到“引用传递”的目的,其实也只是复制了一个指针变量,本质上还是值传递。
     C中定义一个函数时候指定了函数的形参,但在定义的时候,形参并不占用内存,
而在该函数被调用的时候,形参才会被分配内存(在栈上进行开辟),用于存放传入的实参的值,也就是说,实参变量的值已经被复制了一份存放到函数被调用的时候为形参开辟的内存里,这时候,形参与实参并不是公用同一片内存空间,在被调函数里头改变传入的参数的值并不会影响实参变量的值。
还是借用经典的swap函数来实验:
int main()
{
    void swap(int*,int*);
    int a=1,b=2;
    printf("a=%d and b=%d before swap\n",a,b);
    printf("now swap...\n");
    swap(&a,&b);
    printf("a=%d and b=%d after swap\n",a,b);
    scanf("%d",&a);
}
void swap(int *p1,int *p2)
{
    int temp=*p1;
    *p1=*p2;
    *p2=temp;
}
结果: 

a=1 and b=2 before swap

now swap...
a=2 and b=1 after swap
如果将swap函数改成传递int变量,而不是int指针变量:(同时需要对函数的声明和调用部分作改变)
void swap(int p1,int p2)
{
    int temp=p1;
    p1=p2;
    p2=temp;
}
很显然,结果就成了:
a=1 and b=2 before swap
now swap...
a=1 and b=2 after swap
此时,在swap函数里怎样改变形参的值,对实参变量的值都没有任何变化。
小结:
在C#中,类是引用传递的,而在C中,跟“类”最相似的是结构体,所以在从C#倒回来学习C的时候,往往会以C#的思维去思考。本来C#中已经比较理解传参,但在C中能在内存的层次上再去深入,这应该就是C为什么是软开专业甚至是计算机专业必修的原因吧。网上还有很多深入到汇编层面上分析的,可以看到代码执行和栈的进出情况,可以在更底层的地方了解到代码的执行。只有弄懂了最底层的原理,才能在现在成为趋势的快速开发甚至是拖拉控件式的开发中保持清醒。

posted on 2012-01-07 09:59  wyman25  阅读(296)  评论(0编辑  收藏  举报

导航