Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Given `int num[7]`, how do `num` , `&num[0]`, `&num` differ?

Tags:

arrays

c

pointers

I read in a C book that for an array num[7] the term num is equivalent to &num[0]. This concept was working fine for me but when I wrote this program shown below I again got confused.

#include<stdio.h>
#include<conio.h>
int main()
{
    int num[]={21,22,23,24,25,26,27};
    int *x,*y,*z;
    x=&num;
    y=num;
    z=&num[0];
    printf("%d   %d   %d\n",sizeof(x),sizeof(y),sizeof(z));
    printf("%d  %d  %d\n",sizeof(&num),sizeof(num),sizeof(&num[0]));
    printf("%d   %d   %d",*(&num),*(num),*(&num[0]));
    getch();
    return 0;  
}

output is:

      4    4    4
      4    28   4
      2293536   21   21

If num is identical to &num[0] then why there is a difference in their size? And what is this third type of term &num? I know it is showing a garbage value but does this type of term makes any sense? z=&num[0] I already understand. The compiler shows a warning for the assignment x=&num, but for y=num; the compiler doesn't have any problems. If num has size 28 then why did it get assigned to an integer pointer y without a typecast?

Then I tried on 2-d array this way:

#include<stdio.h>
#include<conio.h>
int main ()
{
    int s[4][2]={{1234,56},{1235,57},{1236,58},{1237,59}};
    int i
    printf ("\n%d %d %d %d %d",sizeof(s[i]),sizeof(&s[i]),sizeof(s),
        sizeof(s[0][0]),sizeof(&s));
    getch();
    return 0;
}

Now the output is

8  4  32  4   4

Here sizeof(s[i]) is 8. because s[i] is a 1-D array and it has two elements so it's fine. But I don't have any clue what the terms &s[i] and &s mean. And I am again able to see that s is not identical to s[0][0] . I have used Dev C++ 4.9.9.2 version to run all the programs. I want to be clear in these three type of terms.

like image 224
melyfony Avatar asked Aug 27 '11 20:08

melyfony


2 Answers

Good questions here. Hopefully we can all explain these issues for you.

Given

int num[]={21,22,23,24,25,26,27};

Then

  • num has type int[] because it is a declared array of integers whose memory is allocated in place. Note that it does not have the type int*, which would have been the case if you malloced it.
  • sizeof(num) is 28 because num is an array of 7 ints, which on your machine are 4 bytes in size. The value would be 56 if ints were 8 bytes or 14 if they had 2 bytes, but 4 bytes per integer is most common.
  • &num[0] is a pointer, of type int*, whose value is the address of the first element of num.
  • The sizes of x and friends are 4 because they are declared as pointers, which on your machine, under your C compiler, pointers are allocated in 4 bytes.

The thing to keep in mind is that when an array is used in certain contexts, like being passed as a parameter, it is converted to an int*. That is why you can say *num and get 21. Tricky, but that's how it is. That is why one can usually interchange num and &num[0] but you really should keep the distinction in mind, because as you noticed, the sizeof values differed.

The conversion is why y = num makes sense. y has type int* and in C you get an automatic conversion from int[] TO int*. You can't do x = &num because the type of &num is "pointer to int array." You cannot assign that to an int* (pointer to int).

In the case of

int s[4][2]={{1234,56},{1235,57},{1236,58},{1237,59}};

We have the type of s as int[][], the type of &s as pointer to int[][] and the type of &s[i] as pointer to int[] (because s[i] is an int array). Because of the way C allows you assign/pass arrays to pointers you can play the same kind of games as in your first example.

You will notice that s, &s[0] and &s[0][0] all point to the same memory locations, but, as you noticed, the sizeof values will be different.

like image 168
Ray Toal Avatar answered Nov 16 '22 00:11

Ray Toal


Your contradictions are valid. It is not the case that num is equivalent to &num[0]. That's simply false. Arrays are a distinct type from pointers, and num refers to an object with the type int[7], not int*. That's why the size is different, for example, because one is a contiguous collection of seven integers.

Note that if the need be, num may be converted to an int*, with the value &num[0]. A conversion is not the same as equivalence, of course. You'll find this confusion between arrays and pointers oddly prominent, because people keep repeating the falsity that arrays are pointers. They aren't.

like image 3
GManNickG Avatar answered Nov 16 '22 00:11

GManNickG