在函数之间分配多个变量

huangapple go评论82阅读模式
英文:

Assigning Multiple Variables Between Functions

问题

以下是代码部分的翻译,没有其他内容:

#include <stdio.h>;

int Function(int a, int b, int c) 
{
    int var1 = 1;
    int var2 = 2;
    int var3 = 3;
    
    return var1, var2, var3;
}

int main()
{
    int x, y, z;
    
    x, y, z = Function(x, y, z);

    printf("%d %d %d", x, y, z);
    
    return 0;
}

这段代码似乎只打印出"0 0 3"。

我可能遗漏了什么?我确信问题出在Function函数的return语句上。仅出于好奇,我将return语句分成了三行,分别返回var1... return var3,结果仍然相同,但这次打印出了"1 0 0"。所以我知道这些变量是存在的,只是不确定如何正确地将它们分配。

基本上,我只是想让x、y和z打印出"1 2 3"。

英文:

So I'm working on this program and seem to be having trouble assigning variables from 1 function to another, this is the basis of what I am thinking but it seems to only take the last returned value when I try.

#include &lt;stdio.h&gt;

int Function(int a, int b, int c) 
{
    int var1 = 1;
    int var2 = 2;
    int var3 = 3;
    
    return var1, var2, var3;
}

int main()
{
    int x, y, z;
    
    x, y, z = Function(x, y, z);

    printf(&quot;%d %d %d&quot;, x, y, z);
    
    return 0;
}

This seems to only print out "0 0 3"

What could I be missing? I'm sure its the return statement in the Function. Just out of curiosity I separated the return function to return var1... return var 3 in separate lines and the result is the same but this time prints "1 0 0". So I know the variables are there, I'm just not sure on how to assign them properly.

Basically just trying to get x, y and z to print out "1 2 3"

答案1

得分: 4

你似乎误解了在C语言中,逗号运算符的工作原理。在C语言中,逗号运算符的两个操作数都会被求值,但操作的结果是右操作数的值。这意味着以下情况:

这行代码

return var1, var2, var3;

等价于:

return var3;

这行代码

x, y, z = Function(x, y, z);

等价于:

z = Function(x, y, z);

请注意,在这行代码

x, y, z = Function(x, y, z);

左侧的 x, y, z 使用了逗号运算符,如上所述,但右侧的 x, y, z 没有使用逗号运算符。在这种情况下,,具有完全不同的含义。它充当了三个函数参数之间的分隔符。

如果你希望结果是 1 2 3,那么我建议你将变量通过指针传递给函数 Function,就像这样:

#include <stdio.h>

void Function(int *a, int *b, int *c) 
{
    *a = 1;
    *b = 2;
    *c = 3;
}

int main(void)
{
    int x, y, z;
    
    Function(&x, &y, &z);

    printf("%d %d %d", x, y, z);
    
    return 0;
}

或者,如果你不想使用指针,你还可以使用一个 struct 结构:

#include <stdio.h>

struct triplet
{
    int a;
    int b;
    int c;
};

struct triplet Function( void )
{
    return (struct triplet){1,2,3};
}

int main( void )
{
    struct triplet t;
    
    t = Function();

    printf("%d %d %d", t.a, t.b, t.c);
    
    return 0;
}

另一个可能性是使用数组:

#include <stdio.h>

void Function( int arr[3] ) 
{
    arr[0] = 1;
    arr[1] = 2;
    arr[2] = 3;
}

int main(void)
{
    int numbers[3];
    
    Function( numbers );

    printf("%d %d %d", numbers[0], numbers[1], numbers[2]);
    
    return 0;
}
英文:

You seem to misunderstand how the , comma operator works in C. In C, both operands of the comma operator are evaluated, but the result of the operation is the value of the right operand. This means the following:

The line

return var1, var2, var3;

is equivalent to:

return var3;

The line

x, y, z = Function(x, y, z);

is equivalent to:

z = Function(x, y, z);

Note that in the line

x, y, z = Function(x, y, z);

the left x, y, z uses the comma operator, as described above, but the right x, y, z does not use the comma operator. The , has a completely different meaning in this case. It serves as a delimiter between the three function arguments.

If you want the result to be 1 2 3, then I suggest that you pass the variables by pointer to the function Function, like this:

#include &lt;stdio.h&gt;

void Function(int *a, int *b, int *c) 
{
    *a = 1;
    *b = 2;
    *c = 3;
}

int main(void)
{
    int x, y, z;
    
    Function(&amp;x, &amp;y, &amp;z);

    printf(&quot;%d %d %d&quot;, x, y, z);
    
    return 0;
}

Alternatively, if you don't want to use pointers, you can also use a struct:

#include &lt;stdio.h&gt;

struct triplet
{
    int a;
    int b;
    int c;
};

struct triplet Function( void )
{
    return (struct triplet){1,2,3};
}

int main( void )
{
    struct triplet t;
    
    t = Function();

    printf(&quot;%d %d %d&quot;, t.a, t.b, t.c);
    
    return 0;
}

Another possibility is to use an array:

#include &lt;stdio.h&gt;

void Function( int arr[3] ) 
{
    arr[0] = 1;
    arr[1] = 2;
    arr[2] = 3;
}

int main(void)
{
    int numbers[3];
    
    Function( numbers );

    printf(&quot;%d %d %d&quot;, numbers[0], numbers[1], numbers[2]);
    
    return 0;
}

答案2

得分: 1

编译代码时启用警告会产生以下输出:

chqrlie> clang -Wall -Werror 230312-triplet.c
230312-triplet.c:9:12: error: left operand of comma operator has no effect
      [-Werror,-Wunused-value]
    return var1, var2, var3;
           ^~~~
230312-triplet.c:9:18: error: left operand of comma operator has no effect
      [-Werror,-Wunused-value]
    return var1, var2, var3;
                 ^~~~
230312-triplet.c:16:5: error: left operand of comma operator has no effect
      [-Werror,-unused-value]
    x, y, z = Function(x, y, z);
    ^
230312-triplet.c:16:8: error: left operand of comma operator has no effect
      [-Werror,-unused-value]
    x, y, z = Function(x, y, z);
       ^
230312-triplet.c:16:24: error: variable 'x' is uninitialized when used here
      [-Werror,-Wuninitialized]
    x, y, z = Function(x, y, z);
                       ^
230312-triplet.c:14:10: note: initialize the variable 'x' to silence this warning
    int x, y, z;
         ^
          = 0
230312-triplet.c:16:27: error: variable 'y' is uninitialized when used here
      [-Werror,-Wuninitialized]
    x, y, z = Function(x, y, z);
                          ^
230312-triplet.c:14:13: note: initialize the variable 'y' to silence this warning
    int x, y, z;
            ^
             = 0
230312-triplet.c:16:30: error: variable 'z' is uninitialized when used here
      [-Werror,-Wuninitialized]
    x, y, z = Function(x, y, z);
                             ^
230312-triplet.c:14:16: note: initialize the variable 'z' to silence this warning
    int x, y, z;
               ^
                = 0
7 errors generated.

很可惜,默认情况下未启用警告!

这意味着return var1, var2, var3;不会返回3个值,而是计算逗号运算符表达式var1, var2, var3,它计算为其最后的操作数var3,并将这个值3作为函数的返回值。

类似地,x, y, z = Function(x, y, z);不会实现3个值的并行存储,而是再次计算逗号表达式,根据运算符优先级规则解析为:

x, y, (z = Function(x, y, z));

xy会计算它们的值,但这些值会被忽略(如果它们被声明为volatile,则必须读取这些值),然后z = Function(x, y, z)最终将3存储到z。还要注意,xyz被传递给Function,但它们未初始化,因此仅传递它们的值会导致未定义行为。

正如@AndreasWenzel所解释的,函数可以通过返回结构或通过指针更新调用范围内的值来返回多个值。

对于分开的变量,后者更符合惯例:

#include <stdio.h>;

void initialize(int *a, int *b, int *c) {
    int var1 = 1;
    int var2 = 2;
    int var3 = 3;
    
    *a = var1;
    *b = var2;
    *c = var3;
}

int main() {
    int x, y, z;
    
    initialize(&x, &y, &z);

    printf("%d %d %d\n", x, y, z);
    
    return 0;
}

输出:

1 2 3

将变量分组在一个结构中可能对描述同一对象的变量更一致:

#include <stdio.h>;

typedef struct object {
   int x, y, z;
} object;

void object_initialize(object *obj) {
    obj->x = 1;
    obj->y = 2;
    obj->z = 3;
}

int main() {
    object o;
    
    object_initialize(&o);

    printf("%d %d %d\n", o.x, o.y, o.z);
    
    return 0;
}

输出:

1 2 3
英文:

Compiling your code with warnings enabled produces this output:

chqrlie&gt; clang -Wall -Werror 230312-triplet.c
230312-triplet.c:9:12: error: left operand of comma operator has no effect
      [-Werror,-Wunused-value]
    return var1, var2, var3;
           ^~~~
230312-triplet.c:9:18: error: left operand of comma operator has no effect
      [-Werror,-Wunused-value]
    return var1, var2, var3;
                 ^~~~
230312-triplet.c:16:5: error: left operand of comma operator has no effect
      [-Werror,-Wunused-value]
    x, y, z = Function(x, y, z);
    ^
230312-triplet.c:16:8: error: left operand of comma operator has no effect
      [-Werror,-Wunused-value]
    x, y, z = Function(x, y, z);
       ^
230312-triplet.c:16:24: error: variable &#39;x&#39; is uninitialized when used here
      [-Werror,-Wuninitialized]
    x, y, z = Function(x, y, z);
                       ^
230312-triplet.c:14:10: note: initialize the variable &#39;x&#39; to silence this warning
    int x, y, z;
         ^
          = 0
230312-triplet.c:16:27: error: variable &#39;y&#39; is uninitialized when used here
      [-Werror,-Wuninitialized]
    x, y, z = Function(x, y, z);
                          ^
230312-triplet.c:14:13: note: initialize the variable &#39;y&#39; to silence this warning
    int x, y, z;
            ^
             = 0
230312-triplet.c:16:30: error: variable &#39;z&#39; is uninitialized when used here
      [-Werror,-Wuninitialized]
    x, y, z = Function(x, y, z);
                             ^
230312-triplet.c:14:16: note: initialize the variable &#39;z&#39; to silence this warning
    int x, y, z;
               ^
                = 0
7 errors generated.

It is a pity warnings are not enabled by default!

What this means is return var1, var2, var3; does not return 3 values, but evaluates the comma operator expression var1, var2, var3, which evaluates to its last operand var3, and returns this value 3 as the function return value.

Similarly, x, y, z = Function(x, y, z); does not implement parallel stores of the 3 values, but again evaluates a comma expression which according to the operator precedence rules is parsed as:

x, y, (z = Function(x, y, z));

x and y evaluate to their values which are ignored (but would have to be read were they qualified as volatile, and z = Function(x, y, z) finally stores 3 to z. Note also that x, y and z are passed to Function but are not initialized so merely passing their values has undefined behavior.

As explained by @AndreasWenzel, a function can return multiple values by returning a structure, or updating values in the calling scope via pointers.

The latter is more idiomatic for separate variables:

#include &lt;stdio.h&gt;

void intialize(int *a, int *b, int *c) {
    int var1 = 1;
    int var2 = 2;
    int var3 = 3;
    
    *a = var1;
    *b = var2;
    *c = var3;
}

int main() {
    int x, y, z;
    
    initialize(&amp;x, &amp;y, &amp;z);

    printf(&quot;%d %d %d\n&quot;, x, y, z);
    
    return 0;
}

Output:

1 2 3

Grouping the variables in a structure may be more consistent for variables describing the same object:

#include &lt;stdio.h&gt;

typedef struct object {
   int x, y, y;
} object;

void object_initialize(object *obj) {
    obj-&gt;x = 1;
    obj-&gt;y = 2;
    obj-&gt;z = 3;
}

int main() {
    object o;
    
    object_initialize(&amp;o);

    printf(&quot;%d %d %d\n&quot;, o.x, o.y, o.z);
    
    return 0;
}

Output:

1 2 3

huangapple
  • 本文由 发表于 2023年3月12日 09:27:04
  • 转载请务必保留本文链接:https://go.coder-hub.com/75710584.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定