带有以下声明
int array[ROW][COLUMN]={0};
我得到全零但下面的一个数组
int array[ROW][COLUMN]={1};
我没有获得所有值的数组。默认值仍为0。
为什么会出现这种现象,以及如何用全1初始化?
编辑:我刚刚了解到,将memset
value用作1会将每个字节设置为1,因此每个数组单元的实际值不会为1而是16843009
。如何将其设置为1?
带有以下声明
int array[ROW][COLUMN]={0};
我得到全零但下面的一个数组
int array[ROW][COLUMN]={1};
我没有获得所有值的数组。默认值仍为0。
为什么会出现这种现象,以及如何用全1初始化?
编辑:我刚刚了解到,将memset
value用作1会将每个字节设置为1,因此每个数组单元的实际值不会为1而是16843009
。如何将其设置为1?
why and how
两个。:)
Answers:
您得到此行为,因为int array [ROW][COLUMN] = {1};
这并不意味着“将所有项目设置为一个”。让我尝试逐步解释它是如何工作的。
初始化数组的显式,过于清晰的方法是这样的:
#define ROW 2
#define COLUMN 2
int array [ROW][COLUMN] =
{
{0, 0},
{0, 0}
};
但是,C允许您省略数组(或struct / union)中的某些项。您可以例如编写:
int array [ROW][COLUMN] =
{
{1, 2}
};
这意味着将第一个元素初始化为1和2,然后将其余元素初始化为“好像它们具有静态存储持续时间”。C语言中有一条规则,规定所有未由程序员明确初始化的静态存储持续时间对象都必须设置为零。
因此,在上面的示例中,第一行设置为1,2,第二行设置为0,0,因为我们没有为它们提供任何显式值。
接下来,在C中有一个规则允许大括号样式。第一个例子也可以写成
int array [ROW][COLUMN] = {0, 0, 0, 0};
尽管这当然是不好的风格,但很难阅读和理解。但这条规则很方便,因为它允许我们编写
int array [ROW][COLUMN] = {0};
这意味着:“将第一行中的第一列初始化为0,并将所有其他项目初始化为静态存储持续时间,即将它们设置为零。”
因此,如果您尝试
int array [ROW][COLUMN] = {1};
这意味着“将第一行的第一列初始化为1,并将所有其他项设置为零”。
int array [ROW][COLUMN] = {{0}};
如果要将数组初始化为,-1
则可以使用以下代码,
memset(array, -1, sizeof(array[0][0]) * row * count)
但这将起作用0
并且-1
只有
0000
和1111
<cstring>
在c ++中
int array[ROW][COLUMN]={1};
这仅将第一个元素初始化为1。其他所有元素都为0。
在第一个实例中,您将执行相同的操作-将第一个元素初始化为0,其余元素默认为0。
原因很简单:对于数组,编译器会将未指定的每个值初始化为0。
对于char
数组,您可以memset
用来设置每个字节,但这通常不适用于int
数组(尽管可以使用0)。
常规for
循环将快速完成此操作:
for (int i = 0; i < ROW; i++)
for (int j = 0; j < COLUMN; j++)
array[i][j] = 1;
或可能更快(取决于编译器)
for (int i = 0; i < ROW*COLUMN; i++)
*((int*)a + i) = 1;
0
仅初始化第一个值。然后0
默认情况下初始化所有其余部分。
value
字段memset
为1,则矩阵中的实际值将为1,但是2^0 + 2^8 + 2^16 + 2^24
?
memset
将目标中的每个字节设置为给定的值,将an设置int
为1memset
无效。除非希望将对象的每个字节设置为相同的值,否则不能用于设置多字节对象的值。
请注意,GCC对指定的初始化方法表示法进行了扩展,这对于上下文非常有用。也可以clang
不加评论地允许它(部分原因是它试图与GCC兼容)。
扩展符号允许您使用...
以下值指定要初始化的元素范围。例如:
#include <stdio.h>
enum { ROW = 5, COLUMN = 10 };
int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = 1 } };
int main(void)
{
for (int i = 0; i < ROW; i++)
{
for (int j = 0; j < COLUMN; j++)
printf("%2d", array[i][j]);
putchar('\n');
}
return 0;
}
毫不奇怪,输出是:
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1
请注意,Fortran 66(Fortran IV)对数组的初始化程序具有重复计数。当将指定的初始值设定项添加到语言中时,C没有得到它们,这总是让我感到奇怪。Pascal使用0..9
表示法来指定范围从0到9的范围(包括0和9),但是C不用..
作标记,因此不使用它就不足为奇了。
注意,...
符号周围的空格本质上是必需的;如果它们附加在数字上,则该数字将被解释为浮点数。例如,0...9
如将标记化0.
,.
,.9
,和浮点数不允许作为数组下标。使用命名的常量...ROW-1
不会造成麻烦,但是最好养成安全的习惯。
附加物:
我注意到,GCC 7.3.0拒绝了:
int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = { 1 } } };
标量初始值设定项1
(error: braces around scalar initializer [-Werror]
)周围还有一组花括号。鉴于您通常可以在中的标量周围指定大括号int a = { 1 };
,因此我不确定这是正确的,这是标准明确允许的。我也不确定这是不正确的。
我还想知道是否会有更好的表示法[0]...[9]
-明确,不能与任何其他有效语法混淆,并且避免与浮点数混淆。
int array[ROW][COLUMN] = { [0]...[4] = { [0]...[9] = 1 } };
也许标准委员会会考虑这一点?
要使用零初始化2d数组,请使用以下方法:
int arr[n][m] = {};
注意:以上方法仅适用于以0初始化;