我预计输出是“星期一星期一”,但实际输出是“星期一”,为什么会这样?
#include <stdio.h>
#include <string.h>
static const char *msg[] = {"Sunday", "Monday",
"Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
char *get_a_day(int idx)
{
static char buf[20];
strcpy(buf, msg[idx]);
return buf;
}
int main(void)
{
printf("%s %s\n", get_a_day(0), get_a_day(1));
return 0;
}
答案 0 :(得分:3)
如果您想要解释,其他答案可以解释清楚。
如果您只是想让您的程序正常工作,那么应该解决它:
const char *get_a_day(int idx)
{
return msg[idx];
}
答案 1 :(得分:3)
您将buf[]
声明为static
,这意味着所有实例都会共享一个内存位置。
get_a_day()
似乎隐式返回buf[]
,因此对get_a_day()
的两次调用都返回指向同一缓冲区的指针。
第一个调用将buf[]
设置为"Sunday"
并返回指向buf
的内存位置的指针。然后第二个调用将buf[]
设置为"Monday"
,覆盖"Sunday"
,并返回指向buf
的内存位置的指针 - 与第一次调用相同的内存位置。然后,指向buf
的指针作为第2和第3个参数传递给printf
。由于buf
包含"Monday"
(之前已覆盖"Sunday"
),printf()
会打印Monday Monday
。
为什么buf
需要是静态的?如果您删除此关键字并正确分配内存,那么事情应该如您所愿。另外,你需要buf
吗?如果您刚刚返回msg[i]
,您将获得预期的结果。
另一件事:你不应该隐式返回这样的值。可维护性大幅下降,代码的意图不明确。您应该明确return
您要返回的值。
答案 2 :(得分:2)
您应该启用所有警告(例如使用gcc -Wall -g
进行编译)并学习使用调试器(例如gdb
)。
请注意,您的get_a_day
函数被声明为返回char*
但不返回任何内容(并且您的编译器会向您发出警告)。所以你有一个undefined behavior,一切都可能发生(并且仍然符合C规范)。
即使您在return buf;
函数末尾添加get_a_day
,它也会返回相同的指针,因为buf
为static
(如果像printf
那样在msg[idx]
中调用两次)。
您应该考虑返回堆分配的字符串,并且具有调用者应该释放它的约定。但在您的特定情况下,返回{{1}}就足够了。
答案 3 :(得分:2)
因为你正在使用strcpy。 strcpy替换缓冲区中的整个字符串。因此,第二个调用将覆盖第一个调用(在某些平台上,第一个调用将覆盖第二个调用,因为它们以相反的顺序进行计算)。更不用说缺乏回报了。请尝试使用此代码:
char* get_a_day( int idx, char* buf )
{
strcpy(buf, msg[idx]);
return buf;
}
int main(void)
{
char buf0[20];
char buf1[20];
printf("%s %s\n", get_a_day(0, buf0), get_a_day(1, buf1));
return 0;
}