2011-12-14 11 views
5

Este código proviene de K & R. Lo he leído varias veces, pero parece que se me escapa.Explica este ejemplo C Código

#define BUFSIZE 100 

char buf[BUFSIZE]; 
int bufp = 0; 

int getch(void) 
{ 
     return(bufp>0)?buf[--bufp]:getchar(); 
} 

int ungetch(int c) 
{ 
     if(bufp>=BUFSIZE) 
      printf("too many characters"); 
     else buf[bufp++]=c; 
} 

El propósito de estas dos funciones, por lo que K & R dice, es evitar que un programa de la lectura de demasiada información. es decir, sin este código, una función podría no ser capaz de determinar si ha leído suficientes datos sin leer demasiado. Pero no entiendo cómo funciona.

Por ejemplo, considere getch(). Por lo que yo puedo ver que esto es los pasos que se necesitan:

  1. verificación si bufp es mayor que 0.
  2. si es así, devolver el valor del carbón buf [- bufp].
  3. else return getchar().

me gustaría hacer una pregunta más específica, pero literalmente no sé cómo este código logra lo que se pretende conseguir, por lo que mi pregunta es: ¿Cuál es (a) la finalidad y (b) el razonamiento de este código?

Gracias de antemano.

NOTA: Para cualquier K & ventiladores R, este código se puede encontrar en la página 79 (dependiendo de su edición, supongo)

+0

La prueba dentro de 'ungetch' probablemente debería incluir' bufp' no 'printf' en su condición. Supongo que es un error tipográfico. –

+0

No tengo K & R a mano ahora, pero creo que en ungetch, la condición if debería ser 'bufp> = BUFSIZE' – kol

+0

Lo siento, probablemente sea mi error. SOmeone lo ha solucionado ahora, así que no puedo recordar lo que originalmente escribí. –

Respuesta

9

(a) El propósito de este código es ser capaz de leer un carácter y luego "no leerlo" si resulta que accidentalmente lees demasiado a un personaje (con un máximo de 100 caracteres para ser "no leído"). Esto es útil en analizadores sintácticos con anticipación.

(b) getch lee de buf si tiene contenido, indicado por bufp>0. Si buf está vacío, llama al getchar. Tenga en cuenta que usa buf como una pila: lo lee de derecha a izquierda.

ungetch empuja un personaje en la pila buf después de hacer una comprobación para ver si la pila no está llena.

+0

Pero suponiendo que no se llame a ungetch, entonces getch siempre devolverá getchar(), ya que bufp será cero indefinidamente. No entiendo esta parte. –

+0

@JJG: así es, si nunca llamas 'ungetch', entonces no necesitarás el buffer y siempre recibirás nueva entrada de' getchar'. –

1

El código no es realmente para "leer demasiada información", en su lugar es así que puede devolver los caracteres ya leídos.

Por ejemplo, usted leyó un carácter con getch, vea si es una letra, póngalo de nuevo con ungetch y lea todas las letras en un bucle. Esta es una manera de predecir cuál será el próximo personaje.

1

Este bloque de código está destinado a los programas que toman decisiones basadas en lo que leen de la transmisión. A veces, tales programas necesitan mirar algunos caracteres de la secuencia sin consumir realmente la entrada. Por ejemplo, si su entrada es similar a abcde12xy789 y debe dividirla en abcde, 12, xy, 789 (es decir, grupos separados de letras consecutivas de grupos de dígitos consecutivos) no sabe que ha llegado al final de un grupo de letras hasta que veas un dígito. Sin embargo, no desea consumir ese dígito en el momento en que lo ve: todo lo que necesita es saber que el grupo de letras está terminando; necesitas una forma de "devolver" ese dígito.Un ungetch es útil en esta situación: una vez que ve un dígito después de un grupo de letras, devuelve el dígito llamando al ungetch. En su próxima iteración, recuperará ese dígito a través del mismo mecanismo getch, lo que le evita la necesidad de conservar el carácter que ha leído pero que no ha consumido.

0
    1. La otra idea que también se muestra aquí se puede llamar también como un sistema de gestión de pila de E/S muy primitivo y proporciona la implementación de la función getch() y ungetch().
    2. Para ir un paso más allá, supongamos que desea diseñar un sistema operativo, ¿cómo puede manejar la memoria que almacena todas las teclas?

Esto se resuelve mediante el fragmento de código anterior. Una extensión de este concepto se utiliza en el manejo de archivos, especialmente en archivos de edición. En ese caso, en lugar de usar getchar() que se utiliza para archivo se utiliza como fuente de entrada.