这是按引用还是按值调用? C

时间:2018-06-27 03:20:12

标签: c pass-by-reference call-by-value

我正在阅读Brian W. Kernighan和Dennis M. Ritchie撰写的一本书,称为c编程语言。

这本书列出了以下代码:

void strcpy(char *s, char *t){
    while((*s = *t) != '\0'){
        s++;
        t++;
    }
}

并说:

  

由于参数是通过值传递的,因此strcpy可以使用参数    s t

我不同意。为什么参数要按值传递?

根据另一本书C如何编程:

  

在C语言中,您使用指针和间接操作符进行模拟   呼叫参考。当调用带有参数的函数时   修改后,将传递参数的地址。

从后一种观点来看,这绝对是按引用调用。

请告诉我哪种方法正确,为什么,谢谢!

btw,在分配* s = * t后,将哪个与'\ 0'比较? * s或* t?

2 个答案:

答案 0 :(得分:4)

C总是按值传递参数,这意味着被调用函数将接收调用者引用的内容的本地副本。

被调用函数可以修改接收到的值,因为它是本地副本,而不会影响原始值。例如:

char *test(char *s) {
  s++;
  return s;
}

t = test("A");

这是合法的,表明可以修改参数s而不影响调用方(传递文字...)。

但是您的示例的strcpy()却有所不同:它使用指针s,并修改s指向的指针。指针功能强大,可以用来模拟“按引用传递”(是指针)。

  

在分配* s = * t之后,将哪个与'\ 0'比较? * s或* t?

* s:在C中,赋值返回一个值-且该值是赋值完成后所赋变量的值。写作:

if (i=3) ...

相同
i=3;
if (i) ...

如果我是一个指针,语法会有所不同,但是机制相同,则赋值将“使用”指针,并且整个赋值将用作测试中要评估的表达式。

答案 1 :(得分:2)

许多人认为这个成语既不是按值调用也不是按引用调用。就其价值而言,Kernighan和Ritchie的 C编程语言确实在C“引用”中调用数组和指针,尽管它仅使用术语“按值调用”而不是“按引用调用”。一旦C ++添加了另一种称为引用的语言功能,这种用法似乎已经过时了。

接受指针并取消引用的函数通常会使用具有按引用调用的语言编译为与该函数相同的机器代码。唯一的区别不仅在于没有语法糖:如果指针参数本身不是const,则可以为其重新分配一个新值并使其引用其他内容,即“按引用调用”语义不允许。在具有按引用调用的语言中,您无法编写s++t++来使函数参数引用不同的对象! (C字符串的存储方式可以为指针添加偏移量以获得子字符串,而大多数语言将字符串的长度存储在其内存的前几个字节中。)但是,您通常可以想到在C ++中引用T&等同于传递保证不会成为T *const的{​​{1}},并且在其名称前带有一个不可见的星号。