这是通过引用还是通过值进行的调用? C

问题描述 投票:2回答:2

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

这本书列出了以下代码:

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

并说:

因为参数是按值传递的,所以strcpy可以以任何方式使用参数s和t

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

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

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

在后一种观点中,它绝对是逐个引用的。

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

顺便说一下,在赋值* s = * t之后,哪一个与'\ 0'相比较? * s或* t?

c pass-by-reference call-by-value
2个回答
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) ...

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


2
投票

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

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

© www.soinside.com 2019 - 2024. All rights reserved.