ANSI C:指向字符串文字的指针

时间:2011-11-23 15:17:26

标签: c string-literals

  

可能重复:
  Are string literals const?

以下是否在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可以很好地使用代码。

  1. 我可以将char*变量分配给文本字符串,而不是在初始化时吗?
  2. 我读过字符串文字有static位置类。这是否意味着它们在定义它们的函数之外是不可见的?
  3. const类型到非常规对应的转换何时无效?

2 个答案:

答案 0 :(得分:5)

是的,这是有效的标准C.但是,它仅有效,因为字符串文字具有类型char[]以便向后兼容;为了安全起见,你应该真正从fooconst 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语言中存在,即它始终无效。您必须使用显式强制转换才能执行此类转换。