2

我正在读一本由 Brian W. Kernighan 和 Dennis M. Ritchie 撰写的关于 c 编程语言的书。

这本书列出了下面的代码

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

并说:

因为参数是按值传递的,所以 strcpy 可以 以任何它喜欢的方式使用参数st

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

根据另一本书C如何编程

在 C 中,您使用指针和间接运算符来模拟调用引用。当调用带有应该修改的参数的函数时,会传递参数的地址。

在后一种观点中,它绝对是引用调用。

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

顺便说一句,分配后*s = *t,与哪个比较'\0'*s还是*t

4

2 回答 2

4

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

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

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

t = test("A");

它是合法的,并且表明参数 s 可以在不影响调用者的情况下被修改(它传递了一个文字......)。

但是你的例子中的 strcpy() 做了一些不同的事情:它需要一个指针 s,并修改 s 指向的内容。指针很强大,可以用来模拟“按引用传递”(指针就是引用)。

赋值后 *s = *t 被持有,与 '\0' 比较的是哪一个?*种类?

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

if (i=3) ...

是相同的

i=3;
if (i) ...

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

于 2018-06-27T04:36:43.077 回答
2

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

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

于 2018-06-27T05:03:02.150 回答