2011-10-31 14 views
6

Soy un programador de Python aprendiendo C del libro K & R. Esto parecerá una pregunta tremendamente trivial, pero estoy perplejo de todos modos. A continuación se incluye un fragmento de código del libro K & R (RIP Ritchie!) Que implementa la función atoi().Comprender una función de atoi()

atoi(s) /*convert s to integer */ 
char s[]; 
{ 
    int i, n, sign; 
    for (i=0; s[i]==' '||s[i] == '\n' || s[i] == '\t'; i++) 
    ; /* skip whitespace */ 
    sign = 1; 
    if (s[i] == '+' || s[i] = '-') /* sign */ 
     sign = (s[i++] == '+') ? 1 : -1; 
    for (n=0; s[i] >= '0' && s[i] <= '9'; i++) 
     n = 10 * n + s[i] - '0'; 
    return (sign * n); 
} 

Mis preguntas:

1) ¿La primera 'para' bucle sirve a ningún propósito además de contar el número de characaters válido?
2) Si (1) es verdadero, el primer ciclo establece el valor de 'i' en el número de caracteres válidos. ¿Cómo funciona el segundo ciclo for sin restablecer i en 0?

Digamos, por ejemplo, que ingreso '2992' como entrada a la función. El primero para el ciclo establece de i a 3, entonces, ¿cómo funciona el resto de la función? Es posible que todos mis conocimientos básicos estén mal, pero cualquier ayuda sería muy apreciada. Gracias, -Craig

+1

No sabía que C es _that_ terrible. –

+0

Creo que la mejor manera de entender un fragmento de código es ejecutarlo con un depurador (por ejemplo, gdb) y avanzar paso a paso. También puede ser útil leer el código y los comentarios en el interior. – eyalm

+0

@PatrickB .: eso es _muy antiguo_ C. Modern C parece ... exactamente igual :) (excepto la firma de función que ahora es mucho más clara 'int atoi (const char * s)'.) – Mat

Respuesta

10
int atoi(char* str) 
{ 
    if(!str) 
     printf("Enter valid string"); 

    int number = 0; 
    char* p = str; 

    while((*p >= '0') && (*p <= '9')) 
    { 
     number = number * 10 + (*p - '0'); 
     p++; 
    } 
    return number; 
} 

Aquí está toda la idea detrás de ATOI.

1) Se establece el puntero al comienzo de la matriz de caracteres

2) y luego dentro del bucle while usted se pasa de cada personaje y se multiplica por 10 y agregar el carácter restando por 0.

Y si lo intentas con 2992, el número sería 2992 también.

+0

Si el OP regresa a K & R, le indicaré que en C89 no puede poner declaraciones en el código medio: http://stackoverflow.com/questions/288441/variable-declaration-placement- Cª – HostileFork

4

El primer ciclo hace lo que dice el comentario: se salta el espacio en blanco.

Después de eso, i es el índice del primer carácter que no es de espacio en blanco, que es exactamente lo que necesita para proceder.

1

No, el primer bucle se salta el espacio en blanco, como dice el comentario.

1

El comentario proporciona la respuesta: el primer bucle es skip whitespace. Para 2992, i se mantendrá 0.

1

El primer bucle avanza para señalar el primer carácter que no sea de espacio en blanco.

El condicional entre los bucles toma nota del signo, si lo hay.

Luego, el ciclo final realiza la conversión real.

Finalmente, se aplica el signo y se devuelve el resultado.

0

1) no first for loop no cuenta el número de caracteres, pero cuenta la primera posición de número si solo comenzando caracteres son espacios en blanco, es decir, para este "-2992" voy a ser 1 y para "2992" voy a estar 0. 2) sign = (s[i++] == '+') ? 1 : -1; esta afirmación comprueba si el i \ 'th char es un signo y hace que el contador se eleve en 1 [i ++] y para el próximo bucle for this i es el primer dígito inicial de la cadena. ¡Si hago 0 entonces para la primera entrada condicional, su carta de verificación será espacio!

edit1: primera entrada es "space space-2992"