简体   繁体   English

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

[英]Why can't char** be the return type of the following function in C++?

I have the following function in C++ : 我在C ++中有以下功能:

char** f()
{
    char (*v)[10] = new char[5][10];
    return v;
}

Visual studio 2008 says the following: Visual Studio 2008表示如下:

error C2440: 'return' : cannot convert from 'char (*)[10]' to 'char **'

What exactly should the return type to be, in order for this function to work? 为了使这个功能起作用,返回类型究竟应该是什么?

char** is not the same type as char (*)[10] . char**char (*)[10] Both of these are incompatible types and so char (*)[10] cannot be implicitly converted to char** . 这两者都是不兼容的类型,因此char (*)[10]不能隐式转换为char** Hence the compilation error. 因此编译错误。

The return type of the function looks very ugly. 该函数的返回类型看起来非常难看。 You have to write it as: 你必须把它写成:

char (*f())[10]
{
    char (*v)[10] = new char[5][10];
    return v;
}

Now it compiles . 现在它编译

Or you can use typedef as: 或者你可以使用typedef

typedef char carr[10];

carr* f()
{
    char (*v)[10] = new char[5][10];
    return v;
}

Ideone . Ideone


Basically, char (*v)[10] defines a pointer to a char array of size 10. It's the same as the following: 基本上, char (*v)[10]定义了一个指向大小为10的char数组的指针。它与以下内容相同:

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

 carr *v; //v is a pointer to array of size 10

So your code becomes equivalent to this: 所以你的代码就等同于:

carr* f()
{
    carr *v = new carr[5];
    return v;
}

cdecl.org helps here: cdecl.org在这里帮助:

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

A pointer to pointers is not the same as a pointer to arrays. 指向指针的指针与指向数组的指针不同。

非常粗略的图

(In particular, notice how sizeof(*ptr1) is sizeof(char)*6 , whereas sizeof(*ptr3) is sizeof(char*) — this has serious ramifications for pointer arithmetic.) (特别注意sizeof(*ptr1)sizeof(char)*6 ,而sizeof(*ptr3)sizeof(char*) - 这对指针算法有严重的影响。)


new char[5][10] gives you a char (*)[10] (which has absolutely nothing to do with function pointers, by the way), because the pointers and chars are laid out in that fashion in memory (my second example). new char[5][10]给你一个char (*)[10] (顺便说一下,它与函数指针完全无关),因为指针和字符在内存中以这种方式排列(我的第二个)例)。

This is not the same as char** (which represents a different layout), so a conversion between the two makes no sense; 这是一样char** (代表一个不同的布局),因此两者之间的转换是没有意义的; hence, it is disallowed. 因此,它是不允许的。

So your function's return type must be char (*)[10] : 所以你的函数的返回类型必须是char (*)[10]

char (*f())[10] {
    char (*v)[10] = new char[5][10];
    return v;
}

Of course, this is really ugly, so you're far better off with a std::vector<std::string> . 当然,这真的很难看,所以你用std::vector<std::string>会好得多。


This FAQ entry explains it best, under the title "Conversions". 此FAQ条目以“转换”标题解释最佳。

Because char** and char (*)[10] are two different types. 因为char**char (*)[10]是两种不同的类型。 char** is a pointer to pointer(to char ), while char (*)[10] is a pointer to an array(of size 10) of char . char**是指向指针(指向char )的指针,而char (*)[10]是指向char的数组(大小为10)的指针。 Resultantly, the moving step of char** is sizeof(void *) bytes which is 4 bytes on win32 platform, and the moving step of char (*)[10] is sizeof(char) * 10 bytes. 结果, char**移动步骤sizeof(void *)字节,在win32平台上是4个字节,而char (*)[10]移动步骤sizeof(char) * 10个字节。

Example

   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;

Output 产量

char * *
0034FB1C
0034FB20
char (*)[10]
001AFC50
001AFC5A

To use char (*)[10] as a function's return type(or as input/output parameter of the function), the easiest and most readable way is to use a typedef : 要使用char (*)[10]作为函数的返回类型(或函数的输入/输出参数),最简单和最易读的方法是使用typedef

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

Note that it can easily be mixed up with typedef of an array of pointers , if not careful: 请注意,如果不小心,它很容易与指针数组的 typedef混淆:

// operator[] has higher precedence than operator*,
// PTRARR is an array of pointers to char.
typedef char *PTRARR[10];

Reference 参考

Arrays and Pointers 数组和指针

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM