C语言 C中的多维数组初始化
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18157251/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Multidimensional array initialization in C
提问by user2635911
I am reading the book, "Programming in C" by Kochen and I am confused where he explains the initialization of multidimensional array
我正在阅读 Kochen 的“Programming in C”一书,我对他解释多维数组初始化的地方感到困惑


In particular, I don't understand the meaning of the following sentence Note that, in this case, the inner pairs of braces are required to force the correct initialization. Without them, the first two rows and the first two elements of the 3rd row would have been initialized instead.I'm not sure what the heck the sentence means.
特别不明白下面这句话的意思注意,在这种情况下,需要内部的大括号对来强制正确初始化。没有它们,前两行和第三行的前两个元素将被初始化。我不确定这句话到底是什么意思。
采纳答案by Daniel K
With the inner braces the array looks like this:
使用内大括号,数组如下所示:
10 5 -3 0 0
9 0 0 0 0
32 20 1 0 0
0 0 8 0 0
So in every line the last 2 values are zero (because you didn't set a value for them. Without the inner braces the array would look like this:
因此,在每一行中,最后 2 个值为零(因为您没有为它们设置值。如果没有内大括号,数组将如下所示:
10 5 -3 9 0
0 32 20 1 0
0 8 0 0 0
0 0 0 0 0
Only the first 12 elements would become the given values and the rest will be 0.
只有前 12 个元素会成为给定的值,其余的将为 0。
回答by Joseph Myers
This is because the M[4][5]array has 20 elements (4 rows, 5 columns), and the default order for initialization is row-by-row if rows are not explicitly specified by using inner pairs of braces.
这是因为M[4][5]数组有 20 个元素(4 行 5 列),如果没有使用内部大括号显式指定行,则初始化的默认顺序是逐行。
What this means is that if you assign the same 12 values as a simple linear list, without the inner pairs of braces, then values are assigned to the first two rows (2*5 = 10 elements) plus the first 2 columns of the third row. (The remaining 8 elements of the array which you did not explicitly initialize will automatically be set to 0.)
这意味着,如果您将 12 个值分配为简单的线性列表,而没有内部大括号对,则将值分配给前两行(2*5 = 10 个元素)加上第三行的前 2 列排。(您未显式初始化的数组的其余 8 个元素将自动设置为 0。)
The C compiler is aware that each row only has 5 columns, and will automatically wrap the list of numbers onto the next row each time the 5-column margin is reached. Thus,
C 编译器知道每行只有 5 列,并且每次达到 5 列边距时都会自动将数字列表换到下一行。因此,
int M[4][5] = {10, 5, -3, 9, 0, 0, 32, 20, 1, 0, 0, 8};
is understood to mean
被理解为
int M[4][5] =
{
{10, 5, -3, 9, 0},
{ 0, 32, 20, 1, 0},
{ 0, 8, 0, 0, 0},
{ 0, 0, 0, 0, 0}
};
You can override the default order by using inner braces to separate your 12 values into rows of your own liking (but naturally not more than 5 columns per row for this definition of an array M).
您可以通过使用内大括号将 12 个值分成您自己喜欢的行来覆盖默认顺序(但对于这个数组的定义,每行自然不超过 5 列M)。
For instance, when you use inner braces to separate the same 12 values into four sets of 3 like your page from the book shows, then those inner braces are interpreted to initialize separate rows of the multidimensional array. And the result will be initializing four rowsof the array, but only the first 3 columns of those four rows, setting the remaining columns to zero (two blank zero values at the end of each row).
例如,当您使用内大括号将相同的 12 个值分成四组 3 时,就像您在书中显示的页面一样,那么这些内大括号将被解释为初始化多维数组的单独行。结果将初始化数组的四行,但只初始化这四行的前 3 列,将其余列设置为零(每行末尾有两个空白零值)。
That is to say, the C compiler is aware that the array Mhas 5 columns in each row, and so it will add the missing columns to each row so that each row has 5 columns, and so the array will have a total of 20 values:
也就是说,C 编译器知道数组M每行有 5 列,因此它会将缺失的列添加到每行中,使每行有 5 列,因此数组总共有 20 个值:
int M[4][5] =
{
{10, 5, -3},
{ 9, 0, 0},
{32, 20, 1},
{ 0, 0, 8}
};
is understood to mean
被理解为
int M[4][5] =
{
{10, 5, -3, 0, 0},
{ 9, 0, 0, 0, 0},
{32, 20, 1, 0, 0},
{ 0, 0, 8, 0, 0}
};
回答by Alexandru Barbarosie
Since all arrays internally behave as 1d arrays you have to specify with the brackets which rows exactly you initialize.
由于所有数组在内部都表现为一维数组,因此您必须使用括号指定您要初始化的行。
For exemple:
举个例子:
int a[4][5] = {
{ 1, 2, 3 }, // those are the elements of the first row.
// only the first 3 elements are initialized
{ 1, 2, 3, 4} // those are the elements of the 2nd row.
// only the first 4 element are initialized
};
// everything else will be equal to 0
while
尽管
int a[4][5] = { 1, 2, 3, 1, 2, 3, 4}; // this will initialize first 5 elements
// of the first row and then continue
// with the 2nd one making the first 2
// elements to be 3 and 4 respectivly
// everything else will be equal to 0
回答by 1''
Multidimensional arrays in C are just "syntactic sugar" for one-dimensional arrays. When you allocate a 4 x 5 int array, you're really allocating space for 20 integers in a row in memory. These integers are stored as all the elements of the first row, then all the elements of the second row, etc.
C 语言中的多维数组只是一维数组的“语法糖”。当您分配一个 4 x 5 int 数组时,您实际上是在为内存中的一行中的 20 个整数分配空间。这些整数存储为第一行的所有元素,然后是第二行的所有元素,依此类推。
Without the inner braces, your initializer is 1D as well, and indicates that you want to initialize the first 12 of these 20 integers, namely the first two rows and the first two elements of the third row.
如果没有内大括号,您的初始化器也是 1D 的,并指示您要初始化这 20 个整数中的前 12 个,即前两行和第三行的前两个元素。
回答by Keith Thompson
It would help to see the specific example.
看看具体的例子会有所帮助。
A multidimensional array is an array of arrays. (It's not just syntactic sugar for a long 1-dimensional array.)
多维数组是数组的数组。(这不仅仅是长一维数组的语法糖。)
In an initializer, it's legal to omit both trailing elements (which are implicitly initialized to zero) and inner curly braces.
在初始化程序中,省略尾随元素(隐式初始化为零)和内部大括号是合法的。
Given:
鉴于:
int arr[2][2];
a full initialization might look like:
完整的初始化可能如下所示:
int arr[2][2] = { { 10, 20 }, { 30, 40 } };
You can (but IMHO shouldn't) omit the inner braces:
您可以(但恕我直言不应该)省略内部大括号:
int arr[2][2] = { 10, 20, 30, 40 };
and the compiler will map the elements of the initializer to the elements of arr.
并且编译器会将初始化器的元素映射到arr.
If you omit trailing elements:
如果省略尾随元素:
int arr[2][2] = { { 10, 20 } };
then the second row is implicitly initialized to { 0, 0 }.
然后第二行被隐式初始化为{ 0, 0 }.
Or you could write:
或者你可以写:
int arr[2][2] = { { 10 }, { 20 } };
which would assign the values 10 and 20 to the first element of each row, not to the first row.
这会将值 10 和 20 分配给每行的第一个元素,而不是分配给第一行。
Again, it's hard to tell exactly what the author was talking about without seeing an example, but an inner brace tells the compiler to start a new row, even if the first row is incomplete.
同样,如果没有看到示例,很难确切地说出作者在说什么,但是内大括号告诉编译器开始一个新行,即使第一行不完整。
If you supply initializers for all 4 elements (or more generally all X * Yelements), the inner braces are not strictly necessary; the order of the elements is the same either way.
如果您为所有 4 个元素(或更一般地所有X * Y元素)提供初始化器,则内部大括号不是绝对必要的;无论哪种方式,元素的顺序都是相同的。
Personally, I find it much clearer to include all the inner braces anyway, because they reflect the actual structure you're initializing.
就个人而言,我发现无论如何都包含所有内部大括号更清晰,因为它们反映了您正在初始化的实际结构。
(So what's the difference between a 1-dimensional array and a 2-dimensional array, apart from syntactic sugar? Given the above declaration of arr, if it were the same as a 1-dimensional array then arr[0][2]would be the same as arr[1][0], with the second index overflowing into the second row. And it may work that way in practice, but actually arr[0][2]has undefined behavior. This does have practical consequences; an optimizing compiler may assumethat all bounds are within range, and generate code that misbehaves if that assumption is violated.)
(那么除了语法糖之外,一维数组和二维数组有什么区别?鉴于上面的声明arr,如果它与一维数组arr[0][2]相同arr[1][0],那么将与第二个相同索引溢出到第二行。它可能在实践中以这种方式工作,但实际上arr[0][2]具有未定义的行为。这确实有实际后果;优化编译器可能会假设所有边界都在范围内,如果违反该假设,则会生成行为不端的代码.)
See also this question.
另请参阅此问题。

