nalzok
nalzok

Reputation: 16107

Why the value of this matrix element is unknown?

This is a question on my exercise book:

If we write int a[][3]={{0},{1},{2}};, the value of the element a[1][2] will be ____.

The key says its value cannot be known. Since the statement are not granted to be written outside a function, the matrix should not be simply seen as a global variable, which initializes all elements to 0. However, I suppose the initializer {{0},{1},{2}} is equivalent to {{0,0,0},{1,0,0},{2,0,0}}, so a[1][2] should be 0. Who is wrong, the key or me?

PS: I wrote this code:

#include <stdio.h>

int main()
{
    int a[][3]={{0},{1},{2}};
    printf("%d",a[1][2]);
    return 0;
}

And its output is exactly 0.

Upvotes: 2

Views: 57

Answers (4)

Lundin
Lundin

Reputation: 213513

The problem is that C has lax rules for how the braces should be interpreted, the braces do not specify how many items there are in each array. So you will end up with an array of int [3][3]; which may or may not be what you expected.

According to the rules of array initialization, the items in each array that are not initialized explicitly, will get initialized as if they had static storage duration. That is, to zero.

So you are correct and you can easily prove it by printing the raw contents of the memory, like this:

#include <stdio.h>
#include <inttypes.h>
#include <string.h>

void mem_dump (int a[3][3], size_t size);

int main()
{
  int a[][3]={{0},{1},{2}};
  printf("a is initialized like this:\n");
  mem_dump(a, sizeof(a));
  printf("\n"); 

  int rubbish[3][3];
  memset(rubbish, 0xAA, sizeof(rubbish)); // fill up with some nonsense character
  memcpy(a, rubbish, sizeof(a)); // a guaranteed to contain junk.
  printf("a is now filled with junk:\n");
  mem_dump(a, sizeof(a)); 
  printf("\n");

  memcpy(a, (int[][3]){{0},{1},{2}}, sizeof(a)); // copy back the initialized values
  printf("a now contains the initialized values once more:\n");
  mem_dump(a, sizeof(a));

  return 0;
}

void mem_dump (int a[3][3], size_t size)
{
  for (size_t i=0; i<size; i++)
  {
    printf("%.2" PRIx8 " ", ((uint8_t*)a)[i] );

    if( (i+1) % sizeof(int[3]) == 0) // if divisible by the size of a sub array
      printf("\n");
  }
}

Output:

a is initialized like this:
00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00
02 00 00 00 00 00 00 00 00 00 00 00

a is now filled with junk:
aa aa aa aa aa aa aa aa aa aa aa aa
aa aa aa aa aa aa aa aa aa aa aa aa
aa aa aa aa aa aa aa aa aa aa aa aa

a now contains the initialized values once more:
00 00 00 00 00 00 00 00 00 00 00 00
01 00 00 00 00 00 00 00 00 00 00 00
02 00 00 00 00 00 00 00 00 00 00 00

Upvotes: 1

P.P
P.P

Reputation: 121357

Your answer is right and the key is wrong. Rest of the array members that you didn't initialize will be implicitly initialized to 0 and this is guaranteed by the C standard irrespective of whether the array is global or inside a function.

C11, 6.7.9

If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

Upvotes: 2

2501
2501

Reputation: 25752

You are correct, the rest of the values are initialized to default values, 0 in this case.

The relevant quote from the standard:

6.7.9 Initialization

  1. If there are fewer initializers in a brace-enclosed list than there are elements or members of an aggregate, or fewer characters in a string literal used to initialize an array of known size than there are elements in the array, the remainder of the aggregate shall be initialized implicitly the same as objects that have static storage duration.

Upvotes: 5

Some programmer dude
Some programmer dude

Reputation: 409166

Both are right.

If you don't initialize a local non-static variable, it will have an indeterminate value. But you do initialize the a variable, that's what the "assignment" does, it initializes the variable. And if you initialize an array with less values than it's been declared to have, then the rest will be initialized to "zero".

Upvotes: 1

Related Questions