可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
With the following declaration
int array[ROW][COLUMN]={0};
I get the array with all zeroes but with the following one
int array[ROW][COLUMN]={1};
I don’t get the array with all one value. The default value is still 0.
Why this behavior and how can I initialize with all 1?
EDIT: I have just understood that using memset
with value as 1, will set each byte as 1 and hence the actual value of each array cell wont be 1 but 16843009
. How do I set it to 1?
回答1:
You get this behavior, because int array [ROW][COLUMN] = {1};
does not mean "set all items to one". Let me try to explain how this works step by step.
The explicit, overly clear way of initializing your array would be like this:
#define ROW 2
#define COLUMN 2
int array [ROW][COLUMN] =
{
{0, 0},
{0, 0}
};
However, C allows you to leave out some of the items in an array (or struct/union). You could for example write:
int array [ROW][COLUMN] =
{
{1, 2}
};
This means, initialize the first elements to 1 and 2, and the rest of the elements "as if they had static storage duration". There is a rule in C saying that all objects of static storage duration, that are not explicitly initialized by the programmer, must be set to zero.
So in the above example, the first row gets set to 1,2 and the next to 0,0 since we didn't give them any explicit values.
Next, there is a rule in C allowing lax brace style. The first example could as well be written as
int array [ROW][COLUMN] = {0, 0, 0, 0};
although of course this is poor style, it is harder to read and understand. But this rule is convenient, because it allows us to write
int array [ROW][COLUMN] = {0};
which means: "initialize the very first column in the first row to 0, and all other items as if they had static storage duration, ie set them to zero."
therefore, if you attempt
int array [ROW][COLUMN] = {1};
it means "initialize the very first column in the first row to 1 and set all other items to zero".
回答2:
If you want to initialize the array to -1
then you can use the following,
memset(array, -1, sizeof(array[0][0]) * row * count)
But this will work 0
and -1
only
回答3:
int array[ROW][COLUMN]={1};
This initialises only the first element to 1. Everything else gets a 0.
In the first instance, you're doing the same - initialising the first element to 0, and the rest defaults to 0.
The reason is straightforward: for an array, the compiler will initialise every value you don't specify with 0.
With a char
array you could use memset
to set every byte, but this will not generally work with an int
array (though it's fine for 0).
A general for
loop will do this quickly:
for (int i = 0; i < ROW; i++)
for (int j = 0; j < COLUMN; j++)
array[i][j] = 1;
Or possibly quicker (depending on the compiler)
for (int i = 0; i < ROW*COLUMN; i++)
*((int*)a + i) = 1;
回答4:
Note that GCC has an extension to the designated initializer notation which is very useful for the context. It is also allowed by clang
without comment (in part because it tries to be compatible with GCC).
The extension notation allows you to use ...
to designate a range of elements to be initialized with the following value. For example:
#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;
}
The output is, unsurprisingly:
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
Note that Fortran 66 (Fortran IV) had repeat counts for initializers for arrays; it's always struck me as odd that C didn't get them when designated initializers were added to the language. And Pascal uses the 0..9
notation to designate the range from 0 to 9 inclusive, but C doesn't use ..
as a token, so it is not surprising that was not used.
Note that the spaces around the ...
notation are essentially mandatory; if they're attached to numbers, then the number is interpreted as a floating point number. For example, 0...9
would be tokenized as 0.
, .
, .9
, and floating point numbers aren't allowed as array subscripts.
With the named constants, ...ROW-1
would not cause trouble, but it is better to get into the safe habits.
Addenda:
I note in passing that GCC 7.3.0 rejects:
int array[ROW][COLUMN] = { [0 ... ROW-1] = { [0 ... COLUMN-1] = { 1 } } };
where there's an extra set of braces around the scalar initializer 1
(error: braces around scalar initializer [-Werror]
). I'm not sure that's correct given that you can normally specify braces around a scalar in int a = { 1 };
, which is explicitly allowed by the standard. I'm not certain it's incorrect, either.
I also wonder if a better notation would be [0]...[9]
— that is unambiguous, cannot be confused with any other valid syntax, and avoids confusion with floating point numbers.
int array[ROW][COLUMN] = { [0]...[4] = { [0]...[9] = 1 } };
Maybe the standards committee would consider that?
回答5:
To initialize 2d array with zero use the below method:
int arr[n][m] = {};
NOTE : The above method will only work to initialize with 0;
回答6:
Use vector array instead:
vector<vector<int>> array(ROW, vector<int>(COLUMN, 1));