Tableau pour indiquer la désintégration et passer des tableaux multidimensionnels à des fonctions

Je sais qu’un tableau se désintègre en un pointeur, de telle sorte que

char things[8]; 

et plus tard, les things utilisées ailleurs, things est un pointeur sur le premier élément du tableau.

En outre, de ma compréhension, si on déclare

 char moreThings[8][8]; 

then moreThings n’est pas de type pointeur sur char, mais de type “tableau de pointeurs sur char”, car la décroissance ne se produit qu’une fois.

Quand moreThings est passé à une fonction (par exemple avec un prototype de void doThings(char thingsGoHere[8][8]) que se passe-t-il réellement avec la stack?

Si moreThings n’est pas du type pointeur, est-ce vraiment encore un passage par référence? Je suppose que j’ai toujours pensé que moreThings représentait toujours l’adresse de base du tableau multidimensionnel. Et si doThings prenait-il les thingsGoHere entrée thingsGoHere et les transférait-il à une autre fonction?

La règle est-elle que si le nombre d’entrées d’un tableau n’est pas constant, celui-ci sera toujours modifiable?

Je sais que les vérifications de type ne se produisent qu’au moment de la compilation, mais je ne comprends toujours pas ce qui est techniquement considéré comme une passe par référence (c’est-à-dire uniquement lorsque des arguments de type pointeur sont passés, ou si un tableau de pointeurs serait une passe). par référence aussi?)

Désolé d’être un peu partout avec cette question, mais à cause de ma difficulté à la comprendre, il est difficile d’articuler une enquête précise.

Vous vous êtes un peu trompé: moreThings se désintègre également en pointeur sur le premier élément, mais comme il s’agit d’un tableau d’un tableau de caractères, le premier élément est un “tableau de 8 caractères”. Donc, le pointeur décomposé est de ce type:

 char (*p)[8] = moreThings; 

La valeur du pointeur est bien sûr la même que celle de &moreThings[0][0] , c’est-à-dire du premier élément du premier élément, mais également celle de &a , mais le type est différent dans chaque cas.

Voici un exemple si char a[N][3] :

 +===========================+===========================+==== |+--------+--------+-------+|+--------+--------+-------+| || a[0,0] | a[0,1] | a[0,2]

a[1,0] | a[1,1] | a[1,2]|| … |+——–+——–+——-+++——–+——–+——-++ … | a[0] | a[1] | +===========================+===========================+==== a ^^^ ||+– &a[0,0] |+—–&a[0] +——-&a

  • &a : adresse de tout le tableau de tableaux de caractères, qui est un caractère char[N][3]

  • &a[0] , identique à a : adresse du premier élément, qui est lui-même un caractère char[3]

  • &a[0][0] : adresse du premier élément du premier élément, qui est un caractère

Cela démontre que différents objects peuvent avoir la même adresse, mais si deux objects ont la même adresse et le même type, alors ils sont le même object.

“ADRESSE DE RESEAU ET POINTEURS DE RESEAUX MULTIDIMENSIONNELS”

Commençons par le tableau 1-D en premier:

  • Déclaration char a[8]; crée un tableau de 8 éléments.
    Et voici a adresse du premier élément mais pas l’adresse du tableau .

  • char* ptr = a; est une expression correcte, car ptr est un pointeur sur char et peut traiter le premier élément.

  • Mais l’expression ptr = &a est fausse ! Parce que ptr ne peut pas adresser un tableau.

  • & une adresse moyenne du tableau. Vraiment, les valeurs de a et &a sont identiques mais sémantiquement les deux sont différentes, l’un est l’adresse du caractère, l’autre est l’adresse du tableau de 8 caractères.

  • char (*ptr2)[8]; Ici, ptr2 is pointer to an array of 8 chars , et cette fois, ptr2=&a est une expression valide.

  • Le type de données de &a est char(*)[8] et le type a est car char[8] qui se décompose simplement en char* dans la plupart des opérations, par exemple char* ptr = a;

    Pour mieux comprendre la lecture: Différence entre char *str et char str[] et comment les deux se mémorisent?

Deuxième cas,

  • Déclaration char aa[8][8]; crée un tableau 2D de taille 8x8 .

  • Tout tableau à deux dimensions peut également être visualisé en tant que tableau à une dimension, dans lequel chaque élément de tableau est un tableau à une dimension .

  • aa est l’adresse du premier élément qui est un tableau de 8 caractères. L’expression ptr2 = aa est valide et correcte.

  • Si nous déclarons comme suit:

     char (*ptr3)[8][8]; char ptr3 = &aa; //is a correct expression 

    De même,
    moreThings dans votre déclaration caractère char moreThings[8][8]; contient l’adresse du premier élément qui est un tableau de caractères de 8 éléments.

    Pour mieux comprendre, lisez: Différence entre char* str[] et char str[][] et comment les deux se mémorisent?


Il serait intéressant de savoir:

  • morething est une adresse de tableau de 8 caractères.

  • *morething est une adresse de premier élément qui est &morething[0][0] .

  • &morething est une adresse de tableau 2D de 8 x 8.

    Et les valeurs d’adresse de tous les trois ci-dessus sont identiques mais sémantiquement toutes différentes.

  • **morething est la valeur du premier élément qui est morething[0][0] .

    Pour mieux comprendre, lisez: Différence entre &str et str , lorsque str est déclaré comme char str[10] ?

En outre,

  • void doThings(char thingsGoHere[8][8]) n’est rien d’autre que void doThings(char (*thingsGoHere)[8]) et accepte ainsi n’importe quel tableau à deux dimensions, la deuxième dimension étant 8.

A propos du type de variables en C et C ++: (je voudrais append une réponse)

  • Rien n’est passé par référence en C à son concept C ++. Si son utilisé dans C cela signifie que l’auteur parle de variable de pointeur.
  • C prend en charge pass by Address et pass by value .
  • C ++ prend en charge Pass by address , pass by value et aussi pass by Reference .

    Lire: variables de pointeur et variables de référence

À la fin,

  • Le nom d’un tableau est constant identifiant pas variable.

Joliment expliqué par Kerrek,

En plus de cela, nous pouvons le prouver par l’exemple suivant:

 #include  int main () { int a[10][10]; printf (".. %p %p\n", &a, &a+1); printf (".. %p %p \n ", &a[0], &a[0]+1); printf (".. %p %p \n ", &a[0][0], &a[0][0] +1); } 

La sortie est:

 .. 0x7fff6ae2ca5c 0x7fff6ae2cbec = 400 bytes difference .. 0x7fff6ae2ca5c 0x7fff6ae2ca84 = 40 bytes difference .. 0x7fff6ae2ca5c 0x7fff6ae2ca60 = 4 bytes difference. 

& a +1 -> Déplace le pointeur en ajoutant toute la taille du tableau. soit 400 octets

& a [0] + 1 -> Déplace le pointeur en ajoutant la taille de la colonne. c’est-à-dire: 40 octets.

& a [0] [0] +1 -> Déplace le pointeur en ajoutant la taille de l’élément, à savoir 4 octets.

[taille int est de 4 octets]

J’espère que cela t’aides. 🙂