Pourquoi ne puis-je attribuer un tableau à pointeur directement en C?

voix
7

J'ai le programme suivant. Cependant, je ne comprends pas pourquoi je dois passer l'adresse du tableau. Quand ils sont à la fois pointant vers la même adresse. Quelle est l'adresse du premier élément du tableau de int de.

Je reçois un avertissement quand je tente de faire cette « cession de type pointeur incompatible »:

ptr = var;

Le code source complet:

void print_values(int (*ptr)[5])
{
    size_t i = 0;
    for(i = 0; i < 5; i++) {
        printf(%d: [ %d ]\n, i, (*ptr)[i]);
    }
}

int main(void)
{
    /* declare a pointer to an array integers */
    int (*ptr)[5] = NULL;
    /* array of integers */
    int var[] = {1, 2, 3, 4, 5};
    /* assign the address of where the array is pointing to (first element) */
    ptr = &var;
    /* Both are pointing to the exact same address */
    printf(var  [ %p ]\n,(void*)var);
    printf(&var [ %p ]\n, (void*)&var);

    print_values(ptr);
    return 0;
}

Je compile le code avec gcc 4.4.4 c89 -Wall -Wextra -O0

Créé 17/08/2010 à 17:03
source utilisateur
Dans d'autres langues...                            


4 réponses

voix
17

Il est une question purement de type.

Dans la plupart expression contextes , le nom d'un tableau (comme var) se désintègre en un pointeur sur l'élément initial de l'ensemble, et non pas un pointeur sur le tableau. [Notez que cela ne signifie pas que varest un pointeur - très bien est pas un pointeur - il vient se comporte . Comme un pointeur vers le premier élément du tableau dans la plupart des expressions]

Cela signifie que , dans une expression vardécroît normalement à un pointeur vers un int, et non pas un pointeur vers un tableau de int.

Comme l'opérande de l'adresse de l' opérateur ( &) est un contexte où cette règle de décroissance ne s'applique pas (l'autre étant comme opérande de l' sizeofopérateur). Dans ce cas , le type de &vardérive directement à partir du type de varsorte que le type est pointeur de tableau de 5 int.

Oui, les pointeurs ont la même valeur d'adresse (l'adresse d'un premier élément tableau est l'adresse du tableau lui - même), mais ils ont différents types ( int*vs int(*)[5]) ne sont donc pas compatibles dans l'attribution.

ISO / IEC 9899: 1999 6.3.2.1/4:

Sauf quand il est l'opérande de l' sizeofopérateur ou le unaire &opérateur, ou est un littéral chaîne utilisée pour initialiser un tableau, une expression qui a le type « réseau de Type » est converti en une expression de type « pointeur de type » qui pointe vers l'élément initial de l'objet de réseau et n'a pas une lvalue. ...

Créé 17/08/2010 à 17:09
source utilisateur

voix
4

C est un langage fortement typé. Lorsqu'une fonction attend un paramètre de type int *, vous devez passer un argument de type int *. Non double *, non char *, mais int *. Même si l'adresse numérique réelle de ces double *ou char *est « le même » que celui que vous voulez passer, il ne change toujours rien - vous avez encore passer un int *. La langue que vous interdit de passer la valeur du mauvais type.

C'est exactement ce qui se passe dans votre cas. La fonction prend un paramètre de type int (*)[5]. Cela signifie que vous devez passer l'argument de ce type. Le passage d' un int *lieu n'est pas autorisé. Si l'adresse est la même ne fait aucune différence.

Créé 17/08/2010 à 17:22
source utilisateur

voix
3

varest lui - même un (*int)pointage au premier élément dans votre tableau. Pointeurs et tableaux dans C très similaires. Changer int (*ptr)[5] = NULL;de int* ptr = NULL;et ptr = &var;àptr = var;

Créé 17/08/2010 à 17:09
source utilisateur

voix
1

D'après ce que je peux vous dire assignez un pointeur de tableau ( var) à un pointeur qui pointe vers un pointeur de tableau ( (*ptr)[5]), donc c'est la raison pour laquelle vous obtenez cet avertissement.

Au lieu de cela, essayez d'utiliser

int *ptr = NULL;
Créé 17/08/2010 à 17:10
source utilisateur

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more