Dado `int num [7]`, ¿en qué se diferencian `num`,` & num [0] `,` & num`?

I read in a C book that for an array num[7] el termino num es equivalente a &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;  
}

la salida es:

      4    4    4
      4    28   4
      2293536   21   21

If num es idéntico a &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, pero para y=num; the compiler doesn't have any problems. If num tiene tamaño 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;
}

Ahora la salida es

8  4  32  4   4

Aquí sizeof(s[i]) is 8. porque 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] y &s mean. And I am again able to see that s no es idéntico a 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.

preguntado el 27 de agosto de 11 a las 20:08

Read the C FAQ that has an entire section dedicated to this issue: c-faq.com/aryptr/index.html -

@good question for the beginners ! buddy -

4 Respuestas

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

Dado

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

Entonces

  • num tiene tipo int[] because it is a declared array of integers whose memory is allocated in place. Note that it does no tener el tipo int*, which would have been the case if you malloced it.
  • sizeof(num) es 28 porque 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*, ¿De quién VALORAMOS is the address of the first element of num.
  • Los tamaños de 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 y &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 tiene sentido. y tiene tipo int* and in C you get an automatic conversion from int[] A 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).

En el caso de los

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

We have the type of s as int[][], el tipo de &s as pointer to int[][] y el tipo de &s[i] como puntero a int[] (porque 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.

Notarás que s, &s[0] y &s[0][0] all point to the same memory locations, but, as you noticed, the sizeof values will be different.

Respondido 28 ago 11, 00:08

@pst, right, I made too many assumptions. It contains 7 four-byte integers. Yes, the OP could be on a machine with different sized ints. - Ray Toal

Your contradictions are valid. It is no el caso que num es equivalente a &num[0]. That's simply false. Arrays are a distinct type from pointers, and num refers to an object with the type int[7]no, 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*, con el valor &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.

Respondido 28 ago 11, 00:08

Now my question is if num is identical to &num[0] then why there is a difference in there size?

num es una matriz. sizeof has a sometimes surprising behavior for arrays which is that it tells you the storage size of the whole array if you pass it an actual array, but it only tells you the size of a pointer to an element in the array if you pass it the address of such an element. This can lead to confusion because the array name degrades to a pointer in function calls.

Entonces, la respuesta es que num no es idéntico a &num[0] - the latter is the address of the first element of num, with any information about the total size of the array removed. These two things are interchangeable in many contexts, such as calling actual functions, but not when calling sizeof (which is not a function, but a special keyword handled by the compiler).

Respondido 28 ago 11, 00:08

Wow, that's a lot of questions in one go :P

First I'll try to explain this output to you:

  4    4    4
  4    28   4
  2293536   21   21

sizeof() is a unary operator in c. It is replaced by an integer when the code is compiled, not at runtime. So the compiler literately changes your printfs to:

 printf("%d   %d   %d\n", 4, 4, 4);
 printf("%d  %d  %d\n", 4, 28, 4);
 printf("%d   %d   %d",*(&num),*(num),*(&num[0]));

In a very early stage in the compilation.

The compiler is kind enough to give you the size of the entire array when you write sizeof(num). That's how sizeof is defined to work on arrays. All the other elements give you the size of an (int *) except sizeof (&num) which gives you the size of an (int **) (an int ** is the same size as an int * anyways).

  • &num is the memory location of the pointer to your array
  • num, and &num[0], is the memory location of the first int in your array

For your second question;

printf("\n%d %d %d %d %d",sizeof(s[i]),sizeof(&s[i]),sizeof(s),sizeof(s[0][0]),sizeof(&s));

 

sizeof(s[i]) - size of an array (int[2]) == 8
sizeof(&s[i]) - size of a pointer to an int array sizeof(int **) == 4
sizeof(s) - size of a 2D array containing 8 ints == sizeof(int[8]) == 32
sizeof(s[0][0]) - size of an int === 4
sizeof(&s) - size of a pointer to an array == 4

Respondido 28 ago 11, 05:08

No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas or haz tu propia pregunta.