2010-08-17 10 views
7

Tengo el siguiente programa. Sin embargo, no puedo entender por qué tengo que pasar la dirección de la matriz. Cuando ambos están apuntando a la misma dirección. Cuál es la dirección del primer elemento de la matriz de int.¿Por qué no puedo asignar una matriz al puntero directamente en C?

recibo una advertencia cuando intento hacer esto "asignación de tipo de puntero incompatible":

ptr = var; 

código fuente completo:

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; 
} 

puedo compilar el código con gcc 4.4.4 c89 -Wall -Wextra -O0

+0

Traté de volver a escribir su título, ya que no tenía sentido. Por favor, verifique si seleccioné la esencia de su problema correctamente. –

+0

Creo que su título suena mejor que el mío. Gracias. – ant2009

+0

El fragmento de código compila bien. ¿Quiere decir que obtendría un error si agrega 'ptr = var' a main? –

Respuesta

17

Es simplemente un problema de tipo.

En la mayoría de contextos de expresión, el nombre de una matriz (como var) se desintegra a un puntero al elemento inicial de la matriz, no a un puntero a la matriz. [Tenga en cuenta que esto no implica que var es un puntero - que es mucho no un puntero -. que sólo se comporta como un puntero al primer elemento de la matriz en la mayoría de las expresiones]

Estos medios que en una expresión var normalmente se desintegra a un puntero a int, no a un puntero a una matriz de int.

Como el operando del operador de dirección (&) es un contexto donde esta regla de caída no se aplica (la otra es como operando del operador sizeof). En este caso, el tipo de &var se deriva directamente del tipo de var, por lo que el tipo es un puntero a una matriz de 5 int.

Sí, los punteros tienen el mismo valor de dirección (la dirección de un primer elemento de matrices es la dirección de la matriz), pero tienen tipos diferentes (int* frente a int(*)[5]) por lo que no son compatibles en la tarea.

ISO/IEC 9899: 1999 6.3.2.1/4:

excepto cuando es el operando del operador sizeof o la unario & operador, o es una cadena literal utilizado para inicializar una matriz, una expresión que tiene tipo "matriz de tipo" se convierte en una expresión de tipo "puntero a tipo" que apunta al elemento inicial del objeto de matriz y no es un valor l. ...

+0

Pensé que las matrices solo se descomponen en punteros cuando se llaman en una función. entonces en la expresión int arr [5] = {1,2,3,4,5}; int * ptr = arr; ¿El arry decaería en un puntero cuando se asigna a un puntero? – ant2009

+0

@robUK: No se trata solo de llamadas a funciones, sino de la mayoría de los contextos de expresión en los que se produce el deterioro. La matriz decae cuando se usa para inicializar un puntero; se necesita un valor de puntero para inicializar un puntero a 'int', no una matriz de' int'. –

3

var en sí es un (*int) apuntando al primer elemento en su matriz. Punteros y matrices en C extremadamente similares. Cambie int (*ptr)[5] = NULL; a int* ptr = NULL; y ptr = &var; a ptr = var;

1

De lo que puedo decir que está asignando un puntero de la lista (var) a un puntero que apunta a un puntero de la lista ((*ptr)[5]), así que por eso se obtiene que la alerta.

En su lugar, trate de usar

int *ptr = NULL; 
4

C es un lenguaje fuertemente tipado.Cuando una función espera un parámetro de tipo int *, debe pasar un argumento de tipo int *. No double *, no char *, pero int *. Incluso si la dirección numérica real en esos double * o char * es "la misma" que la que desea pasar, todavía no cambia nada; aún debe pasar un int *. El idioma le prohíbe pasar el valor del tipo incorrecto.

Esto es exactamente lo que sucede en su caso. La función toma un parámetro del tipo int (*)[5]. Eso significa que tienes que pasar el argumento de ese tipo. En su lugar, no se permite pasar int *. Si la dirección es la misma, no hay diferencia.

Cuestiones relacionadas