1

Could you explain why in the first program "array[ counter ]" prints values but in the second program "array[ counter ]" prints addresses?

FIRST PROGRAM

main()
{
    int array[ 4 ] = { 1, 2, 3, 4 };
    int counter;
    for( counter = 0 ; counter <= 3; counter++ )
        printf( "%u\n", array[ counter ]);
}

SECOND PROGRAM

main()
{
    int array[ 4 ] [ 1 ]= { 1, 2, 3, 4 };
    int counter;
    for( counter = 0 ; counter <= 3; counter++ )
        printf( "%u\n", array[ counter ]);
}
user3646717
  • 1,095
  • 2
  • 12
  • 21
  • Same if you do: `int* i[4];` `printf("%u", i);` – Edenia Aug 15 '14 at 00:57
  • Because in the first program you have an array of integers and in the second program you have an array of arrays. Change the second program to use array[counter][0] and you'll get the same results for both. – Jim Balter Aug 15 '14 at 01:58
  • 1
    Thanks to all of you!. I understood specially while reading your comment Jim Balter. Array[counter] always prints the values, in the first program the values are the numbers, in the second program the values are the addresses of the inner array wich has numbers. – user3646717 Aug 15 '14 at 03:07
  • BTW, if you compile this with gcc -Wall it will warn you that your initializer in the second program is missing curly braces ... it should be { {1}, {2}, {3}, {4} }. Also instead of `main()` use `int main(void)`, and if you're using a pre-C99 compiler you need to return a value. – Jim Balter Aug 15 '14 at 06:17

6 Answers6

2

In the second example array[counter] isn't a value, it's an array.

When you pass an array as a parameter to a function, it undergoes the array to pointer decay, and therefore you get a pointer to the beginning of the array, rather than the array itself.

Community
  • 1
  • 1
0

In the second case the type of array[counter] is int [1] while in the first case the type of array[counter] is int.

int [1] is an array type and when you print it, it decays to a pointer referring to the start address of this array. That's what you get when you print it.

Eric Z
  • 14,327
  • 7
  • 45
  • 69
  • 1
    Yay, someone got it right! It's depressing how many people are claiming that `array` and `array[count]` are pointers. – Jim Balter Aug 15 '14 at 02:10
0

In the second program, array is a pointer to a pointer to a list of ints. In the first program, array is a pointer to a list of ints.

Thus, when you dereference array in the second program you get a pointer to a list of ints – in other words, you get a memory address. Similarly, when you dereference array in the first program, you get the first element in the list of ints – in other words, a value.

ravron
  • 11,014
  • 2
  • 39
  • 66
  • No, `array` is not a pointer in either case ... please learn the basics of this issue, which gets discussed ad nauseam at SO. Just because an array is converted to a pointer to its first element in expression contexts doesn't mean an array is a pointer. And you have the two programs reversed. – Jim Balter Aug 15 '14 at 02:07
0

Your first example is quite ordinarily printing all four elements of the array in a loop, nothing special to see.


Your second example on the other hand is simply wrong.

This defines an array of 4 array of 1 it:

int array[4][1] = { 1, 2, 3, 4 };

This orders print to output the value of one unsigned, though it gives a int[1] which automatically decays to int*.
That is Undefined Behavior (UB), anything may happen (if ints and int* are the same size, it might even happen to print the pointer).

printf( "%u\n", array[ counter ]);
Community
  • 1
  • 1
Deduplicator
  • 44,692
  • 7
  • 66
  • 118
  • @JimBalter: It's allowed and well-defined as long as the `int` is non-negative. – Deduplicator Aug 15 '14 at 02:11
  • Hmmm ... the standard says "The unsigned int argument is converted to unsigned octal (o), unsigned decimal (u)" ... but under va_arg it says "the behavior is undefined, except for the following cases: one type is a signed integer type, the other type is the corresponding unsigned integer type, and the value is representable in both types ..." ... so I guess you're right. Still, it's bad practice, and "wrong" in that sense. – Jim Balter Aug 15 '14 at 02:23
  • @JimBalter: There's more fun to be had with conversion to some signed integer type... – Deduplicator Aug 15 '14 at 02:27
0

First of all, the following codes means the same thing, since the format string is "%u":
1. printf("%u\n", xxxx);
2. printf("%u\n", (unsigned int)xxxx);

Secondly:
1. The type of array[counter] is "int" in the first program.
2. The type of array[counter] is "int *" in the second program.

Finally:
1. If you convert "int" to "unsigned int", you will get values.
2. If you convert "int *" to "unsigned int", you will certainlly get addresses.

I hope that solved your problem.

  • "First of all" -- wrong; if xxxx isn't an unsigned int, the version without a cast is undefined behavior. "Secondly" -- wrong; the type of array[counter] is int[4]. "Finally" -- wrong; you get undefined behavior. On a machine where ints are shorter than pointers, you will probably get the low-order bits of an address. – Jim Balter Aug 15 '14 at 02:04
  • Correction: the type of array[counter] is int[1] – Jim Balter Aug 15 '14 at 02:11
  • Another correction: `printf("%u\n", xxxx)` is defined *if* xxxx is an int that can be represented as an `unsigned int` ... so it would be undefined if `array` contained negative numbers. Again, it's wrong to say they the two statements mean the same thing. – Jim Balter Aug 15 '14 at 02:27
  • Thanks. You made it much clear. But if ints are shorter than pointers, endianness might also play a role in the convertion of pointers to ints. I just don't know how to verify. – Fuqiang Jiang Aug 16 '14 at 12:59
  • Printing a pointer with %u could produce either the high or low order bits, depending on endianness, but casting a pointer to a shorter int type doesn't depend on endianness, it just uses the low order bits (in practical, existing implementations; the C standard doesn't define the behavior). To verify, you would need access to machines with different endianness. – Jim Balter Aug 16 '14 at 18:46
0

int array[4][1] is equivalent to int *array[4] So you will be getting the address stored in array.

Sparrow
  • 195
  • 2
  • 5
  • 15