viernes, 14 de septiembre de 2012

Kernighan_Ritchie_2.10 (Convertir un texto a minúsculas)

___________________________________________________________________________________
2.10 Reescriba la función lower, que convierte letras mayúsculas en minúsculas, con una expresión condicional en vez de un if-else.
___________________________________________________________________________________
SOLUCIÓN: La modificación es directa. El programa está escrito de tal manera que se puede recibir como entrada un archivo de texto y convertirlo a minúsculas. La razón por la que éste programa sólo funciona con el código ASCII, es porque la línea principal de la función lower es la siguiente:

x = (c >= 'A' && c <= 'Z')? c + 'a' - 'A': c;

básicamente hace uso del hecho que en ASCII, las letras mayúsculas aparecen antes que las minúsculas, y la distancia entre una mayúscula y su correspondiente minúscula es de 32 posiciones. Así, el valor de A es 65, y el de a es 97; el de S es 83, y el de s 115. Por tal motivo, en la instrucción de asignación, primero se verifica que el carácter sea mayúscula, si lo es, entonces se cambia a el correspondiente valor más 32 ( escrito como c + 'a' -'A'), de lo contrario, se deja igual.


#include <stdio.h>

int lower(int s);


////////////////////////////////////////////////
// MAIN
////////////////////////////////////////////////

int main()
{ /*Abre main*/
int z, l;

printf("\nPor favor, introduzca un texto. ");
printf("Se imprimira en minusculas.\n");

while( (z = getchar()) != EOF)
{ /* Abre while */  
l = lower(z);
putchar(l);
}/*Cierra while */

return 0;
} /*Cierra main*/

/*//////////////////////////////////////////////
// LOWER
//////////////////////////////////////////////*/

int lower(int c)
{  /*Abre lower*/
int x;

x = (c >= 'A' && c <= 'Z')? c + 'a' - 'A': c;

return x;
}  /*Cierra lower*/


La ejecución con éste texto como entrada

ERASE UN HOMBRE A UNA NARIZ PEGADO,
ERASE UNA NARIZ SUPERLATIVA
UNASE UNA NARIZ ZAYON Y ESCRIBA,
ERASE UN PEJE ESPADA MUY BARBADO.

produce:

Por favor, introduzca un texto. Se imprimira en minusculas.

erase un hombre a una nariz pegado,
erase una nariz superlativa
unase una nariz zayon y escriba,
erase un peje espada muy barbado.

Kernighan_Ritchie_2.5 (Primera posición de la coincidencia de dos cadenas)

___________________________________________________________________________________
2.5 Escriba la función any(s1,s2), que regresa la primera posición de la cadena s1 en donde se encuentre cualquier carácter de la cadena s2, o -1 si s1 no contiene caracteres de s2. (La función de biblioteca estándar strpbrk hace el mismo trabajo pero regresa un apuntador a la posición encontrada).
___________________________________________________________________________________
Solución: El código siguiente presenta la solución del problema. Se ha puesto un par de cadenas, las cuales se pueden cambiar. Lo importante es la función any. La ejecución del programa, tal como está, produce -1 como salida, ya que la cadena "xxz" no tiene ningún elemento en común con "La felicidad esta en lugares mas o menos lejanos".

#include<stdio.h>
enum {TAMANO1 = 100, TAMANO2 = 50};

int any(char s1[], int n, char s2[], int m);
void Imprimir( char cadena[]);

/*//////////////////////////////////
// MAIN
//////////////////////////////////*/

int main()
{ /* Abre main */
int y;

char cadena1[TAMANO1] = "La felicidad esta en lugares mas o menos lejanos";
char cadena2[TAMANO2] = "xxz";
/*La cadena1 */
Imprimir(cadena1);
printf("\n");
/*La cadena 2*/
Imprimir(cadena2);
printf("\n");

y = any(cadena1, TAMANO1, cadena2, TAMANO2);

if (TAMANO1 != y)
printf("\n%d\n", y);
else 
printf("-1\n");
return;
} /* Cierra main*/

/*//////////////////////////////////
// ANY
//////////////////////////////////*/

int any(char s1[], int n, char s2[], int m)

{ /* Abre any*/
int i, j, x = TAMANO1; 

for (i = 0; s2[i] !=  '\0'; i++)   
for (j = 0; s1[j] !=  '\0'; j++)
{ /*Abre for*/
if (s1[j] == s2[i])
{ /* Abre if */
x = (j < x)?  j:x;
break; /*Salimos del for anidado*/
} /* Cierra if*/
} /* Cierra for*/

return x;
} /* Cierra any*/


/*///////////////////////////////////
// IMPRIMIR
///////////////////////////////////*/

void Imprimir(char cadena[])

{ /*  Abre Imprimir */
int i = 0; 
for (i = 0; cadena[i] != '\0'; i++)
putchar(cadena[i]); 

return;
} /* Abre Imprimir */

La ejecución de éste programa es la siguiente:

Cadena 1:
La felicidad esta en lugares mas o menos lejanos
Cadena 2:
xxz
-1

__________________________________________________________________________________________
Esta entrada es parte de los problemas resueltos del libro El Lenguaje de Programación C de B. Kernighan y D. Ritchie
Entrada anterior
Entrada siguiente
__________________________________________________________________________________________

jueves, 13 de septiembre de 2012

Kernighan_Ritchie_2.4 (Suprimir las coincidencias de dos cadenas)

___________________________________________________________________________________
2.4 Escriba una versión alterna de squeeze(s1,s2) que borre cada carácter de s1 que coincida con cualquier carácter de la cadena s2.
___________________________________________________________________________________
Solución:
La función squeeze a la que hace referencia el enunciado aparece en el texto y es la siguiente:


void squeeze(char s[], int c)
{
int i, j;

for(i = j = 0; s[i] != '\0'; i++)
   if (s[i] != c)
      s[j++] = s[i];

s[j] = '\0';
}

Esta función comprime la cadena s1 por medio de eliminar la variable c. La variable i recorre el arreglo que contiene s1 y la variable j recorre el mismo arreglo siempre que la variable leída no coincida con c. Al final, para indicar que la cadena ha terminado, se escribe explícitamente el carácter de terminación de cadena '\0'.
A continuación presento mi versión de ésta problema tal como lo pide el libro. He puesto un par de cadenas, la primera que dice: "La felicidad esta en lugares mas o menos lejanos, como Londres" y la segunda: "Hola". Lo que hace el programa, y concretamente la función squeeze, es recibir las dos cadenas (supone que la primera es mayor que la segunda) y recorrer todo el primer arreglo (el mayor) desde el elemento 0 hasta el último en busca de coincidencias. Al mismo tiempo va sustituyendo las variables encontradas en el mismo arreglo, sólo si no coinciden con alguna de las entradas de la segunda cadena. Para esto, se recorren también todos los elementos del segundo arreglo hasta encontrar el elemento terminal '\0'.

/*************************************************************************
*                                                                        *
* Este programa tiene como datos un par de cadenas: cadena y cadena2     *
* Suprime todas las coincidencias de cadena2 en cadena e imprime cadena  *
*                                                                        *
**************************************************************************/
#include<stdio.h>
#define TAMANO 100

void squeeze( char s[], char t[],  int c);
void Imprime(char cl[], int n);

/*//////////////////////////////////////
// MAIN
//////////////////////////////////////*/ 

int main()
{  /* Abre main */

char cadena[TAMANO] = "La felicidad esta en lugares mas o menos lejanos," " como Londres";
char cadena2[TAMANO] = "Hola";
/*Las cadenas se pueden concatenar en tiempo de complilacion*/

/*cadena antes de llamar a la funcion squeeze*/
printf("\nCadena 1: \n");
Imprime(cadena, TAMANO);
printf("\nCadena 2:\n");
Imprime(cadena2, TAMANO);

printf("\n");

squeeze (cadena, cadena2, TAMANO);
 
/* Cadena despues de llamar a la funcion squeeze */ 
Imprime(cadena, TAMANO);

printf("\n");

return 0; 
}  /* Cierra main */

/*/////////////////////////////////////
// SQUEEZE
/////////////////////////////////////*/

void squeeze( char s[], char f[], int c)
{  /* Abre squeeze */
int i, j, k;

for (k = 0; k < c; k++) 
{ /*Abre for*/
for (i = j = 0; s[i] != '\0'; i++)
if ( s[i] != f[k]) 
s[j++] = s[i];

s[j] = '\0';
} /*Cierra for*/
}  /* Cierra squeeze*/

/*//////////////////////////////////////
//  IMPRIME
//////////////////////////////////////*/

void Imprime(char cl[], int n)
{  /* Abre Imprime */
for (n = 0; cl[n] != '\0'; n++ )
putchar(cl[n]);

}  /* Cierra Imprime */

La ejecución de éste programa produce la salida:

Cadena 1: 
La felicidad esta en lugares mas o menos lejanos, como Londres
Cadena 2:
Hola
L feicidd est en ugres ms  mens ejns, cm Lndres

que es, efectivamente, la cadena original sin los elementos de la segunda.

__________________________________________________________________________________________
Esta entrada es parte de los problemas resueltos del libro El Lenguaje de Programación C de B. Kernighan y D. Ritchie
Entrada Anterior
Entrada Siguiente
__________________________________________________________________________________________

viernes, 8 de junio de 2012

Aritmética en el Lenguaje de Programación C

Antes de hablar de aritmética en el lenguaje C, vamos a hablar simplemente de la aritmética.
¿Cuál es el resultado de la siguiente operación?

5 + 4 x 6 = ?

Muchas personas responden de inmediato que el resultado es 54, porque si se suma 5 + 4 el resultado es 9; si ahora se multiplica 9 x 6, el resultado es 54. Otras contestan que el resultado es 29, porque 4 x 6 = 24, y 5 + 24 = 29.
Este ejemplo es ilustrativo, porque muestra claramente que en aritmética es importante el orden en el cual los operadores actúan. Esta importancia es más grande todavía en programación. La respuesta correcta es la segunda,

5 + 4 x 6 = 29

La razón de ésto es que por convención, la multiplicación tiene un orden de precedencia mayor que la suma. Las operaciones NO se realizan en el orden de aparición de los operadores. La norma es, primero se realizan las multiplicaciones y divisiones y luego sumas y restas. Cuando en una expresión aritmética sólo aparecen sumas (restas) o sólo multiplicaciones (divisiones), el orden en el que se realicen estas operaciones sí es indiferente. El lector tal vez recuerda estos resultados como las leyes asociativas y conmutativas de la suma(resta) y la multiplicación (división): el orden de los sumandos no altera la suma y el orden de los factores no altera el producto.
Los operadores aritméticos binarios del lenguaje c son

_______________________________________________________________
|OPERADORES ARITMETICOS BINARIOS DEL LENGUAJE DE PROGRAMACION C|
_______________________________________________________________
|SIMBOLO EN C   | EQUIVALENTE MATEMATICO | EJEMPLO             |
________________________________________________________________
|      *        |            x           |  5*7 = 35           |
________________________________________________________________
|      /        |            /           |  15/3 = 5           |
_______________________________________________________________
|      +        |            +           |  7 + 4 = 11         |
________________________________________________________________
|      -        |            -           |  14 - 8 = 6         |
________________________________________________________________
|      %        |            %           |  9%2 = 1            |
_______________________________________________________________


Los operadores aritméticos de suma, resta y división son los mismos en C y en matemáticas. No así el operador de multiplicación, que en C es *. La razón de ésto, es que el lenguaje toma cualquier letra, como x ó X, como nombres de variables y no como operadores. El signo * está reservado para ser el operador de multiplicación. El lector está familiarizado con dichas operaciones, y no será necesario abundar en ellas. Probablemente el operador de módulo % no sea tan familiar. Éste operador recibe dos enteros y devuelve el residuo de la que queda al realizar la división de tales números. En el ejemplo presentado en la tabla de arriba, el cociente (entero) de 9/2 = 4, y el residuo es 1.
Para alterar el orden natural de ejecución de los operadores es necesario usar paréntesis. Si en el caso de la suma presentada al principio, usamos un par de paréntesis como éstos, que rodean al 5 y al 4

(5 + 4) x 6 = 54

obtendremos como resultado 54. Los paréntesis indican que lo contenido dentro de ellos, debe considerarse como un sólo número. Primero deben hacerse pues, las operaciones indicadas ahí, y el resultado final multiplicarlo por 6. Casos más complicados pueden aparecer cuando hay más de un par de paréntesis y algunos de ellos están anidados

((4 - 6) - 7*(2 + (-8)) = ?

4 pares de paréntesis aparecen aquí. El primero, externo, rodea a toda la expresión. Ese podría ser suprimido sin ningún problema. Sin embargo, muchas veces, cuando escriba programas, verá que es útil rodear una expresión aritmética con paréntesis externos. El siguiente par rodea a 4 - 6. Esto quiere decir, como en el caso anterior, que hay que considerar esa expresión como un sólo número; ese número es -2. El siguiente par de paréntesis rodea a 2 + (-8). El otro par de paréntesis rodea a -8. En realidad también es redundante, ya que podría haberse escrito 2 - 8, pero la literal también es válida. El resultado de esa expresión es -6. Así que, suprimiendo los paréntesis internos, la expresión queda como

-2 - 7*(-6) = ?

Aquí sólo aparece un par de paréntesis, rodeando a -6. Primero se realiza la multiplicación, -7*(-6) = 42. -2 + 42 = 40. El resultado es 40.
Para la potenciación, logaritmo y raíz cuadrada, el lenguaje C incluye funciones preestablecidas. Éstas funciones están empacadas en el encabezado <stdio.h>

Sin embargo, hay que tener en cuenta que en C los números reales son almacenados en espacios de memoria, y el resultado de las operaciones aritméticas que con ellos se realizan, también. Las operaciones entre números enteros (int) producen un int; las operaciones entre float produce números float. Sin embargo, no es posible realizar, por ejemplo, la suma de un tipo int con un tipo float. En caso de ocurrir una operación de ese tipo, el compilador convierte el tipo int a tipo float de manera implícita, y el resultado es un float. En general la regla es que los tipos menores se convierten a los tipos mayores, lo cual ocurre sin pérdida de precisión. En general, y a pesar de dicha conversión, no es conveniente permitir que ocurran tales casos. El almacenamiento de un tipo float (producto de una operación aritmética) en un tipo int no es posible, y el intento produce un mensaje de error.
Los operadores en una expresión aritmética podrían ser funciones de variables. Por ejemplo:

int a, s, t;

a = f(s) + g(t)

En este fragmento de programa, a la variable entera a se le asigna la suma de los valores de retorno (tipos int) de las funciones f (que depende del parámetro entero s) y g (dependiente, a su vez, del parámetro entero t). En casos como éste, el estándar de C no indica qué función se evalúa primero. Un compilador, en una computadora podría evaluar primero g(t) y luego f(s), en tanto que otro compilador (o incluso el mismo) en una computadora distinta, puede hacer la evaluación al revés. Esto es especialmente grave si las funciones dependen del mismo parámetro y lo modifican en los cuerpos de instrucciones.
También es necesario cuidar la precedencia cuando uno escribe segmentos de código como

a[i] = i++;

Los operadores de incremento y decremento pueden producir sutiles errores cuando se usa la variable incrementada o decrementada en la misma expresión. En este ejemplo, el estándar no dice qué se hace primero, si incrementar el contador o localizar el espacio de memoria en el arreglo. Como recomendación contra éstos errores, es necesario evitar expresiones en las que el resultado depende el orden de evaluación de los elementos de dichas expresiones.
Vale aquí una digresión que no está del todo fuera de lugar. El procesador de una computadora para fines teóricos es llamado unidad de proceso (PU por sus siglas en inglés). Una PU consta de dos partes: la unidad lógica aritmética (ALU) y la unidad de control (CU). La primera es capaz de realizar sumas, restas, etc. y llevar a cabo operaciones lógicas del tipo igual que, mayor o igual que, etc; en tanto que la segunda coordina la realización de esas tareas aritméticas y lógicas. La ALU sólo puede llevar a cabo una operación a la vez, por lo cual es importante el papel jugado por la CU al asignarle las tareas mediante las instrucciones adecuadas. Estas instrucciones se realizan con un orden determinado y en conjunto se les conoce como ciclo de instrucción. Éstos pasos son:
Buscar y traer (Fetch) La PU busca y trae la siguiente instrucción del programa que está ejecutando.
Decodificar la instrucción LA PU tiene que saber qué tipo de instrucción va a realizar la ALU (suma, multiplicación, división, etc.)
Ejecutar la instrucción Esta es la tarea realizada por la ALU.
Almacenar el resultado El resultado de la operación aritmética o lógica realizada por la ALU es almacenada en memoria para su posterior utilización.
Todas las computadoras realizan este ciclo de instrucción, y todo lo que saben hacer las computadoras es solamente esto. Es sorprendente que audio, video,comunicación remota y todas las tareas para las que sirven las computadoras sean realizadas llevando a cabo sólo operaciones lógicas y aritméticas, pero así es. Tan importante es este ciclo, que los procesadores valen por la cantidad de ciclos de instrucción que pueden hacer en un segundo. Un procesador de 3 GHz realiza 3 x 1000000000 ciclos por segundo.
Ninguna tarea tiene control absoluto del procesador. Todas las tareas se enlistan y se efectúan con un orden que depende de la prioridad que tiene la tarea. Los sistemas operativos se crearon para administrar las tareas que hará el procesador y el tiempo asignado a ellas.

miércoles, 30 de mayo de 2012

Las Funciones Getchar y Putchar

La función getchar recibe un carácter, mientras que la función putchar imprime un carácter. Este par de funciones son más útiles de lo que parece. Permiten manipular de distintas maneras archivos y caracteres. El siguiente programa es un clásico. Recibe carácter por carácter la entrada del usuario (puede ser un número, una cadena, un archivo) con la función getchar y lo imprime con la función putchar.


/*+++++++++++++++++++++++++++++++++++++++++
  * ESTE PROGRAMA LEE E IMPRIME UNA CADENA + 
  * CARACTER POR CARACTER                  +
  * +++++++++++++++++++++++++++++++++++++++*/

 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  *                                                       +
  *                   ALGORITMO                           +
  * Solicitar una cadena                                  +
  *                                                       +
  + Recibe un caracter                                    +
  * Mientras (el caracter recibido no sea fin de archivo) +
  * { // Abre mientras                                    +
  * Imprime el siguiente caracter                         +
  * Incrementa en uno el numero de caracteres             +
  * Recibe el siguiente caracter                          +
  * }  // Cierra mientras                                 +
  *                                                       +
  *++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

  #include <stdio.h>
  
  int main()
  {  /* Abre main */
  int c;

  printf("\nEste programa recibe e imprime una cadena de caracteres ");
  printf("caracter por caracter.\nPor favor introduzca la cadena: \n");

  while(EOF != (c = getchar()))
  putchar(c);
  
  return 0;
  } /* Cierra main */

_____________________________________________________________________________________________
Ahora hagamos un análisis del programa línea por línea para revisar cada instrucción

/*+++++++++++++++++++++++++++++++++++++++++
  * ESTE PROGRAMA LEE E IMPRIME UNA CADENA + 
  * CARACTER POR CARACTER                  +
  * +++++++++++++++++++++++++++++++++++++++*/

 /*++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  *                                                       +
  *                   ALGORITMO                           +
  * Solicitar una cadena                                  +
  *                                                       +
  + Recibe un caracter                                    +
  * Mientras (el caracter recibido no sea fin de archivo) +
  * { // Abre mientras                                    +
  * Imprime el siguiente caracter                         +
  * Incrementa en uno el numero de caracteres             +
  * Recibe el siguiente caracter                          +
  * }  // Cierra mientras                                 +
  *                                                       +
  *++++++++++++++++++++++++++++++++++++++++++++++++++++++*/

Este par de comentarios indican de qué va el programa.

#include <stdio.h>

Un encabezado que indica que se usará entrada y salida estándar. Además de eso, en este programa se hace uso de otro contenido de este encabezado: la definición del valor del carácter que indica el fin de archivo EOF (End of File)

int main()

Recuerde que en C la unidad básica de programación es la función. El nombre main es también un buen nombre para esta función. main se llamaba la función principal en el lenguaje de programación B, del cual evolucionó el lenguaje C.

{  /* Abre main */

Los corchetes se utilizan en cualquier parte donde pueda ponerse una instrucción simple (salvo en el operador ternario). En el caso de la función main (en realidad en cualquier definición de función) las llaves son obligatorias. NO es correcto escribir un programa como éste:

int main()

return 0;

Un programa con una función main vacía debe escribirse así

main()
{

}

Éste es el programa más corto que puede escribirse en el lenguaje C. Sólo consta de 8 caracteres. Sobra decirlo: el programa no hace nada, pero sintácticamente está bien. Es prescindible el encabezado stdio.h, la instrucción return y el tipo int. No son prescindibles el nombre main, los paréntesis después del nombre, ni las llaves. Todos los cuerpos de las funciones deben estar contenidos en llaves.

int c;

Esta declaración de variable reserva espacio para un tipo entero. La variable, c, será utilizada para almacenar temporalmente cada uno de los caracteres. El tipo de datos char es el tipo adecuado para almacenar caracteres. ¿Por qué se utiliza entonces el tipo int? Porque c también debe guardar el valor de EOF, el fin de archivo, el cual generalmente es -1 (véase este programa). Dado que los tipos char son enteros sin signo, al declarar a la variable c como tipo char, no se podría distinguir el fin de archivo.

printf("\nEste programa recibe e imprime una cadena de caracteres ");
printf("caracter por caracter.\nPor favor introduzca la cadena: \n");

Este par de líneas printf son un mensaje para el usuario.

while(EOF != (c = getchar()))

Esta es una forma muy compacta de escribir código. Dentro de la condición de while ocurren varias cosas, y ellas tienen que ver con el orden de precedencia de los operadores. Lo que está dentro de los paréntesis externos, sea lo que sea; se evalúa como una expresión booleana. Si no es una expresión booleana, entonces se convierte explícitamente a una, esto quiere decir que si el valor de dicha expresión es 0, entonces se toma como "falso" y no se realiza el cuerpo de if y por otra parte, el compilador tomará como "verdadero" todo valor distinto de 0, y en ese caso se ejecuta el cuerpo de la instrucción while. Lo primero que "ve" el compilador dentro de los paréntesis externos es una condición:
EOF != (expresion) ¿Qué es EOF? EOF es el caracter que indica el fin del archivo. En los sistemas Unix el fin de archivo es Ctrl D, en tanto que en los sistemas windows es Ctrl C. Si usa un sistema distinto, deberá averiguar cuál es la combinación de teclas que indican EOF. EOF tiene un valor determinado por la plataforma en la que programe. Este valor tiene que ser tal que no se pueda confundir con cualquier carácter válido (como a, b, c, \t, etc). Generalmente se trata de un número negativo (-1). La condición dentro de los paréntesis de while dice "mientras el carácter leído sea distinto de EOF, realiza este cuerpo de instrucciones". Pero ¿qué hay a la derecha del operador relacional !=? Este operador es un operador "izquierdo", toma el valor de la izquierda y lo compara con el de la derecha. A su derecha, y entre paréntesis aparece la expresión x = getchar() ¿Por qué aparece esta expresión entre paréntesis? Porque la precedencia del operador relacional != es superior a la del operador de asignación =. De no haber paréntesis, el compilador primero compararía el valor de c con EOF y luego trataría de asignar el valor de getchar() a la cantidad que se encuentra a la izquierda de =, lo cual provocará un error en la compilación; en este caso los paréntesis son necesarios. Por lo tanto, después de evaluar el valor de EOF, el compilador evalúa la expresión c = getchar(), y aquí se encuentra una expresión que contiene al operador = de asignación. La asociatividad de = es de derecha a izquierda, primero se evalúa la expresión a la derecha y eso se le asigna a la variable c. Pero la expresión de la derecha es una invocación de la función getchar(), definida en el encabezado stdio.h Esa función lo que hace es recibir un carácter de la entrada. La sintaxis general de la función getchar es la siguiente:

int getchar(void)

La función retorna un entero (el valor del carácter leído) y no recibe ningún parámetro. Este valor entero se asigna a la variable c, que se ha declarado previamente como tipo int. Y es ese valor, el de c, el que se compara con EOF. Si el carácter leído es distinto a EOF, entonces se lee el siguiente y así. Se trata pues de un ciclo while controlado por centinela.

putchar(c);

El cuerpo de while consta de una sola instrucción: la función putchar, la cual recibe un entero y retorna también un entero. Esos int son los valores de un carácter. La forma general de la función putchar es la siguiente:

int putchar(int caracter);

En este programa, putchar(c) simplemente envía a la salida estándar el carácter que getchar() acaba de leer.

return 0;

La instrucción return 0; como en todos los programas, indica que se ha terminado el programa satisfactoriamente.

} /* Cierra main */

Esta llave indica el fin del cuerpo de main. Muchas veces le va a ocurrir que hay cuerpos de instrucciones que contienen llaves sin cerrar. Para evitar esto, créese el buen hábito de cerrar el cuerpo antes de escribir las instrucciones. También acostúmbrese a indicar, en cada caso, a qué instrucción corresponden las llaves.
_______________________________________________________________________________________________
Lo que aprendió:
El significado de EOF
La función getchar()
La función putchar()
_______________________________________________________________________________________________
Esta entrada forma parte del Curso de C con Programas Explicados Línea por Línea
Índice
Entrada Anterior
Entrada Siguiente
Related Posts Plugin for WordPress, Blogger...