C语言 在一个语句中具有两次静态字段的调用函数



为了把问题说清楚,我写了一些测试代码:

#include <stdio.h>
#include <string.h>
char *foo(int a) {
    printf("%dn", a);
    static char string[2];
    string[0] = a > 0? '1' : '0';
    string[1] = '';
    return string;
}
int main(void) {
    printf("%st%sn", foo(1), foo(0));
    return 0;
}

运行代码会给出如下输出:

0
1
1       1

我这里有两个问题:1. 为什么 0 印在 1 之前?在 Main 的 printf 函数中,第二个 foo 在第一个之前执行?这是一种定义的行为还是偶然。2. 为什么最终输出是 1、1?预期结果应为 1, 0。

参数计算的顺序取决于实现 - 你的编译器恰好以这种方式实现它

编辑:根据您的第二个问题,您正在使用静态缓冲区。这意味着它由两个 foo() 调用共享 - 即两个 foo() 调用返回相同的指针。

给定您的评估顺序,首先写入 0,然后写入 1。当两个 foo() 调用都完成并且需要打印缓冲区时,那里都有一个 1 - 在两种情况下(缓冲区静态 == 共享)。

如果要解决此问题,可以让调用方在缓冲区中传递,并且函数写入用户提供的内存,以便每次调用都是唯一的。

在你的例子中,是首先调用 foo(1) 还是 foo(0) 在 C 中没有定义。在您的例子中,调用了 foo(0),将 foo 的静态字符串设置为"0"并返回字符串的地址。然后调用 foo(1),将字符串设置为 "1"。然后打印字符串两次。无论如何,它永远是一样的。

计算参数的顺序是实现定义的:

拨打printf后:

printf("%st%sn", foo(1), foo(0));

它首先用0调用foo(),然后用1。每次调用时,都会返回 String 的地址并将其存储在变量中。由于String static地址不会更改。呼叫结束后,printf打印String内容,这是String发生的最后一次更改(调用foo(1)之后)。相同的地址表示相同的值,表示输出为:

0
1
1       1

最新更新