2012-06-24 7 views
5

Tengo un ejemplo que implica un puntero a una matriz 2D. ¿Alguien puede ayudarme a entender lo que está sucediendo en este ejemplo?Array 2D y puntero en C: cómo acceder a los elementos?

int main() 
{ 

    int i = 0, j=0, sum0=0, sum1=0; 
    int data[4][3] = { {23,55,50},{45,38,55},{70,43,45},{34,46,60}}; 
    int *Ptr; 
    Ptr = *data; //Why is the indirection operator used here? 
        // Does Ptr = 23 by this assignment? 

    for (i=0; i<4; i++) { 
     sum1 = 0; 
     for (j = 0; j < 3; j++) { 
      sum1 += data[i][j]; 
     } 
     if (sum1 > sum0) { 
       sum0 = sum1; 
       Ptr = *(data + i);  // Seems like this statement makes Ptr 
     }        // point one row below ... what syntax 
    }         // can you use to access columns then? 
             // Is it possible to use pointer arithmetic 
    for (i=0; i<3; i++)     // to access elements of data[i][j] that 
     printf("%d\n", Ptr[i]);   // are not at j = 0? 

    return 0; 
} 
+0

¿Esto es [etiqueta: tarea]? – Alexander

+0

¡Sip! Estaba tomando un curso introductorio de CS y este fue solo un ejemplo dado en mis notas de clase. – shafools

Respuesta

13

data es una matriz de 2 dimensiones, que tiene 4 filas y cada fila tiene 3 elementos (es decir, 4 X 3).

Ahora, Ptr = *data; significa que está almacenando la dirección de inicio de la 1ª fila en la variable de puntero Ptr. Esta declaración es equivalente a Ptr = *(data + 0). Ptr = *(data + 1) - esto significa que estamos asignando la dirección inicial de la 2ª fila.

Luego *Ptr o *(Ptr + 0) le dará el valor del primer elemento de la fila a la que apunta. Del mismo modo, *(Ptr + 1) le dará el valor del segundo elemento de la fila.

El ciclo for en su programa se utiliza para identificar qué fila tiene el valor máximo de la suma de sus elementos (3 elementos). Una vez que el control sale de ese bucle for, Ptr apunta a la fila que tiene la suma máxima de sus elementos y sum0 tendrá el valor de la suma.

Considere una matriz int a[5];, espero que sepa que a[0] y 0[a] es lo mismo. Esto es porque a[0] significa *(a+0) y 0[a] significa *(0 + a). Esta misma lógica se puede usar en una matriz bidimensional.

data[i][j] es similar a *(*(data + i) + j). Podemos escribirlo como i[data][j] también.

Para obtener más información, consulte el libro "comprensión de punteros en c" por yashwant kanetkar.

1

data es una matriz de matrices 3 de elementos de números enteros. En contextos que esperan un "puntero a foo", puede usar una "matriz de foo" y se comportará como un puntero a su primer elemento, por lo que *data es un puntero al primer elemento de data, es decir (por así decirlo) {23,55,50}.

Entonces, la respuesta a la primera pregunta en los comentarios: No, no es verdad que Ptr = 23. (No podía ser; Ptr es un int * y 23 es una int.)

Tiene razón en que Ptr = *(data+i) hace Ptr punto a la i ª fila de data. Más precisamente, data es una matriz de matrices de 3 elementos de int, que se comporta como un puntero a matrices de 3 elementos de int; agregando i a él se mueve más allá de i tales arrays.

La forma habitual de acceder a otras columnas de la matriz es la indexación ordinaria de matrices. Si se refiere al data[i][j], obtendrá la columna j de la fila i. Si desea hacerlo con aritmética de puntero explícito, observe que (por ejemplo) Ptr en el código de ejemplo es de tipo "puntero a entero", por lo que Ptr+1 (por ejemplo) es el elemento 1 de la fila a la que apunta Ptr. (Pero, como una cuestión de estilo, generalmente no debe hacer una aritmética de puntero explícita cuando no la necesita).

0

En su ejemplo, el ciclo recorre todas las filas de la matriz para encontrar aquella cuya suma de todos los elementos tiene el valor máximo

Al principio se le asigna un puntero a la primera fila:

Ptr = *data; 

Lo que significa que lo siguiente es cierto:

(Ptr[0] == 23 && Ptr[1] == 55 && Ptr[2] == 50) 

en cuenta que Ptr es un puntero para que se mantenga una dirección de memoria, por lo tanto Ptr es diferente de (a menos que la dirección de memoria sea , que es poco probable que suceda).

4

Ptr = *data; es la abreviatura de *(data+0)+0 que es un puntero para el elemento de la primera columna de la primera fila. el primer 0 agregado con datos es el número de fila, que está indirectamente y nos lleva a la primera fila. * (data+0) sigue siendo una dirección y no un valor al que apunta (para matriz 2D). Entonces, Ptr ahora apunta a la dirección de la primera columna en la primera fila. El segundo cero es la columna no ... Por lo tanto, se elige la dirección de memoria de la primera fila y la primera columna. Usar la indirección (*) de nuevo solo daría valor ahora a la dirección. como * (*(data+0)+0) o **data.

Generalmente, si p es el nombre del indicador, i número de fila y el número de columna j,

  1. (*(p+i)+j) daría una dirección de memoria de un elemento en matriz 2D. yo es la fila no. yj es col. no.,
  2. *(*(p+i)+j) daría el valor de ese elemento.
  3. *(p+i) accedería a la fila ín fila
  4. para acceder a las columnas, agregue el número de columna al *(p+i). Es posible que deba declarar el puntero como (*p)[columns] en lugar de solo *p. Al hacerlo, declaras un puntero a una matriz 2D.

El uso de aritmética de puntero trata a 2d array como 1D array. Inicialice el puntero * Ptr al primer elemento (int *Ptr = *data) y luego agregue un no. (Ptr + n) para acceder a las columnas. Agregar un número más alto que el número de columna simplemente continuaría contando los elementos de la primera columna de la siguiente fila, si eso existe.

Cuestiones relacionadas