ANSI C:指向字符串文字的指针
可能的重复:
字符串文字是常量吗?
以下内容在 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*
变量分配给文字字符串吗? - 我读到字符串文字有静态分配类。这是否意味着它们在定义它们的函数之外是不可见的?
- 从什么时候起,从
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.
- Can I assign a
char*
variable to a literal string elsewhere than at the point of its initialization? - 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? - Since when are conversions from
const
types to their non-const counterparts invalid?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,这是有效的标准 C。但是,它之所以有效,只是因为字符串文字具有
char[]
类型以实现向后兼容性;为了安全起见,你确实应该将 foo 的返回值设置为 const char* 。写入foo
返回的任何一个字符串都会引发未定义的行为。如果您的编译器抱怨这一点,那么您可能不小心使用了 C++ 编译器。在 C++ 中,字符串文字的类型为
const char []
。 (如果将char*
更改为const char*
,您的程序也会神奇地变成有效的 C++ 程序。)你的意思是
?是的,这是可能的。
您混淆了静态分配和静态变量。您当然可以在另一个翻译单元中使用
foo
的结果。从 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 fromfoo
aconst char*
for safety. Writing to either of the strings returned byfoo
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 changechar*
toconst char*
, your program magically becomes a valid C++ program as well.)You mean
? Yes, that's possible.
You're confusing static allocation and
static
variables. You can certainly use the result fromfoo
in another translation unit.Officially since 1989, when
const
was introduced to C. You have to explicitly cast theconst
off.您从 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 toconst 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 toconst 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 thefoo
exits, meaning that the pointer returned byfoo
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.