10

我有我认为应该是一个非常简单的代码片段来编写,尽管由于我不明白的原因我无法编译。

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

char buffer[9] = "12345678";
char* pBuffer = &buffer;

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

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

C++ 不完全是我的“本机”语言,但我所看到的任何地方都告诉我这应该可以工作。非常感谢任何想法或建议。

4

6 回答 6

20

而不是获取数组的地址,而是写

char buffer[9] = "12345678";
char *pBuffer = buffer;

编辑:这一切是什么意思?

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

  • 指针是内存地址。

例如,下面的代码

char a[5] = "hello";
char *p = "world";

对应内存中的以下情况:

将数组与指针进行比较。

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

char buffer[9] = "12345678";

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

当使用“类型数组”(此处buffer)类型的表达式时,它总是“衰减”到指向第一个元素的指针,除非

1.该表达式用作sizeof的操作数(在 中sizeof(buffer)buffer不会衰减为指针)

2.该表达式用作一元 &的操作数(在 中&bufferbuffer不会衰减为指针)

或者

3.表达式是字符数组的字符串字面量初始化器(在 中char someBuffer[3] = "ab",字符串字面量"ab"是一个数组,不会衰减为指针)。

在标准的第 6.2.2.1 节中列出:

729 除非它是 sizeof 运算符或一元 & 运算符的操作数,或者是用于初始化数组的字符串字面量,否则“类型数组”类型的表达式将转换为“类型指针”类型的表达式指向数组对象的初始元素并且不是左值。

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

char *pBuffer = buffer;
于 2013-01-07T04:43:24.663 回答
12
  • 该声明创建了一个字符char buffer[9] = "12345678";数组。 这里,是它的第一个元素的地址,而不是数组的地址。 9
    buffer

  • char* pBuffer = buffer;是一个正确的表达式,因为pBuffer它是一个指向 char 的指针,并且可以寻址第一个元素。

  • 但是表达式char* pBuffer = &buffer错误的,因为pBuffer无法寻址数组。(代码中的错误,&buffer数组地址如下所述

buffer和之间的区别&buffer

&buffer表示数组的地址。和的实际上是相同的,但在语义上两者是不同的。一个是 char 的地址,而另一个是 9 个字符的数组的地址。buffer&buffer

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)     

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

即使 is 的值和isbuffer201值,它们的 含义也不同:&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));
}  

输出如下:

0xbfdc0343, 0xbfdc0344

0xbfdc0343, 0xbfdc034c

[回答]

就是错误的原因

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

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

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

如何更正您的代码?

正如内特钱德勒的回答:

char buffer[9] = "12345678";
char* pBuffer =   buffer;   

或其他方法,

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

您选择哪种取决于您的需要。

于 2013-01-07T09:19:15.477 回答
4

数组衰减为指针,你只需要

char* pBuffer = buffer;

还结帐:std::decay

   std::cout << "int[] -> int*; // " << std::boolalpha
              << std::is_same<int *, std::decay<int[]>::type>::value;

输出:

int[] -> int*; // true
于 2013-01-07T04:48:35.627 回答
2

错误信息非常清楚;&buffer是类型char (*)[9],即指向具有 9 个元素的 char 数组的指针(是的,数组是完全成熟的类型)。

这与char*. 但是,数组在需要时会降级为指向第一个元素的指针,所以......

char *pbuffer = buffer;
于 2013-01-07T04:49:02.403 回答
0

数组名表示它的基地址,所以如果只写缓冲区,则表示缓冲区[0]的地址。如果你使用 &buffer,你需要在 char** 中而不是在 char * 中。

所以,

char* pBuffer = buffer;

按照建议是正确的。

于 2013-01-07T06:12:34.940 回答
-1

因为编译器无法将 char( )[] 隐式转换为 char。所以你需要显式类型转换

char buffer[9] = "12345678";
char* pBuffer = (char*)&buffer;
于 2013-01-07T04:49:11.450 回答