我可以直接将指针指向char指针吗?

时间:2017-10-18 21:12:39

标签: 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

我预计至少第二个这个可以工作,因为“StringLiteral”在我看来至少会衰减到一个指针,所以在:

const char** ppchar = (const char**) &"StringLiteral";

第一个指针指向字符串文字的地址。如果首先将字符串文字分配给左值指针,则第一个指针将指向第二个指针,该指针基本上保持其地址。对我来说似乎也一样。

编辑:此外,我似乎可以这样做:

const char * _pptr = (const char*)&"StringLiteral";
std::cout << _pptr; // Prints "Hello"

因此,似乎不反对直接指定字符串文字。

编辑:对许多人来说,这是显而易见的,我的间接水平错误。这是由莫斯科弗拉德在他的回答中解释的。在:

const char ** pptr = (const char**)&"StringLiteral";

编译器期望pptr指向存储char的地址的东西,而我已经将它分配给“StringLiteral”本身的地址,这意味着当我输出时它解引用第一个指针来查找找到哪个地址char。问题是它直接指向“StringLiteral”的地址,这意味着它使用“StringLiteral”的第一个字母的值作为查找char的地址,基本上它将使用“S”作为地址要去。讨厌这么厚。

2 个答案:

答案 0 :(得分:4)

此表达式

&"StringLiteral"

在C ++中的类型为const char( * )[14],在C中的类型为char ( * )[14],因为字符串文字分别具有const char[14]char[14]类型。

因此,您可能无法将此类指针指定给const char **char **类型的对象,因为指针不兼容。

如果您将尝试使用此声明中的转换

const char** ppchar = (const char**) &"StringLiteral";

尽管如此,取消引用像*ppchar这样的指针是没有意义的,因为它不会像预期的类型char *的对象那样得到与第一个字符的值相对应的值。字符串文字而不是地址值。

例如,您可以通过以下方式将字符串文字转换为类型const char *(或C中的char *

StringLiteral + 0

因为在这样的表达式中,字符串文字被转换为指向其第一个字符的指针。但是,您可能不会将一元运算符&应用于此表达式,如

&( StringLiteral + 0 )

获取const char **类型的对象,因为您可能无法将操作符应用于rvalue

所以你可以做的是以下

const char *pchar = "StringLiteral";
const char **ppchar = &pchar;

答案 1 :(得分:1)

@Vlad from Moscow之外的好答案。

  

我可以直接将指针指向char指针吗?

几乎。在C中,代码可以使用复合文字来形成用字符串文字初始化的extension Array { var bounds : (Int, Int) { get { return (0, self.count - 1) } } } extension Array where Element == Array<Int> { subscript(first: Int, second: Int) -> Int? { get { guard !self.isEmpty else { return nil } guard first <= bounds.1 else { return nil } let it = self[first] guard second <= it.bounds.1 else { return nil } return it[second] } } } let one = [[1, 0], [3, 4]] print(one[1, 0]) // => Optional(3) ,然后将该指针的地址分配给{{1 }}

const char *