【问题标题】:Initialization - Multidimensional Arrays in C初始化 - C 中的多维数组
【发布时间】:2015-10-04 16:47:42
【问题描述】:

我是 C 新手,我正在尝试使用多维数组。我有以下示例,我试图初始化一个多维数组:

char matrix[5][10];  

matrix[0] = {'0','1','2','3','4','5','6','7','8','9'};
matrix[1] = {'a','b','c','d','e','f','g','h','i','j'};
matrix[2] = {'A','B','C','D','E','F','G','H','I','J'};
matrix[3] = {'9','8','7','6','5','4','3','2','1','0'};
matrix[4] = {'J','I','H','G','F','E','D','C','B','A'};

乍一看,这种类型的声明似乎是有效的,因为多维数组是数组的数组;但是,此示例无法正确编译,我不完全确定原因。

我知道我可以使用以下符号初始化多维数组:

char matrix2[5][10] =
{
    {'0','1','2','3','4','5','6','7','8','9'},
    {'a','b','c','d','e','f','g','h','i','j'},
    {'A','B','C','D','E','F','G','H','I','J'},
    {'9','8','7','6','5','4','3','2','1','0'},
    {'J','I','H','G','F','E','D','C','B','A'},
};

但是,如果我在声明时不知道数组的内容并且想在以后用数据填充这个数组怎么办。我可以按如下方式初始化每个单独的元素:

matrix[0][0] = '0';
matrix[0][1] = '1';
matrix[0][2] =  '2';
etc....

我想知道是否可以使用我原来的方法声明每个数组:

matrix[0] = {'0','1','2','3','4','5','6','7','8','9'};
matrix[1] = {'a','b','c','d','e','f','g','h','i','j'};
etc...

我尝试使用strcpy如下:

strcpy(matrix[0], "012345678");
strcpy(matrix[1], "abcdefghi");

如果多维数组是一个以空字符结尾的字符串数组,这似乎可行,但它等效于整数或其他数据结构的多维数组。任何帮助表示赞赏。谢谢。

【问题讨论】:

  • 使用memcpy 而不是strcpy

标签: c arrays multidimensional-array


【解决方案1】:

initialiserassignment 是有区别的。它们都是由= 介绍的,但是它们在语法和语义上是不同的。

对于initializer,C 可以通过左侧类型推导出= 右侧的类型。对于assignment,类型必须知道右侧并且与左侧(左值)类型兼容。这里最重要的是:编译器在评估右侧时没有来自左值的类型信息(当时它甚至没有启动赋值表达式)。

initialiser 只能与 definition 一起使用(您似乎将此与 declaration 混淆了 - 注意,它们是明确定义的与different meaning 的条款。所以一旦你完成了定义,你就不能再使用_initialiser了。

从 C99 开始,您可以使用复合文字。这很像字符串文字 ("Hello world"),但您必须告诉编译器它的确切类型(字符串文字的类型由 " 给出)。此外,C 不允许像标量或structs 那样简单地分配数组。因此你必须memcpy 而不是赋值:

memcpy(matrix[0], (char [10]){ 1,2,3,4, ... }, 10));

注意(char ...} 部分,它是复合文字。这不是强制转换,而是告诉编译器花括号中的对象具有哪种类型(这里:10chars 的数组)。转换 OTOH 是一个前缀表达式,它改变了以下表达式的类型。请注意,您可以在此处改用 _string 文字,但这显然不适用于其他数组元素类型。另请注意,对于 字符串文字,除了提供尽可能多的字符外,您不能定义它们的长度。因此,如果您忘记了两个字符,您将调用 undefined behavior 来读取数组边界之外的内容。 (两个是因为隐含的尾随 '\0' 字符)。

对于维度,您最好使用符号常量(即 C 中的宏),例如 #define ROWS 10,以避免代码中出现幻数 - 您必须多次使用这些值。

对于指针数组,可以使用更简单的方法:

matrix[0] = (char [10]){ 1,2,3,4,...};

警告:这不允许像第一个版本那样更改条目,因为不能写入 literals

额外:这个版本也适用于structs(不仅仅是指向它们的指针),因为 C 确实 允许为它们赋值。对我来说,这看起来像是 C 的违规行为之一。

【讨论】:

  • 它与演员表有何不同?
  • @nerdistcolony:它不是演员表,而是属于大括号。大括号之间的内容不会转换为给定的类型,而是告诉编译器 parentethised(!;-) 构造的类型。演员表是一个表达式。
  • 感谢您的洞察力。我将不得不阅读 C 如何处理初始化和赋值语句。
  • @BLUEPIXY:我编辑了。再次感谢您的更正。我通常只将它与结构一起使用,所以我一开始就忘记了。
  • @Olaf - 我尝试了一个带有 int 指针的示例,但我不知道如何使其工作。你能展示我如何使用该技术初始化一个指针数组吗?我尝试将“强制转换”为 (int **)、(int *)、(int *[]) ... 没有任何效果:ideone.com/b6R5cy,还有ideone.com/b6R5cy
猜你喜欢
  • 2011-04-03
  • 2015-02-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-01
  • 1970-01-01
相关资源
最近更新 更多