quelle est la sortie? S’il vous plaît expliquer, étant donné que je suis un novice en c

int a[3][4] = { 1,2,3,4, 5,6,7,8, 9,10,11,12, }; printf("%u %u %u \n", a[0]+1, *(a[0]+1), *(*(a+0)+1)); 

Temps pour un cours intensif sur les tableaux en C.

Tout d’abord, corrigeons l’initialiseur pour le tableau:

 int a[3][4] = { { 1, 2, 3, 4}, { 5, 6, 7, 8}, { 9, 10, 11, 12} }; 

Ceci définit un tableau à 3 éléments de tableaux à 4 éléments de int . Le type de l’ expression a est “tableau à 3 éléments de tableaux à 4 éléments de int “.

Passons maintenant à la partie induisant des maux de tête. Sauf s’il s’agit de l’opérande sizeof ou des opérateurs unary, ou s’il s’agit d’un littéral de chaîne utilisé pour initialiser un autre tableau dans une déclaration, une expression de type tableau aura son type implicitement converti (“decay”) en un type pointeur.

Si l’expression a apparaît seule dans le code (comme dans une instruction telle que printf("%p", a); son type est converti de “tableau à 3 éléments de tableau à 4 éléments de int ” en “pointeur sur Tableau de 4 éléments de “, ou int (*)[4] . De même, si l’expression a[i] apparaît dans le code, son type est converti à partir de” tableau de 4 éléments de int “( int [4] ) to “pointeur vers int ” ( int * ). Si a ou a[i] sont des opérandes de sizeof ou & , la conversion n’a pas lieu.

De manière similaire, l’indice de tableau est effectué par l’arithmétique de pointeur: l’expression a[i] est interprétée comme si elle était écrite *(a+i) . Vous décalez i éléments de la base du tableau et déréférenciez le résultat. Ainsi, a[0] est identique à *(a + 0) , ce qui correspond à *a . a[i][j] est identique à l’écriture *(*(a + i) + j) .

Voici un tableau résumant tout ce qui précède:

 Le type d'expression se décompose en valeur résultante
 ---------- ---- --------- -----
          a int [3] [4] int (*) [4] Adresse du premier élément du tableau
         & a int (*) [3] [4] n / a Comme ci-dessus, mais le type est différent
         * a int [4] int * Comme ci-dessus, mais le type est différent
       a [0] int [4] int * Comme ci-dessus
     * (a + 0) int [4] int * Comme ci-dessus
       a [i] int [4] int * Adresse du premier élément de la iième sous-masortingce
     * (a + i) int [4] int * Comme ci-dessus
      & a [i] int (*) [4] n / a Comme ci-dessus, mais le type est différent
      * a [i] int n / a Valeur du 0ème élément du ième sous-tableau
    a [i] [j] int Valeur du ième élément du ième sous-tableau
  * (a [i] + j) int Comme ci-dessus
 * (* (a + i) + j) int Comme ci-dessus

Espérons que cela devrait vous donner tout ce dont vous avez besoin pour comprendre ce que devrait être la sortie. Toutefois, la déclaration printf doit être écrite comme suit:

 printf("%p %d %d\n", (void *) a[0]+1, *(a[0]+1), *(*(a+0)+1)); 
 $ gcc -Wall -o output output.c output.c: In function 'main': output.c:5:5: warning: missing braces around initializer [-Wmissing-braces] output.c:5:5: warning: (near initialization for 'a[0]') [-Wmissing-braces] output.c:9:5: warning: format '%u' expects argument of type 'unsigned int', but argument 2 has type 'int *' [-Wformat] 

parce que le tableau à 2 dimensions est initialisé comme s’il n’avait qu’une dimension.

Programme complet, pour référence:

 #include  int main() { int a[3][4] = {1,2,3,4, 5,6,7,8, 9,10,11,12, }; printf ("%u %u %u \n", a[0]+1, *(a[0]+1), *(*(a+0)+1)); return 0; } 

Tout d’abord, votre initialisation est fausse: votre initialiseur le spécifie pour un tableau à une dimension, alors que vous en déclarez un à deux dimensions.

Deuxièmement, voyons ce que votre code fait.

a est un tableau à deux dimensions, donc a[0] est de type int[4] (tableau à une dimension) et représente la 0-ème colonne du tableau multidimensionnel, et est (généralement) identique à un pointeur sur l’élément principal de la colonne. Maintenant, vous utilisez l’arithmétique d’adresses: a[0] + 1 est le pointeur sur l’élément après le premier dans la 0ème colonne (représenté par un pointeur sur celui-ci), c’est-à-dire un pointeur sur le 1ier élément e colonne. C’est là que le deuxième avertissement apparaît, indiquant que votre argument pour printf est int* et non unsigned int .

Ensuite, *(a[0]+1) déréférence le pointeur sur le 1 er élément de la 0 e colonne. Ceci est (comme d’habitude) équivalent à a[0][1] .

Ensuite, *(*(a+0)+1)) est identique, car *(a+0) est identique à a[0] .

(Pour comprendre tout cela, vous devez connaître quelques bases: en C *(x + y) est identique à x[y] , et que le tableau à une dimension est essentiellement le même que le pointeur sur son premier élément.)

À propos de la différence entre votre livre et la réalité: la première valeur de sortie est simplement un pointeur; il peut donc s’agir d’une valeur arbitraire, en fonction de l’emplacement de votre tableau dans la mémoire. En ce qui concerne les deux autres valeurs, la question dépend de la manière dont le tableau a été rempli par le mauvais initialiseur.