为什么char**不能成为C++中以下函数的返回类型?

con*_*ist 3 c c++ function return-type char

我在C++中有以下功能:

char** f()
{
    char (*v)[10] = new char[5][10];
    return v;
}
Run Code Online (Sandbox Code Playgroud)

Visual Studio 2008表示如下:

error C2440: 'return' : cannot convert from 'char (*)[10]' to 'char **'
Run Code Online (Sandbox Code Playgroud)

为了使这个功能起作用,返回类型究竟应该是什么?

Naw*_*waz 16

char**与...不是同一类型char (*)[10].这两者都是不兼容的类型,因此char (*)[10]无法隐式转换为char**.因此编译错误.

该函数的返回类型看起来非常难看.你必须把它写成:

char (*f())[10]
{
    char (*v)[10] = new char[5][10];
    return v;
}
Run Code Online (Sandbox Code Playgroud)

现在它编译.

或者您可以使用typedef:

typedef char carr[10];

carr* f()
{
    char (*v)[10] = new char[5][10];
    return v;
}
Run Code Online (Sandbox Code Playgroud)

Ideone.


基本上,char (*v)[10]定义一个指向char大小为10 的数组的指针.它与以下内容相同:

 typedef char carr[10]; //carr is a char array of size 10

 carr *v; //v is a pointer to array of size 10
Run Code Online (Sandbox Code Playgroud)

所以你的代码就等同于:

carr* f()
{
    carr *v = new carr[5];
    return v;
}
Run Code Online (Sandbox Code Playgroud)

cdecl.org 帮助:

  • char v[10] 读为 declare v as array 10 of char
  • char (*v)[10] 读为 declare v as pointer to array 10 of char

  • 这是一个很好的答案.伟大的工作Nawaz. (2认同)

Lig*_*ica 13

指向指针的指针与指向数组的指针不同.

非常粗略的图

(特别注意如何sizeof(*ptr1)sizeof(char)*6,而sizeof(*ptr3)sizeof(char*)-这对指针运算严重的后果.)


new char[5][10]给你一个char (*)[10](顺便说一下,它与函数指针完全无关),因为指针和字符在内存中以这种方式排列(我的第二个例子).

这是一样的char**(代表一个不同的布局),因此两者之间的转换是没有意义的; 因此,它是不允许的.

所以你的函数的返回类型必须是char (*)[10]:

char (*f())[10] {
    char (*v)[10] = new char[5][10];
    return v;
}
Run Code Online (Sandbox Code Playgroud)

当然,这真的很丑陋,所以你的成绩要好得多std::vector<std::string>.


此FAQ条目以"转换"标题解释最佳.


Eri*_*c Z 5

因为char**char (*)[10]是两种不同的类型.char**是一个指向指针(to char)char (*)[10]的指针,而是一个指向数组(大小为10)的指针char.作为结果,所述移动步骤char**sizeof(void *)这是对win32平台4个字节字节,移动步骤char (*)[10]sizeof(char) * 10字节.

   char *c = NULL;
   char **v = &c;
   cout << typeid(v).name() << endl;
   cout << (void*)v << endl;
   v += 1;
   cout << (void*)v << endl;

   char d[10];
   char (*u)[10] = &d;
   cout << typeid(u).name() << endl;
   cout << (void*)u << endl;
   u += 1;
   cout << (void*)u << endl;
Run Code Online (Sandbox Code Playgroud)

产量

char * *
0034FB1C
0034FB20
char (*)[10]
001AFC50
001AFC5A
Run Code Online (Sandbox Code Playgroud)

char (*)[10]用作函数的返回类型(或函数的输入/输出参数),最简单和最易读的方法是使用typedef:

// read from inside-out: PTRTARR is a pointer, and, it points to an array, of chars.
typedef char (*PTRTARR)[10];
Run Code Online (Sandbox Code Playgroud)

请注意,它可以很容易地混在一起typedef的的指针数组,如果不小心:

// operator[] has higher precedence than operator*,
// PTRARR is an array of pointers to char.
typedef char *PTRARR[10];
Run Code Online (Sandbox Code Playgroud)

参考

数组和指针