指向字符数组C++的问题

Dan*_*l S 11 c++

我有我认为应该是一个非常简单的代码片段,但我无法编译,因为我不明白的原因.

以下简化代码将无法编译:

char buffer[9] = "12345678";
char* pBuffer = &buffer;
Run Code Online (Sandbox Code Playgroud)

编译器(g ++)抛出以下错误:

error: cannot convert 'char (*)[9]' to 'char*' in initialization

C++并不完全是我的"原生"语言,但我看过的每个地方都告诉我这应该有用.非常感谢任何想法或建议.

Nat*_*ler 20

写,而不是取数组的地址

char buffer[9] = "12345678";
char *pBuffer = buffer;
Run Code Online (Sandbox Code Playgroud)

编辑:这一切意味着什么?

  • T长度类型的数组nn T内存中的(连续)序列.

  • 指针是内存地址.

所以例如,下面的代码

char a[5] = "hello";
char *p = "world";
Run Code Online (Sandbox Code Playgroud)

对应于内存中的以下情况:

将数组与指针进行比较.

在您的代码中,您已经创建了一个数组

char buffer[9] = "12345678";
Run Code Online (Sandbox Code Playgroud)

char a[5] = "hello"创建数组的方式相同.您打算创建一个指向char *数组第一个字符的指针,就像char *p上面指向数组的第一个字符一样"world".

当使用类型为"array of type"(此处buffer)的表达式时,它总是"衰减"到指向第一个元素的指针,除非

1.表达式用作sizeof的操作数(in sizeof(buffer),buffer不衰减到指针)

2.表达式用作一元&(在&buffer,buffer不衰减到指针)的操作数

要么

3.表达式是字符数组的字符串文字初始值设定项(在char someBuffer[3] = "ab"字符串文字中"ab",数组不会衰减为指针).

在标准的6.2.2.1节中列出:

729除非它是sizeof运算符或一元&运算符的操作数,或者是用于初始化数组的字符串文字,否则将类型为"array of type"的表达式转换为类型为"指向类型的指针"的表达式指向数组对象的初始元素,而不是左值.

因此,创建指向char *pBuffer数组中第一个字符的指针所需要做的就是写入

char *pBuffer = buffer;
Run Code Online (Sandbox Code Playgroud)

  • @DanielS for tl; dr:数组衰减到指向第一个元素的指针.获取数组的地址会生成一个指向_array_(这是一个不同类型)的指针,而不是指向该数组的第一个元素的指针.所以数组直接转换为指针. (2认同)

Gri*_*han 12

  • 声明char buffer[9] = "12345678";创建了一组9字符.
    这里buffer第一个元素的地址,但不是数组的地址.

  • char* pBuffer = buffer;是一个正确的表达式,因为它pBuffer是一个指向char的指针,可以解决第一个元素.

  • 但表达式char* pBuffer = &buffer错误的,因为pBuffer无法解决数组问题.(代码中的错误&buffer,数组的地址,如下所述)

buffer和之间的区别&buffer

&buffer表示数组的地址.buffer&buffer真的一样,但在语义上都是不同的.一个是char的地址,而另一个是9个字符的数组的地址.

buffer[9] = "12345678";


+----+----+----+---+---+----+----+----+---+----+ 
| '1'| '2' |'3'|'4'|'5'| '6'| '7'|'8' | 0 |  ...........
+----+----+----+---+---+----+----+----+---+---+----+  
 201   202  203 204 205 206  207   208 209 210  211
  ^     ^                                         
  |     |                                         
(buffer) (buffer + 1)                                         
|                                         |
|-----------------------------------------|--------
|201                                      | 210
  ^                                          ^
  |                                          |
(&buffer)                                 (&buffer + 1)     
Run Code Online (Sandbox Code Playgroud)

我使用十进制数字表示地址而不是十六进制

尽管价值bufferIS 201和的值&buffer201,他们的 意思是不同的:

  • buffer:第一个元素的地址 - 它的类型是char*.
  • &buffer:完整的char数组的地址 - 它的类型是char(*)[9].

另外,要观察差异,请添加1:

buffer + 1给出202 这是第二个数组元素 的地址,'2'
&buffer + 1给出210了下一个数组的地址.

在我的系统上,我编写以下代码:

int main(){
   char buffer[9] = "12345678";
   char (*pBuffer)[9] =  &buffer; 

   printf("\n %p, %p\n",buffer, buffer+1);
   printf("\n %p, %p\n",(&buffer), (&buffer+1));
}  
Run Code Online (Sandbox Code Playgroud)

输出如下:

0xbfdc0343, 0xbfdc0344

0xbfdc0343, 0xbfdc034c
Run Code Online (Sandbox Code Playgroud)

[回答]

就是错误的原因:

错误:初始化时无法将'char()[9]'转换为'char '

您正在尝试将'char (*)[9]'类型值分配给char*.

  • char (*ptr2)[9]; 在这里ptr2 is pointer to an array of 9 chars,这次
    ptr2=&buffer是一个有效的表达.

如何更正您的代码?

正如Nate Chandler的回答:

char buffer[9] = "12345678";
char* pBuffer =   buffer;   
Run Code Online (Sandbox Code Playgroud)

或另一种方法,

char buffer[9] = "12345678";
char (*pBuffer)[9] =  &buffer;       
Run Code Online (Sandbox Code Playgroud)

您选择哪种方法取决于您的需求.