C/C++ 中的二维字符数组

Two-dimensional character array in C/C++

本文关键字:二维 字符 数组 C++      更新时间:2023-10-16

两者有什么区别

char (CharBuff[50])[10];

char CharBuff[10][50];

我的要求是有 10 个字符的缓冲区,每个缓冲区的最大长度为 50(包括 null 终止字符(

而且,我想以CharBuff[0],CharBuff[1]等方式访问缓冲区。

char (CharBuff[50])[10];

CharBuff声明为 50 个元素数组的 10 个元素数组的 char 个数组。 在这种情况下,括号是多余的。

char CharBuff[10][50];

CharBuff声明为 10 元素数组的 50 元素数组的 char

假设你想要10个最多50个字符的字符串,你将使用第二种形式;每个CharBuff[i]的类型将是"50元素数组char"。

如果你真的想为一个 50 个元素的 char 数组创建一个单独的类型定义,你可以做类似的事情

typedef char Str[50];  
...
Str CharBuff[10];

现在CharBuff是一个 10 元素的 Str 数组,它是一个 50 元素的 char 数组。

通常,我不会创建这样的单独 typedef,除非我想使Str不透明;也就是说,我不想将其实现的细节暴露给使用它的人。 除了 typedef 之外,我还提供了一个 API,用于分配、分配、复制、格式化和显示类型 Str 的对象。

换句话说,如果使用 Str 类型的人必须知道它是一个 50 元素的char数组才能正确使用它,那么最好让他们使用 50 元素的char数组。

这里的其他答案说它们是一样的是错误的!两者都不是相同的数组,它们的大小也非常不同。这里有一个片段来说明这一点:

char i[50][10];
std::cout << sizeof(i[1]) << 'n';
char (j[10])[50];
std::cout << sizeof(j[1]) << 'n';

10

50

您可以在此处查看实时示例。

i 是一个 50 元素数组,每个元素是 10 个元素的字符数组,而j是一个 10 个元素的数组,每个元素都是一个 50 个元素的字符数组。尽管两者的总大小相同,但每个级别的元素大小会有所不同。如果你假设它们是相同的,这将导致未定义的行为

i[25][5]  // OK
j[25][5]  // accessing j beyond index 9 is undefined behaviour!

这表明括号在非指针、非引用数组声明中没有意义,即 char (j[10])[50]只是混淆了char j[10][50]的符号。

我的要求是有 10 个字符的缓冲区,每个缓冲区的最大长度为 50

然后你应该将数组声明为 char CharBuff[10][50]

没有人使用前者,总是使用后一种形式:

char CharBuff[10][50];

后一种语法将很熟练,并且根据您对 10 行(字符缓冲区(的要求,每行长度为 50 条,不会造成混淆。

选择最后一个,因为它清楚地说明了您要分配的内容。
但是,由于该问题也标记为c++,因此我建议使用std::vectorstd::string,如下所示:

std::vector<std::string> CharBuff(10, std::string(50, ''));

我在这里看到的大问题是语法混乱。当你使用括号时,它们已经在 c 和 c++ 语法中具有已知的角色,例如类型转换、指向函数的指针(看起来有点像你写的(。你使用它们的目的增加了一个新的含义,它使代码更加模糊,并忽略了一个事实,即 c 和 c++ 有一个伟大而直观的方式,对于任何至少使用过一次矩阵的人来说,表达 2D 数组。因此,为了获得干净且不令人困惑的语法,请使用后一个版本:

char CharBuff[10][50];

您正在寻找 10 个数组,每个数组 50 个字符。

要声明 50 个字节的单个缓冲区,请使用

夏尔·查巴夫[50];

但是你想要有 10 个缓冲区,所以只需将其附加到之前[50],例如:

夏尔·查巴夫[10][50];

现在 CharBuff[0] 将寻址第一个五十字节缓冲区,CharBuff[1] 将获得第二个缓冲区,依此类推。