2010-04-19 3 views
1

J'ai le code suivant:Comprendre c-pointeurs pour les lignes de tableau à 2 dimensions

int main() { 
    int n = 3, m = 4, a[n][m], i, j, (* p)[m] = a; 
    for (i = 0; i < n; i++) 
     for (j = 0; j < m; j++) 
      a[i][j] = 1; 
    p++; 
    (*p)[2] = 9; 
    return 0; 
} 

J'ai du mal à comprendre ce que p est ici, et les conséquences des opérations sur p à la fin. Quelqu'un peut-il me donner une brève explication de ce qui se passe? Je sais c-pointeurs dans leurs paramètres simples, mais ici, il devient un peu plus compliqué.

+0

Vous avez besoin d'une étiquette 'homework'? –

+0

@Paul envisager de lire http: //meta.stackexchange.com/questions/34503/should-the-possible-homework-tag-be-decouragé –

+0

Eh bien, c'est un exercice pour un travail de groupe en introduction à la programmation avec Java (et certains de base C). Je suis actuellement l'assistant du cours, mais mon C est plus rouillé que mon Java, donc je suis en train de faire la préparation finale pour la classe. – utdiscant

Répondre

2

a est un tableau de int[m] et p est un pointeur vers int[m]. Il est initialisé à a, qui se désintègre en pointeur vers son premier élément.

Le déréférencement p donne int[m], qui se désintègre en int* (pointeur vers son premier élément). Donc (*p)[2] ajoute 2 au int* qui était le résultat de la désintégration. Donc, il définit le troisième des 4 premiers entiers (int[m], avec m étant 4) à 9.

Ajouter à p avancerait l'adresse stockée dans par unités de sizeof(int[m]) octets, qui lors de l'exécution (depuis m n'est pas une constante de temps de compilation) Equivaut à 4 * sizeof(int). Donc, (*(p+1))[2] accéderait au tiers du second 4 entiers. Au total, p a 3 de tels tableaux de 4 ints pour indiquer: a+0, a+1 et a+2.

Notez que vous avez créé un tableau VLA C99 de longueur variable. Vous devez #definen et m des constantes entières pour se débarrasser de ces VLA (qui ne sont pas tout à fait portable parmi les compilateurs C).

2

p est un pointeur sur un élément 4-int matrices (à savoir un pointeur de pointeur vers int, où la première dimension est de 4 et le second est inconnue). Lorsque vous incrémentez p, il pointe vers le tableau suivant composé de 4 éléments int, c'est-à-dire le cinquième int. Ensuite p est déréférencé avec un décalage 2, ce qui signifie que le septième int changements, donc vous obtenez

1 1 1 1 
    1 1 9 1 
    1 1 1 1 

que l'état final du tableau 4x3.

2

Quelques petites déclarations d'impression doivent préciser ce que ce code fait:

#include <stdio.h> 

int main() { 
    int n = 3, m = 4, a[n][m], i, j, (* p)[m] = a; 
    for (i = 0; i < n; i++) 
     for (j = 0; j < m; j++) 
      a[i][j] = 1; 

    printf("p points to %u, sizeof(int)*m = %d", p, sizeof(int)*m); 
    p++; 
    printf(", p++ points to %u\n", p); 

    (*p)[2] = 9; 

    for (i = 0; i < n; i++) 
     for (j = 0; j < m; j++) 
      printf("a[%d][%d] = %d\n", i, j, a[i][j]); 

    return 0; 
} 

Exemple de sortie:

p points to 2293536, sizeof(int)*m = 16, p++ points to 2293552 
a[0][0] = 1 
a[0][1] = 1 
a[0][2] = 1 
a[0][3] = 1 
a[1][0] = 1 
a[1][1] = 1 
a[1][2] = 9 
a[1][3] = 1 
a[2][0] = 1 
a[2][1] = 1 
a[2][2] = 1 
a[2][3] = 1 

De toute évidence, p est un pointeur vers int[m], donc p++ fera avancer le pointeur vers la la rangée suivante au a. C'est pourquoi (*p)[2] va changer a[1][2]. Si vous n'avez pas incrémenter p, cette ligne changera a[0][2].

Espérons que c'était assez simple !?

Questions connexes