C++中const char*和const char[]的区别

6

我看到一个关于以下两个问题的区别的提问:

const char*

并且

const char[]

曾经有一段时间,我认为数组只是指针的语法糖。但现在有些事情让我感到困扰,我有一段类似以下代码的片段:

namespace SomeNamespace {
    const char* str = { 'b', 'l', 'a', 'h' };
}

我遇到了一个错误:scaler对象“str”在初始化程序中需要一个元素。 因此,我尝试了如下方法:
namespace SomeNamespace {
    const char str[] = { 'b', 'l', 'a', 'h' };
}

一开始它是有效的,我认为这可能与当它是const char*时会应用额外操作有关,而GCC从来不喜欢在函数外执行操作(这也是不好的实践),但错误似乎并没有表明如此。然而,在:

void Func() {
    const char* str = { 'b', 'l', 'a', 'h' };
}

正如预期的那样,它编译得很好。有人知道为什么吗?

x86_64/i686-nacl-gcc 4(.1.4?) pepper 19工具链(基本上是GCC)。


一个是数组,一个是指针。 - chris
如果你认为它们是一样的,再去想想。 - WhozCraig
@WhozCraig 就像我所说的那样,我读到了一个解释它们不同的问题(之前我认为数组是指针的语法糖,基本上是一组重载运算符)。 - The Floating Brain
2
最后一个代码片段在我的clang (Apple LLVM 4.2, clang-425.0.28)上也*无法编译,所以我不知道你的代码出了什么问题。(错误:“标量初始化器中有多余元素”),但我并没有期望它能编译成功。 - WhozCraig
1
我向您推荐关于此问题的C FAQ:http://c-faq.com/aryptr/aryptrequiv.html - kfsone
显示剩余2条评论
1个回答

7

首先,无论是在命名空间范围还是在函数中尝试使用复合初始化都没有区别:两者都不应该工作!当您编写

char const* str = ...;

您得到了一个指向一系列char的指针,它可以用字符串字面值进行初始化。无论如何,这些字符与指针不在同一位置。而另一方面,当您写入时,请注意:
char const str[] = ...;

您需要定义一个字符数组,数组的大小由右侧元素个数决定,例如在您的例子中,大小将变为4:{'b', 'l', 'a', 'h'}。如果您使用了"blah",大小当然是5。数组的元素被复制到定义str的位置。
请注意,char const x[]在某些情况下可以等同于char const* x:当您声明函数参数时,char const x[]实际上与char const*相同。

1
当你写“is the same”时,你不应该说“可以被隐式转换”吗? - IInspectable
关于typedef,这是基于每个实例还是在类型声明时进行的? - The Floating Brain
2
@IInspectable:不是的。声明为 char const x[]char const* x 的函数参数是相同的。但是,当作为 typedef 使用时,它们实际上是不同的,但我还没有完全弄清楚。这里有一个测试:void f(char const x[], char const* y) { std::cout << std::is_same<decltype(x), decltype(y)>::value << '\n'; } - Dietmar Kühl
@IInspectable:即使你在括号中提到了一个大小,类型仍然是char const*:也就是说,void f(char const x[10])等同于void f(char const* x)!你可以使用任何其他正值代替10 - Dietmar Kühl
2
@DietmarKühl 这是一个修改过的示例,演示了我认为你所指的关于typedef差异(而且奇怪的是,相同)的问题。这真是让人费解。我想我可能终于找到了我的第一个SO问题。谢谢。 - WhozCraig
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接