Zeb*_*ish 4 c++ pointers string-literals
我想知道是否可以将指向 char 的指针直接分配给字符串文字,而无需先将字符串文字分配给左值指针。通常,如果参数采用指向某个对象的指针,则可以使用 & 传递对象的地址,并且字符串文字似乎是(或至少衰减为) char 指针,因为您可以将它们分配给 char 指针。这就是为什么我期望以下其中一项能够发挥作用:
const char ** ppchar = &"StringLiteral"; // This doesn't compile
const char ** ppchar = (const char **)&"StringLiteral"; // This compiles, but...
std::cout << *ppchar; // Throws an exception
Run Code Online (Sandbox Code Playgroud)
我预计至少其中第二个可以工作,因为在我看来“StringLiteral”至少会衰减为指针,因此:
const char** ppchar = (const char**) &"StringLiteral";
Run Code Online (Sandbox Code Playgroud)
第一个指针将指向字符串文字的地址。如果首先将字符串文字分配给左值指针,则第一个指针将指向第二个指针,该指针本质上保存着其地址。对我来说似乎是一样的。
编辑:另外,我似乎可以这样做:
const char * _pptr = (const char*)&"StringLiteral";
std::cout << _pptr; // Prints "Hello"
Run Code Online (Sandbox Code Playgroud)
因此,似乎没有禁止直接分配给字符串文字的规则。
编辑:正如对许多人来说显而易见的那样,我的间接级别是错误的。来自莫斯科的弗拉德在他的回答中解释了这一点。在:
const char ** pptr = (const char**)&"StringLiteral";
Run Code Online (Sandbox Code Playgroud)
编译器期望 pptr 指向存储字符地址的内容,而我已将其分配给“StringLiteral”本身的地址,这意味着当我 cout 时,它会取消引用第一个指针以查找哪个地址找到该字符。问题是它直接指向“StringLiteral”的地址,这意味着它使用“StringLiteral”的第一个字母的值作为要查找字符的地址,基本上它会使用“S”作为地址要去。讨厌这么厚。
这个表情
&"StringLiteral"
Run Code Online (Sandbox Code Playgroud)
const char( * )[14]
在 C++ 和C 中具有类型char ( * )[14]
,因为字符串文字分别具有类型const char[14]
或char[14]
。
因此,您可能不会将这样的指针分配给该类型的对象const char **
,或者char **
因为指针不兼容。
如果您尝试使用此声明中的强制转换
const char** ppchar = (const char**) &"StringLiteral";
Run Code Online (Sandbox Code Playgroud)
然而,像这样取消引用此指针*ppchar
是没有意义的,因为char *
您将获得与字符串文字的第一个字符的值相对应的值,而不是预期的类型对象,而不是地址值。
例如,您可以首先按以下方式将字符串文字转换为类型const char *
(或C 语言)char *
StringLiteral + 0
Run Code Online (Sandbox Code Playgroud)
因为在这样的表达式中,字符串文字被转换为指向其第一个字符的指针。但是,您不能将一元运算符应用于&
此表达式,例如
&( StringLiteral + 0 )
Run Code Online (Sandbox Code Playgroud)
获取该类型的对象,const char **
因为您可能无法将运算符应用于rvalue
.
所以你可以做的是以下
const char *pchar = "StringLiteral";
const char **ppchar = &pchar;
Run Code Online (Sandbox Code Playgroud)