这个调用在 C 中是通过引用调用还是通过值调用?

Is this call by reference or by value in C?

我正在阅读由 Brian W. Kernighan 和 Dennis M. Ritchie 合着的 c 编程语言一书。

本书列出了下面的代码

void strcpy(char *s, char *t){
    while((*s = *t) != '[=10=]'){
        s++;
        t++;
    }
}

并说:

Because arguments are passed by value, strcpy can use the parameters s and t in any way it pleases

我不同意。为什么上面的参数是按值传递的?

根据另一本书C how to program:

In C, you use pointers and the indirection operator to simulate call-by reference. When calling a function with arguments that should be modified, the addresses of the arguments are passed.

从后一种观点来看,肯定是call-by-reference

请告诉我哪种方式是正确的,为什么,谢谢!

btw,赋值后*s = *t,和'[=12=]'比较的是哪个? *s*t?

C 始终按值传递参数,这意味着被调用函数接收调用者引用的任何内容的本地副本。

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

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

t = test("A");

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

但是您示例中的 strcpy() 做了一些不同的事情:它接受一个指针 s,修改 s 指向的内容。指针很强大,可以用来模拟"pass by reference"(一个指针一个引用)

after assignment *s = *t is held, which one is compared with '[=13=]'? *s or *t?

*s: 在C中,一个赋值returns一个值——而这个值就是赋值完成后被赋值变量的值。写作:

if (i=3) ...

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

如果 i 是一个指针,语法会有所不同,但机制是相同的,赋值将 "use" 指针和整个赋值的值用作要在测试中评估的表达式。

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

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