C 编程 - 引用传递

发布于 2024-09-13 00:45:00 字数 542 浏览 12 评论 0原文

在下面的 C 程序中,我不明白为什么在调用 foo 后 buf[0] = 'A' 。 foo 不是在进行值传递吗?

#include <stdio.h>
#include <stdlib.h>

    void foo(char buf[])
    {
      buf[0] = 'A';
    }

    int main(int argc, char *argv[])
    {
      char buf[10];

      buf[0] = 'B';
      printf("before foo | buf[0] = %c\n", buf[0]);
      foo(buf);
      printf("after foo | buf[0] = %c\n", buf[0]);

      system("PAUSE"); 
      return 0;
      }

输出:

before foo | buf[0] = 'B' 
after foo | buf[0] = 'A'

In the C program below, I don't understand why buf[0] = 'A' after I call foo. Isn't foo doing pass-by-value?

#include <stdio.h>
#include <stdlib.h>

    void foo(char buf[])
    {
      buf[0] = 'A';
    }

    int main(int argc, char *argv[])
    {
      char buf[10];

      buf[0] = 'B';
      printf("before foo | buf[0] = %c\n", buf[0]);
      foo(buf);
      printf("after foo | buf[0] = %c\n", buf[0]);

      system("PAUSE"); 
      return 0;
      }

output:

before foo | buf[0] = 'B' 
after foo | buf[0] = 'A'

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(12

红墙和绿瓦 2024-09-20 00:45:00
void foo(char buf[])

相同

void foo(char* buf)

与调用它时foo(buf)

,您按值传递指针,因此会创建指针的副本。指针的副本指向与原始指针相同的对象(或者,在本例中,指向数组的初始元素)。

C 不具有按引用传递语义,而 C++ 具有按引用传递语义。 C 中的所有内容都是按值传递的。指针用于获取引用语义传递。

void foo(char buf[])

is the same as

void foo(char* buf)

When you call it, foo(buf), you pass a pointer by value, so a copy of the pointer is made.

The copy of the pointer points to the same object as the original pointer (or, in this case, to the initial element of the array).

C does not have pass by reference semantics in the sense that C++ has pass by reference semantics. Everything in C is passed by value. Pointers are used to get pass by reference semantics.

迟到的我 2024-09-20 00:45:00

数组只是使用指针的一种奇特方式。当您将 buf 传递给函数时,您是按值传递指针,但是当您取消引用该指针时,您仍然引用它指向的字符串。

an array is just a fancy way to use a pointer. When you pass buf to the function, you're passing a pointer by value, but when you dereference the pointer, you're still referencing the string it points to.

壹場煙雨 2024-09-20 00:45:00

数组作为函数参数相当于指针,因此声明

void foo( char buf[] );

相同。

void foo( char* buf );

与数组参数衰减为指向其第一个元素的指针

Array as function parameter is equivalent to a pointer, so the declaration

void foo( char buf[] );

is the same as

void foo( char* buf );

The array argument is then decayed to the pointer to its first element.

人事已非 2024-09-20 00:45:00

数组的处理方式与其他类型不同;您不能在 C 中“按值”传递数组。

在线 C99 标准(草案 n1256),第 6.3.2.1 节,“左值、数组和函数指示符”,第 3 段:

除非它是 sizeof 运算符或一元 & 的操作数。运算符,或者是一个
用于初始化数组的字符串文字,类型为“array of type”的表达式是
转换为“指向类型的指针”类型的表达式,该表达式指向 的初始元素
数组对象并且不是左值。如果数组对象具有寄存器存储类别,则
行为未定义。

在调用中,

foo(buf);

数组表达式 buf 不是 sizeof& 的操作数,也不是用于初始化数组的字符串文字,因此它从类型“10 元素 char 数组”隐式转换(“衰减”)为“指向 char 的指针”,并且第一个元素的地址被传递给 foo。因此,您对 foo() 中的 buf 所做的任何操作都将反映在 main() 中的 buf 数组中。由于数组下标的定义方式,您可以在指针类型上使用下标运算符,因此它看起来就像您正在使用数组类型,但实际上并非如此。

在函数参数声明的上下文中,T a[]T a[N]T *a 同义,但这是在这种情况下才是正确的。

Arrays are treated differently than other types; you cannot pass an array "by value" in C.

Online C99 standard (draft n1256), section 6.3.2.1, "Lvalues, arrays, and function designators", paragraph 3:

Except when it is the operand of the sizeof operator or the unary & operator, or is a
string literal used to initialize an array, an expression that has type ‘‘array of type’’ is
converted to an expression with type ‘‘pointer to type’’ that points to the initial element of
the array object and is not an lvalue. If the array object has register storage class, the
behavior is undefined.

In the call

foo(buf);

the array expression buf is not the operand of sizeof or &, nor is it a string literal being used to initialize an array, so it is implicitly converted ("decays") from type "10-element array of char" to "pointer to char", and the address of the first element is passed to foo. Therefore, anything you do to buf in foo() will be reflected in the buf array in main(). Because of how array subscripting is defined, you can use a subscript operator on a pointer type so it looks like you're working with an array type, but you're not.

In the context of a function parameter declaration, T a[] and T a[N] are synonymous with T *a, but this is only case where that is true.

救赎№ 2024-09-20 00:45:00

*char buf[] 实际上意味着 char ** 所以你是通过指针/引用传递的。
这表明 buf 在 ma​​in() 和 foo() 函数中都是一个指针。

*char buf[] actually means char ** so you are passing by pointer/reference.
That gives you that buf is a pointer, both in the main() and foo() function.

梦在深巷 2024-09-20 00:45:00

因为您正在传递一个指向 buf 的指针(按值)。所以buf指向的内容被改变了。

Because you are passing a pointer to buf (by value). So the content being pointed by buf is changed.

对于指针,情况就不同了;你是按值传递的,但你传递的是指针的值,它与数组的值不同。

因此,指针的值不会改变,但您正在修改它指向的内容。

With pointers it's different; you are passing by value, but what you are passing is the value of the pointer, which is not the same as the value of the array.

So, the value of the pointer doesn't change, but you're modifying what it's pointing to.

一杯敬自由 2024-09-20 00:45:00

数组和指针(几乎)是同一件事。

int* foo = malloc(...)

foo[2]*(foo+2*sizeof(int))

轶事相同:你写的

int main(int argc, char *argv[])

它也是合法的(将编译和工作相同)到写

int main(int argc, char **argv)

,而且

int main(int argc, char argv[][])

它们实际上是相同的。它比这稍微复杂一些,因为数组知道它有多少个元素,而指针则不知道。但它们的用法是一样的。

arrays and pointers are (almost) the same thing.

int* foo = malloc(...)

foo[2] is the same as *(foo+2*sizeof(int))

anecdote: you wrote

int main(int argc, char *argv[])

it is also legal (will compile and work the same) to write

int main(int argc, char **argv)

and also

int main(int argc, char argv[][])

they are effectively the same. its slightly more complicated than that, because an array knows how many elements it has, and a pointer doesn't. but they are used the same.

江城子 2024-09-20 00:45:00

为了按值传递,函数需要知道参数的大小。在这种情况下,您只是传递一个指针。

in order to pass that by value, the function would need to know the size of the argument. In this case you are just passing a pointer.

蓝天 2024-09-20 00:45:00

您在这里通过引用传递。在此示例中,您可以通过在所需数组的索引处传递单个字符来解决该问题。

如果要保留原始数组的内容,可以将字符串复制到函数中的临时存储中。

编辑:如果将 char 数组包装在结构中并传递该结构,会发生什么?我相信这也可能有效,尽管我不知道可能会在编译器级别产生什么样的开销。

You are passing by reference here. In this example, you can solve the problem by passing a single char at the index of the array desired.

If you want to preserve the contents of the original array, you could copy the string to temporary storage in the function.

edit: What would happen if you wrapped your char array in a structure and passed the struct? I believe that might work too, although I don't know what kind of overhead that might create at the compiler level.

我为君王 2024-09-20 00:45:00

请注意一件事,

声明

void foo(char buf[])

说,这将使用 [ ] 符号。不是您将使用数组的哪个元素。

如果你想指出这一点,你想获得一些特定的值,那么你应该声明这个函数为

void foo(char buf[X]); //where X would be a constant.

当然这是不可能的,因为它是无用的(用于在数组的第n个元素进行操作的函数?)。您不必写下您想要获取数组的哪个元素的信息。您需要的一切都是简单的声明:

voi foo(char value);

so...

void foo(char buf[])

是一个声明,说明您要使用哪种表示法( [ ] - part ),并且它还包含指向某些数据的指针。

的数组名称

foo(buf);

此外...您会期望什么...您向函数 foo 发送了一个相当于 &buf[0] 。所以...这是一个指针。

please note one thing,

declaration

void foo(char buf[])

says, that will be using [ ] notation. Not which element of array you will use.

if you would like to point that, you want to get some specific value, then you should declare this function as

void foo(char buf[X]); //where X would be a constant.

Of course it is not possible, because it would be useless (function for operating at n-th element of array?). You don't have to write down information which element of array you want to get. Everything what you need is simple declaration:

voi foo(char value);

so...

void foo(char buf[])

is a declaration which says which notation you want to use ( [ ] - part ), and it also contains pointer to some data.

Moreover... what would you expect... you sent to function foo a name of array

foo(buf);

which is equivalent to &buf[0]. So... this is a pointer.

旧时光的容颜 2024-09-20 00:45:00

C 中的数组不是按值传递的。它们甚至不是合法的函数参数。相反,编译器会发现您正在尝试传递数组并将其降级为指针。它默默地这样做,因为它是邪恶的。它还喜欢踢小狗。

在函数参数中使用数组是一种很好的方式,可以向 API 用户发出信号,表明该内容应该是分割成 n 字节大小的块的内存块,但不要指望编译器会关心您是否拼写 char *foo< /code> 函数参数中的 char foo[]char foo[12]。他们不会。

Arrays in C are not passed by value. They are not even legitimate function parameters. Instead, the compiler sees that you're trying to pass an array and demotes it to pointer. It does this silently because it's evil. It also likes to kick puppies.

Using arrays in function parameters is a nice way to signal to your API users that this thing should be a block of memory segmented into n-byte sized chunks, but don't expect compilers to care if you spell char *foo char foo[] or char foo[12] in function parameters. They won't.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文