2011-07-03 16 views
7

Estoy aprendiendo C hoy. He estado codificando en lenguajes administrados (Java, C#, Python, etc.) desde hace un tiempo. Pensé que estaba entendiendo los detalles de los punteros, pero luego escribí el siguiente código que funcionó como se esperaba, pero generó una advertencia de "tipo de puntero incompatible".Aclaración sobre por qué funciona este código C

void setText(char* output) { 
    //code to set output to whatever, no problems here. 
} 

int main(int argc, const char* argv[]) { 
    char output[10]; 

    setText(&output); 

    //[EDITED] ...other test code which printf's and further manipulates output. 

    return 0; 
} 

Así que busqué en Google, y terminó cambiando la línea

setText(&output); 

a

setText(output); 

la que se deshizo de la advertencia. Pero ahora no sé por qué el primero estaba funcionando en absoluto. Estaba enviando la dirección de una dirección hasta donde puedo decir (porque char * x; es esencialmente lo mismo que char x [];). ¿Qué estoy malinterpretando y por qué funcionan ambos?

+0

Es un poco difícil decir por qué 'setText' funcionaba sin ver su implementación. Aunque, si todo 'setText' hace es establecer una variable, después de que el programa sale, ¿cómo se puede decir realmente si el programa está haciendo lo que quieres? – jwodder

+2

'T *' es * no * lo mismo que 'T [K]'. Ver p. http://c-faq.com/~scs/cgi-bin/faqcat.cgi?sec=aryptr – delnan

+0

@delnan: El enlace parece estar roto – Cameron

Respuesta

17

El tipo de output es char [10], que se desintegra a un char * en el contexto de una llamada de función (que es la razón por la segunda variante funciona).

El tipo de &output es char (*)[10], es decir, un puntero a matriz. Esto no es lo mismo, de ahí la advertencia del compilador. Sin embargo, el valor de &output (una dirección) es equivalente al valor de output (una vez que ha decaído a char *), por lo que el resultado final es "como se esperaba".

Esto puede parecer una pedantería, pero hay una diferencia bastante importante. Pruebe lo siguiente:

void foo(const char *p) 
{ 
    printf("%s\n", p); 
} 

int main(void) 
{ 
    char output[][6] = { "Hello", "world" }; 

    foo(output[0] + 1); 
    foo(&output[0] + 1); 
} 

Lectura recomendada es the C FAQ on arrays and pointers, en particular, pregunta 6.3 y 6.12.

+1

Y "funciona" a pesar de la advertencia porque ambos terminan apuntando al mismo lugar. –

+1

Buen ejemplo. Realmente ayuda a ilustrar lo que está sucediendo aquí. – hbw

+0

Sí, ese ejemplo ayudó. Gracias. – atheaos

Cuestiones relacionadas