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?
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".
As for how to initialize the whole array to a specific value/values, see https://stackoverflow.com/a/13488596/584518.
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
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;
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;
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?
Use vector array instead:
vector<vector<int>> array(ROW, vector<int>(COLUMN, 1));
char grid[row][col];
memset(grid, ' ', sizeof(grid));
That's for initializing char array elements to space characters.
Related
I'm relatively new to C programming and I stumbled upon a for me unexplainable behaviour while running the following code and debugging it using gdb and lldb.
In short: When swapping the indices i and j (max i != max j) when accessing a value in a two-dimensional Array inside a double nested for-loop it does not seem to matter if I access the value using array[i][j] or array[j][i].
The two loops and arrays are mostly identical.
unsigned matrix[3][1] =
{
{3},
{4},
{5}
};
//Loop1
for (size_t i = 0; i < sizeof(matrix) / sizeof(*matrix); i++)
{
for (size_t j = 0; j < sizeof(matrix[i]) / sizeof(*matrix[i]); j++)
{
matrix[i][j] <<= 1;
printf("matrix[%zu][%zu] has the value: %d\n", i, j, matrix[i][j]);
}
}
//same two dimensional array as matrix
unsigned matrix2[3][1] =
{
{3},
{4},
{5}
};
//Loop2, basically the same loop as Loop1
for (size_t i = 0; i < sizeof(matrix2) / sizeof(*matrix2); i++)
{
for (size_t j = 0; j < sizeof(matrix2[i]) / sizeof(*matrix2[i]); j++)
{
//swapped i and j here
matrix2[j][i] <<= 1;
printf("matrix2[%zu][%zu] has the value: %d\n", j, i, matrix2[j][i]);
}
}
Am I missing here something?
In both cases i is passed the value 2 at the end of the outer loop and j the value 0 at the end of the inner loop.
Intuitively, matrix[0][2] should throw an exception as each row only has one element.
I will take a slightly different approach than the other respondents.
You are technically not reading outside of the array's boundary as far as the memory layout is concerned. Looking at it from a human perspective you are (the index [0][2] doesn't exist!), but the memory layout of the array is contiguous. Each of the "rows" of the matrix are stored next to each other.
In memory, your array is stored as: | ? | 3 | 4 | 5 | ? |
So when you index to matrix[1][0] or matrix [0][1] you are accessing the same position in memory. This would not be the case if your array was larger than 1 dimension wide.
For example, replace your array with the following one and experiment. You can access integer '4' either by indexing matrix[0][2], or matrix [1][0]. The position [0][2] shouldn't exist, but it does because the memory is contiguous.
unsigned matrix[3][2] =
{
{3, 6},
{4, 8},
{5, 10}
};
Oops, matrix[0][2] should throw an exception as each row only has one element...
Some languages do warn the programmer by an exception if they try an out of bound access, but C does not. It just invokes Undefined Behaviour. On a technical point of view, it means that the compiler does not have to test the out of bound condition. On an operational point of view, it means that anything can happen, including expected behaviour... or an immediate crash... or a modification of an unrelated variable... or...
If my C skills aren't mega-rusty you're reading "unsafe memory".
Essentially your matrix is declared as a block of bytes. After that block of bytes there are more bytes. What are they? Usually more variables that are declared as your program's data. Once you reach the end of the program's data block you reach the user code memory block (encoded ASM instructions).
Most languages perform checks and throw an exception when you run out of bounds by somehow keeping track of the last index that is valid to access. C does not do that and doing such thing is your very own responsibility. If you aren't careful you might be overwriting important parts of your program's code.
There are attacks that one can perform on C programs that don't sanitize user input, like a buffer overrun; which exploits what it's been described.
Essentially if you declare a char[] of length N and store a string that comes from outside and this string happens to be of length N+X you'll be overwriting program memory (instructions).
With the right sequence of characters you can inject your very own assembly code into a running program which doesn't sanitize user input
As your array is int and all elements are of the same size, i don't see any problem as your array is stored in contiguous space in RAM and you use a special case of matrix where inverting indexes has no side effect.
In the first loop your indexes are [0][0], [1][0], [2][0]
In the second loop your indexes are [0][0], [0][1], [0][2]
now try to linear the access, as your array is saved as linear array into the RAM.
address of element = row * NCOL + col
row: is row number
NCOL: number of columns into your matrix
col : the column number
so the linear index for :
[0][2] ==> 0 * 1 + 2 = 2 /* the third element*/
[2][0] ==> 2 * 1 + 0 = 2 /* always the third element */
But if you use a matrix of n x m , n >= 1 and m > 1 and n != m.
if you inverse the indexes, the result will not be the same.
so if you take a 4 x 2 matrix
linear index of [3][1] = 3 * 2 + 1 = 7
linear index of [1][3] = 1 * 2 + 3 = 5 /* even [1][3] is out of the range of your matrix index */
[1][3] you will manipulate the element [2][1]
So be worry when manipulating matrix indexes.
My array is:
int array[100];
If I initialize the first n elements (n < 100) with integers including 0, and the rest is uninitialized, how do I calculate n?
I tried a normal while loop with the following codes:
int i = 0;
int count = 0;
while (a[i++])
count++;
However, the problem with these codes is that it doesn't count the element of value 0 (it takes 0 as FALSE). How do I overcome this problem?
UPDATE: below is the background of this question
I have the following code:
int a[100];
int i;
for (i = 0; i < 100; i++)
scanf("%d", &a[i]);
If I have to input (just an example):
1 0 1 0 1 *
Then the first 5 elements of the array will be: 1 0 1 0 1. The rest will be uninitialized. In this situation, how do I count the number of these initialized elements to get 5?
If you can't simply record how many elements have been initialized, then you need to use a "magic" value like INT_MIN (the largest negative int) to know when an element is not used. Alternatively, instead of storing ints, store something like this:
struct element {
int value;
int flags; // 0 means not used
};
Oh, one more idea: store the count of initialized elements in the first element. This is sort of how malloc() works sometimes. Then you can make the array have 101 elements and pass (array + 1, array[0]) to functions which expect an array of size 100.
void doSomething()
{
int hist[5] = { 0 };
int num_bins = 5;
int indices[10] = { 0, 0, 2, 3, 3, 3, 3, 4, 4, 4 };
int num_indices = 10;
int i;
for (i = 0; i < num_indices; i++)
{
hist[indices[i]]++;
}
for (i = 0; i < num_bins; i++)
{
printf("%d ", hist[i]);
}
printf("\n");
}
Assume I have correct libraries this is a conceptual question from class. I am wondering how the answer comes out to 2 0 1 4 3 for the array.
The line
hist[indices[i]]++
Says "go to the element of the hist array at index indices[i], then increment it." If you think of the array as a list of counters, this says to increment the counter at position indices[i].
This code builds a histogram of the frequencies of various numbers in an array. The idea behind the above code is to iterate over the array and increment the frequencies of each element.
Hope this helps!
The elements in indices range from 0 to 4, which are all valid index of the 5 elements array hist. (That's why the array is named indices, as it's for indexing)
So for instance, i is 2, then indices[i] is 2.
hist[indices[i]]++;
is equivalent to
hist[2]++;
For small questions like this you should try to write down the state of every element of each array on a piece of paper and execute your code step by step. You could also write the code to print useful information in runtime.
If after that you still can't figure it out then it's worth asking here. Otherwise you won't be learning much.
This program increments the 0's in
hist
as it indexes appear in
indices[10]
eg.
when you have the first for interation
hist[indices[0]]++ // hist[0]++ --> 0++;
It looks like "2 0 1 4 3" is a count of how many items exists in the array. 2 0's, 0 1's, 1 2, 4 3's and 3 4's. So the query is counting how many instances of each number are in the array and then printing out that result.
So the statement:
hist[indices[i]]++
find the value of indices[], then increments the int in the hist[] array by 1 giving you a count of how many of those elements are in the array.
1.As you have partially initialized your array, compiler sets other values to 0
2.hist[indices[i]]++; this statement increments the value of hist[i], for the current value of i
3.the value of i is denoted by your array indices[]
4.try having values grater than 5 in your array named indices[].
C99 provides a feature to initialize arrays by using both element-by-element & designated
method together as:
int a[] = {2,1,[3] = 5,[5] = 9,6,[8] = 4};
On running the code:
#include <stdio.h>
int main()
{
int a[] = {2,1,[3] = 5,[0] = 9,4,[6] = 25};
for(int i = 0; i < sizeof(a)/sizeof(a[0]); i++)
printf("%d ",a[i]);
return 0;
}
(Note that Element 0 is initialized to 2 and then again initialised by designator [0]
to 9)
I was expecting that element 0(which is 2) will be replaced by 9(as designator [0] = 9)
and hence o/p will become
9 1 0 5 4 0 25
Unfortunately I was wrong as o/p came;
9 4 0 5 0 0 25
Any explanation for unexpected o/p?
Using designated initializers combined with element initializers implies positions based on the designated initializers.
So if you were to do:
int a[] = {2, 1, [3] = 5, 6};
The result ought to be:
2 1 0 5 6
Not:
2 1 0 6
Note that 6 occupies position 3 in the initializer, but its resulting position is implied by the preceding designated initializer (which uses position 3). The position following the one used by the designated initializer is 4, so that is where the 6 is placed.
The process of initializing an array with an initializer is basically:
set the index counter to 0, and initialize the entire array to 0s
go through the initializer elements from left to right
if the initializer element has a designated index, set the index counter to the designated index
store the initializer element value at the index given by the index counter
increment the index counter
go back to step 3 if there are any more initializer elements.
If you have an array in C, how can you find out how much of it is filled?
In a C array, any element is an object. It's not like in Java where you have references that first have to be assigned to point to objects. Anything in C behaves like a primitive type in Java.
If you have an array of pointers in C, you may view this similar to how things in Java work. You can use null pointers to designate "is not filled to point to an object":
// creates an array of 10 pointers, and initializes all of
// them to null pointers. If you leave off "{ 0 }", you
// have to manually initialize them!
struct foo *array[10] = { 0 };
Then you can simply test with
if(array[i] == 0) {
printf("Position %d does not point to an object!\n", i);
}
You need to keep track of this yourself. There is no concept of "full" (or anything in between for that matter): you have to define this.
Of course if the elements are contiguous in the array, you could use a NULL element to signify the "end" of the array thus defining a "full" state at the same time.
It's all filled, so the answer is whatever the size of your array is. An array is a contiguous memory segment, so it is filled by default with whatever was at that memory location before.
But you probably want to know how much of it is filled with data that you care about, and not with random data. In that case, there is no way of knowing that unless you keep track of it yourself.
I agree with other answers, but I can suggest you a way to make your work easier. You can manage the array like an object and control the adding and the removing of data. If you implement two functions, one to add elements and one to remove them, with the proper logic to manage fragmentation and multi-threading, you can track the number of elements into the array reading a counter, which is written only by add and remove function. So you don't have to execute a loop every time you need to count the elements.
From the C language perspective, there is no concept of "filled". Once an array is defined, memory is allocated to it. For arrays like array1 (see example below), elements get initialized to 0. However, for arrays like array2, the elements can have random value.
So, the notion of "filled" has to be supplied by the program. One possible to "in-band" way is to:
(a) Choose one specific value of the element type (e.g. 0xFFFFFFFF) and use it to detect fill/empty property of each array element (However, realize that this approach takes away one otherwise valid value from the element set.), and
(b) "initialize" all the elements of the array to that disallowed value at suitable position in the program scope.
(c) To find array fill level, count the number of valid elements.
$ cat t2.c
#include <stdio.h>
#define N 10
typedef unsigned long int T;
static const T EmptyElementValue = 0xFFFFFFFF;
// Choose any suitable value above. However, the chosen value
// would not be counted as an "empty" element in the array.
static T array1[ N ];
void
printArray( T a[], size_t length )
{
size_t i;
for( i = 0; i < length; ++i )
{
printf( "%lu, ", a[ i ] );
}
printf( "\n" );
}
size_t
numFilledElements( T a[], size_t length )
{
size_t fillCount = 0;
size_t i;
for( i = 0; i < length; ++i )
{
if( a[ i ] != EmptyElementValue )
{
fillCount += 1;
}
}
return fillCount;
}
int main()
{
T array2[ N ];
size_t i;
printArray( array1, N );
printArray( array2, N );
//------------------------------------------//
// Make array2 empty
for( i = 0; i < N; ++i )
{
array2[ i ] = EmptyElementValue;
}
// Use some elements in array2
array2[ 2 ] = 20;
array2[ 3 ] = 30;
array2[ 7 ] = 70;
array2[ 8 ] = 80;
printf( "Number of elements \"filled\" in array2 = %u\n",
numFilledElements( array2, N ));
// Stop using some elements in array2
array2[ 3 ] = EmptyElementValue;
printf( "Number of elements \"filled\" in array2 = %u\n",
numFilledElements( array2, N ) );
return 0;
}
$ gcc -Wall t2.c -o t2
$ ./t2
0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 60225, 2280452, 1627469039, 1628881817, 2281060, 2280680, 1628304199, 1628881818, 47,
Number of elements "filled" in array2 = 4
Number of elements "filled" in array2 = 3
$
Subtract the number of empty elements from the size of the array. ;-)
Sorry, there is no way (except you keeping track), to tell whether an array element has been modified.
in C, there is no built-in way of knowing how many elements are filled with data that you care about. You will need to build it yourself. As was previously said, if you can have a value that will not represent anything(0 for example), you could :
Count the elements that do not have this undefined value.
If your filled elements will be in the same block of memory, you can look for the undefined value(Sentinel)
On the other hand, if you need the extent of your data to be represented, You will need a flag array that will keep track of the elements that are set and those that aren't :
For example, if you have an array of 32 elements or less, you only need an unsigned integer to keep track of your array:
1100010 ...
Values:
1 -> Set
2 -> Set
3 -> no set
4 -> not set
5 -> not set
6 -> set
etc.
So Whenever you are filling an element you call the function that sets the correct bit and when you are "unfilling" the data you unset the bit that corresponds to it.
Once this is done, All you would need to do is simply call a popcount over the flag array.
You could do a while(yourArray != NULL)loop and through the loop just increment an integer value and that should tell you.