为了使问题清楚,我写了一些测试代码:
#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。
答案 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
的地址并将其存储在变量中。由于String
为static
,因此地址不会更改。通话结束后,printf
会打印String
内容,这是String
(调用foo(1)
后)的最后一次更改。相同的地址表示相同的值,表示输出为:
0
1
1 1