Lectura de una cadena con scanf

Estoy un poco confundido por algo. Tenía la impresión de que la forma correcta de leer una cadena C con scanf() iba por las líneas de

(No importa el posible desbordamiento de búfer, es solo un ejemplo)

 char string[256]; scanf( "%s" , string ); 

Sin embargo, lo siguiente parece funcionar también,

 scanf( "%s" , &string ); 

¿Es esto solo mi comstackdor (gcc), pura suerte o algo más?

Una matriz “decae” en un puntero a su primer elemento, por lo que scanf("%s", string) es equivalente a scanf("%s", &string[0]) . Por otro lado, scanf("%s", &string) pasa un puntero a char[256] , pero apunta al mismo lugar.

Luego scanf , al procesar la cola de su lista de argumentos, intentará sacar un char * . Eso es lo correcto cuando has pasado en string o &string[0] , pero cuando pasas in &string dependes de algo que el estándar de idioma no garantiza, a saber, los punteros &string y &string[0] – punteros a objetos de diferentes tipos y tamaños que comienzan en el mismo lugar – están representados de la misma manera.

No creo haber encontrado un sistema en el que eso no funcione, y en la práctica probablemente estés a salvo. No obstante, está mal, y podría fallar en algunas plataformas. (Ejemplo hipotético: una implementación de “depuración” que incluye información de tipo con cada puntero. Creo que la implementación de C en Symbolics “Lisp Machines” hizo algo como esto).

Creo que esto a continuación es preciso y puede ser útil. No dude en corregirlo si encuentra algún error. Soy nuevo en C.

 char str[] 
  1. matriz de valores de tipo char, con su propia dirección en la memoria
  2. matriz de valores de tipo char, con su propia dirección en la memoria tantas direcciones consecutivas como elementos en la matriz
  3. incluyendo el carácter nulo de terminación '\0' &str , &str[0] y str , los tres representan la misma ubicación en la memoria que es la dirección del primer elemento de la matriz str

    char * strPtr = & str [0]; // statement e inicialización

alternativamente, puedes dividir esto en dos:

 char *strPtr; strPtr = &str[0]; 
  1. strPtr es un puntero a un char
  2. strPtr apunta a la matriz str
  3. strPtr es una variable con su propia dirección en la memoria
  4. strPtr es una variable que almacena el valor de la dirección &str[0]
  5. strPtr propia dirección strPtr en la memoria es diferente de la dirección de memoria que almacena (dirección de la matriz en la memoria aka & str [0])
  6. &strPtr representa la dirección de strPtr en sí

Creo que puedes declarar un puntero a un puntero como:

 char **vPtr = &strPtr; 

declara e inicializa con la dirección del puntero strPtr

Alternativamente, podrías dividir en dos:

 char **vPtr; *vPtr = &strPtr 
  1. *vPtr puntos *vPtr en el puntero strPtr
  2. *vPtr es una variable con su propia dirección en la memoria
  3. *vPtr es una variable que almacena el valor de la dirección & strPtr
  4. comentario final: no se puede hacer str++ , la dirección str es una const , pero se puede hacer strPtr++