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

时间:2013-01-07 04:39:39

标签: c++

我认为应该是一个非常简单的代码片段,但是由于我不理解的原因我无法编译。

以下简化代码无法编译:

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

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

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

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

6 个答案:

答案 0 :(得分:20)

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

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

修改:这一切意味着什么?

  • 长度为T的{​​{1}}类型数组是内存中n n的(连续)序列。

  • 指针是一个内存地址。

所以for example,以下代码

T

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

Comparing an array to a pointer.

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

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

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

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

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

buffer该表达式用作unary &的操作数(在2.中,&buffer不会衰减到指针)

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

这在section 6.2.2.1 of the standard中列出:

  

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

因此,为数组中的第一个字符创建指针"ab"所需要做的就是写

char *pBuffer

答案 1 :(得分: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)     

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

即使buffer的值为201&buffer的值为201,其含义也不同:

  • buffer:第一个元素的地址 - 其类型为char*
  • &buffer:完整字符数组的地址 - 其类型为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

[ANSWER]

错误的原因:

  

错误:初始化时无法将'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;   

或其他方法,

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

您选择的内容取决于您的需求。

答案 2 :(得分:4)

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

char* pBuffer = buffer;

同时结帐:std::decay

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

输出:

int[] -> int*; // true

答案 3 :(得分:2)

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

这与char*不同。但是,在需要时,数组会降级为指向第一个元素的指针,因此......

char *pbuffer = buffer;

答案 4 :(得分:0)

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

所以,

char* pBuffer = buffer;

建议是正确的。

答案 5 :(得分:-1)

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

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