简体   繁体   English

初始化 - C中的多维数组

[英]Initialization - Multidimensional Arrays in C

I am new to C and I am trying to experiment with multi-dimensional arrays. 我是C的新手,我正在尝试使用多维数组。 I have the following example where I am trying to initialize a multi-dimensional array: 我有以下示例,我正在尝试初始化多维数组:

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'};

At first glance it would appear that this type of declaration would be valid since a multi-dimensional array is an array of arrays; 乍一看似乎这种类型的声明是有效的,因为多维数组是一个数组数组; however, this example fails to properly compile and I am not entirely certain as to why. 但是,这个例子无法正确编译,我不完全确定为什么。

I am aware that I am able to initialize a multi-dimensional array using the following notation: 我知道我能够使用以下表示法初始化多维数组:

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'},
};

However, what if I do not know the contents of the array at declaration time and would like to populate this array with data at a later point. 但是,如果我在声明时不知道数组的内容并希望稍后用数据填充此数组,该怎么办? I could initialize each individual element as follows: 我可以按如下方式初始化每个元素:

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

I am wondering if it somehow possible to declare each array using my original approach: 我想知道是否有可能使用我原来的方法声明每个数组:

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...

I tried to use strcpy as follows: 我尝试使用strcpy如下:

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

It appears that this might work if the multi-dimensional array was an array of null-terminated strings, but what would be an equivalent to a multi-dimensional array of integers or other data structures. 看起来如果多维数组是一个以空字符结尾的字符串数组,这可能会起作用,但是它会等同于整数或其他数据结构的多维数组。 Any help is appreciated. 任何帮助表示赞赏。 Thank you. 谢谢。

There is a difference between an initialiser and an assignment . 初始化者作业之间存在差异。 They both are introduced by = , but they are syntactically and semantically different. 它们都是由=引入的,但它们在语法和语义上都是不同的。

For an initializer , C can deduce the type of the right side of the = by the left side type. 对于初始化程序 ,C可以通过左侧类型推导出=的右侧类型。 For an assignment , the type must be know with the right side and be compatible with the left side (lvalue) type. 对于赋值 ,必须知道右侧的类型并且与左侧(左值)类型兼容 Most imporatnt here: the compiler has no type information from the lvalue when evaluating the right side (it does not even started the assignment expression at that moment). 最重要的是:在评估右侧时,编译器没有来自左值的类型信息(此时它甚至没有启动赋值表达式)。

An initialiser must only be used with a definition (you seem to confuse this with declaration - pay heed, they are well-defined terms with different meaning ). 初始化者只能与定义一起使用(您似乎将此与声明混淆 - 注意,它们是具有不同含义的明确定义的术语)。 SO once you have complete the definition , you cannout use an _initialiser anymore. 所以,一旦你完成了定义 ,你就不再使用_initialiser了。

Since C99, you can use a compound literal. 从C99开始,您可以使用复合文字。 This is much like a string literal ( "Hello world" ), but you have to tell the compiler its exact type (the string literal's type is given by the " ). Additionally, C does not allow arrays to be simply assigned like scalars or struct s. Thus you have to memcpy instead of the assignment: 这很像一个字符串文字( "Hello world" ),但是你必须告诉编译器它的确切类型(字符串文字的类型由" )给出。另外,C不允许像标量一样简单地指定数组或struct s。因此你必须memcpy而不是赋值:

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

Note the (char ...} part which is the compound literal . This is not a cast, but tells the compiler which type the object in the curly braces has (here: array of 10 char s). A cast OTOH is a prefix expression and changess the type of the following expression. Note that you can use a _string literal here instead, but that does obviously not work for other array element types. Also note that for string literals you cannot define their length other than providing as many characters. So if you forget two characters, you will invoke undefined behaviour for reading outside array boundaries. (Two because of the implicit trailing '\\0' character). 注意(char ...}部分是复合文字 。这不是强制转换,而是告诉编译器花括号中的对象具有哪种类型(这里: 10 char的数组)。强制转换OTOH是一个前缀表达式和更改下面表达式的类型。请注意,您可以在此处使用_string文字,但这显然不适用于其他数组元素类型。另请注意,对于字符串文字 ,除了提供尽可能多的字符外,您无法定义它们的长度因此,如果你忘记了两个字符,你将调用未定义的行为以便在数组边界外读取。(两个因为隐式尾随'\\0'字符)。

For the dimensions, you better use symbolic constants, (ie macros in C) like #define ROWS 10 to avoid magic numbers in your code - you have to use these values multiple times. 对于维度,最好使用符号常量(即C中的宏),如#define ROWS 10以避免代码中的幻数 - 您必须多次使用这些值。

For an array of pointers, you can use the easier way: 对于指针数组,您可以使用更简单的方法:

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

Warning: This does not allow to change entries like the first version does, because literals must not be written to! 警告:这不允许像第一个版本那样更改条目,因为文字不能写入!

Extra: This version also works for struct s (not just pointers to them), because C does allow assignments for those. 附加:此版本也适用于struct秒(不只是指向它们的指针),因为C 确实允许这些任务。 To me, this looks like one of the irregularities of C one has to live with. 对我来说,这看起来像C之一的不规则之处。

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

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