我正在为我的一些 C 库上的 C 技能打扫灰尘。在完成了第一个工作实现之后,我现在正在检查代码以使其更高效。目前我的主题是通过引用或值传递函数参数。
我的问题是,为什么我会在 C 中按值传递任何函数参数?代码可能看起来更简洁,但它不会总是比通过引用传递效率低吗?
我正在为我的一些 C 库上的 C 技能打扫灰尘。在完成了第一个工作实现之后,我现在正在检查代码以使其更高效。目前我的主题是通过引用或值传递函数参数。
我的问题是,为什么我会在 C 中按值传递任何函数参数?代码可能看起来更简洁,但它不会总是比通过引用传递效率低吗?
因为为计算机编写代码不如为下一个人类编写代码重要。如果您要传递引用,那么任何读者都必须假设任何被调用的函数都可以更改其参数的值,并且有义务在调用之前对其进行检查或复制参数。
你的函数签名是一个契约,它把你的代码分开,这样你就不必为了理解某个区域发生的事情而将整个代码库放到你的脑海中,通过传递引用你会让下一个人的生活变得更糟,作为程序员,你最大的工作应该是让下一个人的生活变得更好——因为下一个人很可能就是你。
在 C 中,所有参数都按值传递。真正的引用传递是当您看到修改的效果时根本没有任何显式间接:
void f(int c, int *p) {
c++; // in C you can't change the original paramenter passed like this
p++; // or this
}
但是,通常需要使用值而不是指针:
int sum(int a, int b) {
return a + b;
}
你不会这样写:
int sum(int *a, int *b) {
return *a + *b;
}
因为它不安全而且效率低下。效率低下,因为有一个额外的间接。此外,在 C 中,指针参数建议调用者将通过指针修改值(尤其是当指向的类型的大小小于或等于指针本身时更是如此)。
请参阅C 中的引用传递。通过引用传递在 C 中是用词不当。它指的是传递变量的地址而不是变量,但您是通过值传递指向变量的指针。
也就是说,如果您要将变量作为指针传递,那么是的,它会稍微更有效率,但主要原因是能够修改它指向的原始变量。如果您不想这样做,建议您按价值衡量以明确您的意图。
当然,就 Cs 较重的数据结构之一而言,所有这些都没有实际意义。无论您喜欢与否,数组都通过指向其第一个变量的指针传递。
两个原因:
很多时候,您将不得不取消引用您多次传递的指针(想想一个长的 for 循环)。您不想在每次要查找该地址的值时都取消引用。直接访问速度更快。
有时你想在你的函数中修改传入的值,而不是在调用者中。例子:
void foo( int count ){
while (count>0){
printf("%d\n",count);
count--;
}
}
如果您想使用通过引用传递的内容来执行上述操作,您将不得不在您的函数中创建另一个变量来首先存储它。