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

时间:2014-02-08 22:25:22

标签: c function static

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

#include <stdio.h>
#include <string.h>

char *foo(int a) {
    printf("%d\n", a);
    static char string[2];
    string[0] = a > 0? '1' : '0';
    string[1] = '\0';
    return string;
}

int main(void) {
    printf("%s\t%s\n", foo(1), foo(0));
    return 0;
}

运行代码会产生如下输出:

0
1
1       1

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

3 个答案:

答案 0 :(得分:2)

参数评估的顺序依赖于实现 - 您的编译器恰好以这种方式实现

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

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

如果你想解决这个问题,可以让调用者在缓冲区中传递,你的函数会写入用户提供的内存,这样每次调用都是唯一的。

答案 1 :(得分:0)

在您的示例中,首先调用foo(1)或foo(0)是否未在C中定义。在您的情况下调用foo(0),将foo的静态字符串设置为“0”并返回地址的字符串。然后调用foo(1),将字符串设置为“1”。然后你打印两次字符串。无论如何,它总是一样的。

答案 2 :(得分:0)

评估参数的顺序是实现定义:

致电printf后:

printf("%s\t%s\n", foo(1), foo(0));

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

0
1
1       1