Pregunta

Tenemos el siguiente fragmento de código:

char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'};
printf("%s\n", tab);

Y no entiendo por qué no conseguimos un error / advertencia en la llamada a printf. HAGO una advertencia, pero no un error y el programa se ejecuta bien.Imprime '12'.
printf se espera un argumento de tipo char *, es decir,un puntero a char.Así que si yo he declarado char arr[3], a continuación, arr es una dirección de una unidad de memoria que contiene un char, por lo que si me llama printf con ella, sería la desintegración puntero a char, es decir, char *.
De forma análoga, tab es una dirección de una unidad de memoria que contiene el tipo de matriz de 3 caracteres que es a su vez, una dirección de memoria de la unidad contiene char, por lo que tab se decadencia char **, y que debe ser un problema, ya que printf está a la espera de un char *.

Alguien puede explicar este problema?

Addendum:

El aviso que me sale es:
a.c:6: warning: char format, different type arg (arg 2)

¿Fue útil?

Solución

Fuente de ejemplo

#include <stdio.h>

int main( void ) {
  char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'};
  printf("%s\n", tab);

  return 0;
}

Advertencia de compilación

$ gcc test.c
test.c: In function ‘main’:
test.c:5: warning: format ‘%s’ expects type ‘char *’, but argument 2 has type ‘char (*)[3]’

Los punteros son punteros

El argumento %s para printf indica a la función que recibirá un puntero (a una cadena). Una cadena, en C, es simplemente una serie de bytes terminados por un ASCII-Z. La variable tab[2][3] es un puntero. Algunos compiladores emitirán una advertencia sobre la falta de coincidencia del puntero. Sin embargo, el código aún debe imprimir 12 porque el código de tab atraviesa la memoria comenzando en el puntero que se le dio (imprimiendo caracteres a medida que avanza) hasta que encuentra un byte cero. 1, 2 y \ 0 se configuran de forma contigua en la memoria, comenzando en la dirección representada por la variable <=>.

Experimento

Como experimento, qué sucede cuando compila y ejecuta el siguiente código:

#include <stdio.h>

int main( void ) {
  char tab[2][3] = {'1', '2', '\0', '3', '4', '\0'};
  printf("%s\n", tab[1]);

  return 0;
}

No tengas miedo de experimentar. Vea si puede llegar a una respuesta basada en lo que ahora sabe. ¿Cómo haría referencia <=> ahora (a la luz del experimento) para deshacerse de la advertencia y seguir mostrando <=>?

Otros consejos

El parámetro tab coincide con los puntos suspensivos en la llamada printf (). Los compiladores de C y C ++ no tienen la obligación de verificar dichos parámetros.

Su suposición de que tab se decadencia char ** es incorrecto: tab tiene el tipo char [2][3], es decir, la desintegración char (*) [3].Es importante entender que a pesar de las matrices y punteros a menudo se comportan igual, ellos no son la misma cosa. printf() espera un char *, así que toma los bits de la char (*) [3] y las interpreta en consecuencia.Aunque funciona en la plataforma, el estándar de C no garantiza esto:ambos punteros hacen referencia a la misma ubicación de memoria, pero su representación no tiene que ser idéntica.

Verificación mi respuesta a esta pregunta relacionada con la para obtener más detalles.

Parece que lo ha explicado usted mismo, no veo lo que queda por decir.

tab es una matriz de dos char * 's. Cada elemento de printf es una cadena que <=> puede aceptar, pero <=> en sí misma no es aceptable, ya que es un puntero a un puntero a un carácter.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top