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

发布于 2024-12-17 13:31:53 字数 848 浏览 0 评论 0原文

可能的重复:
字符串文字是常量吗?

以下内容在 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. 我读到字符串文字有静态分配类。这是否意味着它们在定义它们的函数之外是不可见的?
  3. 从什么时候起,从 const 类型到非 const 对应类型的转换无效?

Possible Duplicate:
Are string literals const?

Is the following valid in 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;
}

The code compiles and runs well under GCC/Linux.

MinGW/Windows says:

invalid conversion from `const char*' to `char*'

MS Visual C/C++ 2008 is fine with the code.

  1. Can I assign a char* variable to a literal string elsewhere than at the point of its initialization?
  2. I've read that string literals have static alocation class. Does it mean that they are invisible outside of the function which they were defined in?
  3. Since when are conversions from const types to their non-const counterparts invalid?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦开始←不甜 2024-12-24 13:31:53

是的,这是有效的标准 C。但是,它之所以有效,只是因为字符串文字具有 char[] 类型以实现向后兼容性;为了安全起见,你确实应该将 foo 的返回值设置为 const char* 。写入 foo 返回的任何一个字符串都会引发未定义的行为。

如果您的编译器抱怨这一点,那么您可能不小心使用了 C++ 编译器。在 C++ 中,字符串文字的类型为 const char []。 (如果将 char* 更改为 const char*,您的程序也会神奇地变成有效的 C++ 程序。)

我可以在初始化时以外的其他地方将 char* 变量分配给文字字符串吗?

你的意思是

char *p;
// do some other stuff
p = "literal";

?是的,这是可能的。

我读到字符串文字具有静态分配类。这是否意味着它们在定义它们的函数之外是不可见的?

您混淆了静态分配和静态变量。您当然可以在另一个翻译单元中使用 foo 的结果。

从 const 类型到非 const 类型的转换从什么时候开始无效?

从 1989 年开始,const 被正式引入 C。您必须显式地放弃 const

Yes, this is valid standard C. However, it's only valid because string literals have type char[] for backwards compatibility; you should really make the return value from foo a const char* for safety. Writing to either of the strings returned by foo provokes undefined behavior.

If your compiler complains about this, then you may have accidentally used a C++ compiler. In C++, strings literals have type const char []. (If you change char* to const char*, your program magically becomes a valid C++ program as well.)

Can I assign a char* variable to a literal string elsewhere than at the point of its initialization?

You mean

char *p;
// do some other stuff
p = "literal";

? Yes, that's possible.

I've read that string literals have static allocation class. Does it mean that they are invisible outside of the function which they were defined in?

You're confusing static allocation and static variables. You can certainly use the result from foo in another translation unit.

Since when are conversions from const types to their non-const counterparts invalid?

Officially since 1989, when const was introduced to C. You have to explicitly cast the const off.

年华零落成诗 2024-12-24 13:31:53

您从 MinGW/Windows 编译器收到的错误消息强烈表明您正在将此代码编译为 C++。在 C 语言中,字符串文字具有 char[N] 类型(与 C++ 中的 const char[N] 不同)。在 C 语言中,您不应该收到此错误消息。然而,即使在 C 中,字符串文字也是不可修改的,这意味着在指向字符串文字时坚持使用 const char * 指针是一个好主意。

你的第一个问题有点奇怪。字符串文字是无名对象,这意味着初始化是直接使指针指向字符串文字的唯一方法。没有其他办法了。稍后您可以将您的非常量指针复制到其他非常量指针,这是可以的。请记住,您不允许通过这些指针将任何内容写入字符串文字:字符串文字是不可修改的。

你的问题2也没有什么意义。 “可见性”是名称的一个属性。字符串文字是无名对象。它们在任何地方都看不到。他们不可见,因为他们没有名字。由于它们没有名称,因此“抓取”字符串文字并保留它的唯一方法是在指针初始化期间将指针附加到它(如您的示例中所示)。可见性与此完全无关。字符串文字确实具有静态存储持续时间,这意味着它们“永远存在”:只要程序运行,它们就存在。在您的示例中,即使在 foo 退出后,字符串文字 "Hans""Gretel" 仍继续存在,这意味着 返回的指针code>foo 仍然有效。

你的问题3的答案是:从const指针到其非const对应物的隐式转换在C语言中从未存在过,即它始终是无效的。您必须使用显式强制转换才能执行此类转换。

The error message you are getting from MinGW/Windows compiler strongly suggests that you are compiling this code as C++. In C language string literals have char[N] type (as opposed to const char[N] in C++). In C language you should not get this error message. Nevertheless, even in C string literals are non-modifiable, meaning that it is a good idea to stick to const char * pointers when pointing to string literals.

Your question number 1 is a bit weird. String literals are nameless objects, which means that initialization is the only way to directly make a pointer to point to a string literal. There's no other way. Later you can copy your non-const pointer to other non-const pointers, which is OK. Just remember that you are not allowed to write anything into a string literal through those pointers: string literals are non-modifiable.

Your question 2 also makes little sense. "Visibility" is a property of a name. String literals are nameless objects. They are not visible anywhere. They can't be visible, since they have no names. Since they have no names, the only way to "grab" a string literal and hold on to it is to attach a pointer to it during pointer initialization (as in your examples). Visibility has nothing to do with it at all. String literals do indeed have static storage duration, which means that they "live forever": they exist as long as the program runs. In your example, string literals "Hans" and "Gretel" continue to live even after the foo exits, meaning that the pointer returned by foo remains valid.

The answer to your question 3 is: implicit conversions from const pointers to their non-const counterparts never existed in C language, i.e. it has always been invalid. You have to use an explicit cast in order to perform such a conversion.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文