2010-06-17 18 views
6

¿Cuándo debo insertar/no insertar & para scanf() en C? Gracias.scanf() (C Language) me confundió

int main() 
{ 
    char s1[81], s2[81], s3[81]; 

    scanf("%s%s%s", s1, s2, s3); 

    // If replace scanf() with the expression below, it works too. 
    // scanf("%s%s%s", &s1, &s2, &s3); 

    printf("\ns1 = %s\ns2 = %s\ns3 = %s", s1, s2, s3); 

    return 0; 
} 

//programming is fun 
// 
//s1 = programming 
//s2 = is 
//s3 = fun 
+2

Recomiendo leer el lenguaje de programación C por K & R. Esto no es realmente una pregunta sobre scanf, sino más una pregunta acerca de cómo funciona el acceso a la memoria en C. – BobbyShaftoe

Respuesta

9

scanf pone los valores escaneados en la dirección indicada por sus argumentos. El & es el operador de dirección y se usa para tomar la dirección de una variable.

Pero, está utilizando matrices, y las matrices se degradan a punteros cuando se utilizan como argumentos de funciones. Por lo tanto, no es necesario utilizar el operador & en el caso de las matrices.

Ejemplo:

char s[81]; 
int n; 
int* nptr; 
//Initialize nptr to some meaningful value 
scanf("%s %d %d",s,&n,nptr); 

En este caso, tenemos que utilizar el operador & para obtener la dirección fueron n se mantiene. No necesitamos usarlo con nptr, porque ya es un puntero a algún lugar en la memoria, ni con s, porque una matriz se degrada a un puntero cuando se pasa a una función.

+0

@All. Gracias. –

1

Sólo una conjetura, pero yo supongo que es porque s1, s2 y s3 son matrices.

6

Los argumentos que siguen al especificador de formato deben ser punteros. Cuando se pasa un nombre de matriz a una función, se pasa la ubicación del elemento inicial, por lo que no necesita utilizar el & en absoluto en su ejemplo. Se podría hacer esto sin embargo (de K&R):

int day, year; 
char monthname[20]; 

scanf("%d %s %d", &day, monthname, &year); 

Desde el primer día y el año son int, que debe utiliza el & para obtener la dirección de esas variables. Como monthname es una matriz, no se requiere &.

+4

Todos los codificadores C deben leer K & R. – atlpeg

+3

Un nombre de matriz no es un puntero sino que se convierte implícitamente a uno dependiendo del contexto en el que se utiliza. De lo contrario, 'sizeof' y la dirección del operador no funcionarían como se esperaba. –

+0

@Georg: Eso es cierto. Edité mi respuesta para ser más explícito. –

2

s1 devuelve la dirección del primer elemento de la matriz, mientras que &s1 devuelve la dirección de la matriz. La dirección del primer elemento y la dirección de la matriz en sí son idénticas, de ahí que ambas representaciones funcionen.

0

En general, usaría scanf de la manera en que lo hace en su línea no comentada. La forma en que funcionan las matrices en C es que el nombre de las matrices como s1, s2 y s3 ​​es en realidad la dirección del primer elemento de la matriz. Sin embargo, para las primitivas, debería usar la sintaxis de la variable &. Por ejemplo:

float f; 
scanf("%f", &f); 
+0

Los nombres de matriz no apuntan al primer elemento, vea el comentario en la respuesta de Bills. –

1

Si a es una matriz, tanto a y &a resultado de un puntero en este contexto:

  • a hace debido a la matriz en descomposición a un puntero (C99, § 6.3.2.1/3):

    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 el tipo '' array del tipo '' se convierte en una expresión con el tipo '' puntero al tipo '' que apunta al elemento inicial del objeto de matriz y no es un valor l.

    ... cursivas en el

  • &a hace como resultado de que el operador & - devuelve un puntero al objeto.

4

En C, cuando se trata de matrices:

int c_array[24]; 
c_array == &c_array == &c_array[0] 

Sí, es divertido - que tienen el mismo aspecto (la diferencia está en los tipos). Lee this.

+0

La diferencia de tipo se vuelve visible cuando compara las dos direcciones '& s1 [1]' y '& (& s1) [1]'. La indexación agrega el * tamaño de los elementos * multiplicado por el valor del índice en la dirección. Sin embargo, el tamaño de un elemento en '& s1' es' sizeof (s1) ', es decir, 81. –

1

Scanf acepta una cantidad variable de parámetros. El primer argumento de scanf es el formato y después de eso n direcciones donde los valores se almacenan mientras n es el número de formato especificado en el formato de cadena. ya que está usando una matriz, para almacenar valores, debe proporcionar la dirección base de la matriz.

 

//If int 
int i; 
scanf("%d",&i); // store int value at address &i 

float f; 
scanf("%f",&f); //store float value at address &f 

int a[10]; 
scanf("%s",a); //store string or array value at a 

si se utiliza una en última línea que confunde, puede intentar hacer lo mismo con la dirección del primer elemento que es & a [0].

creo que sirve,
GG