以下是否在ANSI C中有效?
#include <stdio.h>
/* This returns "Hans" if arg != 0, "Gretel" if arg == 0 */
char* foo(int arg)
{
return arg ? "Hans" : "Gretel";
}
int main()
{
char* p_ch;
p_ch = foo(1);
printf("%s\n", p_ch);
p_ch = foo(0);
printf("%s\n", p_ch);
return 0;
}
代码在GCC / Linux下编译并运行良好。
MinGW / Windows说:
invalid conversion from `const char*' to `char*'
MS Visual C / C ++ 2008可以很好地使用代码。
char*
变量分配给文本字符串,而不是在初始化时吗?static
位置类。这是否意味着它们在定义它们的函数之外是不可见的?const
类型到非常规对应的转换何时无效?答案 0 :(得分:5)
是的,这是有效的标准C.但是,它仅有效,因为字符串文字具有类型char[]
以便向后兼容;为了安全起见,你应该真正从foo
和const char*
获得返回值。写入foo
返回的任一字符串会引发未定义的行为。
如果您的编译器抱怨这一点,那么您可能不小心使用了C ++编译器。在C ++中,字符串文字的类型为const char []
。 (如果将char*
更改为const char*
,您的程序也会神奇地成为有效的C ++程序。)
我可以将
char*
变量分配给文本字符串,而不是在初始化时吗?
你的意思是
char *p;
// do some other stuff
p = "literal";
?是的,这是可能的。
我读过字符串文字有静态分配类。这是否意味着它们在定义它们的函数之外是不可见的?
您会混淆静态分配和static
变量。您当然可以在另一个翻译单元中使用foo
的结果。
从const类型到非const对应的转换何时无效?
正式自1989年以来,当const
被引入C时。你必须明确地抛弃const
。
答案 1 :(得分:1)
您从MinGW / Windows编译器获得的错误消息强烈建议您将此代码编译为C ++。在C语言中,字符串文字具有char[N]
类型(而不是C ++中的const char[N]
)。在C语言中,您不应该收到此错误消息。尽管如此,即使在C字符串文字中也是不可修改的,这意味着在指向字符串文字时坚持const char *
指针是一个好主意。
你的问题1有点奇怪。字符串文字是无名对象,这意味着初始化是直接使指针指向字符串文字的唯一方法。别无他法。稍后您可以将非const指针复制到其他非const指针,这是正常的。请记住,不允许通过这些指针将任何内容写入字符串文字:字符串文字是不可修改的。
你的问题2也没什么意义。 “可见性”是名称的属性。字符串文字是无名对象。它们在任何地方都看不到。它们不可见,因为它们没有名字。由于它们没有名称,因此“抓取”字符串文字并保持它的唯一方法是在指针初始化期间附加指针(如示例中所示)。可见性完全与它无关。字符串文字确实具有静态存储持续时间,这意味着它们“永远存在”:只要程序运行它们就存在。在您的示例中,字符串文字"Hans"
和"Gretel"
即使在foo
退出后也会继续存在,这意味着foo
返回的指针仍然有效。
你的问题3的答案是:从const指针到非const对应物的隐式转换从未在C语言中存在,即它始终无效。您必须使用显式强制转换才能执行此类转换。