Mostrando entradas con la etiqueta Elementos básicos. Mostrar todas las entradas
Mostrando entradas con la etiqueta Elementos básicos. Mostrar todas las entradas

K&R

2009/12/06
Navegando me encontré con un libro fundamental que, lo juro, nunca he tenido en las manos. Hasta ahora.

Yo conocí C mediante mis apuntes de otros lenguajes y de pequeños manuales en la red -como éste blog-, y de fotocopias de un libro arcaico y poco claro de Herbert Schildt. Pero para conocer el lenguaje sin más esperas, al ritmo que a cada uno le convenga, y sobre todo, explicado por los autores (Ritchie es  un grande entre los grandes de esta ciencia), nada mejor que el libro.






Gracias a la web LuChOeDu, que lo pone al alcance de todos.

Estructuras de control

2009/07/21
Bucles: for

En programación, un bucle es una estructura de control que permite que se ejecuten un conjunto de instrucciones repetidamente, según una condición. Si se requieren ejecutar sentencias más de una vez, for u otros bucles son una gran utilidad.

Lo primero que se dice sobre una estructura de control es su forma general. Para for es

for(inicialización; condición; incremento)
{
|||||||sentencia0;
|||||||sentencia1;
|||||||...
|||||||...
}

Ahora: ¿inicialización de qué? ¿Incremento de qué?

La inicialización suele ser la asignación de un valor inicial para una variable que llamaremos "variable de control". El incremento es cuánto cambiará la variable de control para el próximo ciclo. La condición es simplemente una expresión relacional que define cómo y cuándo terminará el bucle. Observe que cada una de las partes que conforman el bucle for son separadas por un punto y coma (;).

Reflexiónelo un momento: sin bucles, la manera de imprimir los números 1 a 500 -por decir algo- sería escribiendo printf() o funciones parecidas ¡quinientas veces! Lo cual, además de poco práctico y nada elegante, será un seguro desastre: lo reto a demostrar que tiene la paciencia necesaria. Empleando for, esa misma tarea se vería reducida a unas cuantas líneas de código, siguiendo estos pasos:

1) Declarar la variable de control como entero. Por ejemplo: int x.
2) Construir la estructura for. Asignarle 1 a x como valor inicial (x=1).
3) Establecer la condición. Por ejemplo, mientras x sea menor o igual que 500, que se ejecuten las sentencias (x <= 500).
4) Definir el incremento. De cinco en cinco (x+=5), de dos en dos (x+=2), de uno en uno... (x++ ó x+=1); como usted lo decida.

for(x = 1; x <= 500; x++) printf(" %d", x);

Nota: expresiones como x+=2 son pequeñas abreviaciones. En este caso, x += 2 es equivalente a x = x + 2 (x igual a sí mismo más dos). No está limitado a la suma o acumulación; también son posibles asignaciones como -=, *=, etc...



Tabla del 11


La instrucción for de C, comparada con sus equivalentes en otros lenguajes, es por mucho más flexible y adaptable, ya que se le puede escribir de muchas maneras: como al trasladar la inicialización fuera de él; obviar el incremento -aunque trasladándolo a otro sitio, de lo contrario provocaría un bucle infinito- o cosas aún más extravagantes: ¡inicializar varias variables en el mismo bucle for!

El siguiente ejemplo es perfectamente válido.

for(x = 0, y = 20; x <= y; x++, y--)
|||||||printf(" %d %d \n", x, y);

Lo que produciría en pantalla la siguiente salida.




Haga sus pruebas.

Estructuras de control

2009/07/20
Condicionales o de decisión: switch

Implícitamente switch manifiesta elegancia. Ya que, una vez que se conoce, uno se da cuenta que es una forma práctica y muy ordenada de evaluar constantes.

Su forma general es

switch(variable) {
|||||||case constante0:
|||||||||||||||sentencias;
|||||||case constante1:
|||||||||||||||sentencias;
|||||||case constante2:
|||||||||||||||sentencias;

||||||||||...

|||||default:
|||||||||||||||sentencias;
}


En primer lugar, switch evalúa una y sólo una variable. Según qué constante esté almacenada en la variable será el "case" cuyas sentencias se habrán de ejecutar.
Si ningún "case" corresponde a la constante de la variable evaluada, y existe "default" -cuyo uso es completamente alternativo: puede o no presentarse-, serán las sentencias de "default" las ejecutadas.

Como verá, su uso es muy simple. Ponga atención al siguiente ejemplo.



Todos los "case" ejecutarán la misma sentencia, sin importar cuál sea el que contenga la constante correcta. En este caso, mientras la variable sea igual a una vocal, los "case" correspondientes retornarán el valor 1, para Verdadero. Si la variable no almacena una vocal, será "default" la culpable de retornar 0.

Ahora, si lo importante fuese evaluar un caracter en particular, habría que recurrir al uso de la sentencia break por cada "case".
break utilizada dentro de cada "case" provoca que el control del programa salga del bloque switch y continúe justo después donde éste acaba. Sin break en cada "case" -como en el ejemplo-, todas las sentencias se ejecutarán.

Repetición simplificada: cada "case" se ejecutará uno detrás de otro, a menos que exista la sentencia break entre ellos.

En programas de sólo texto (como todos los ejemplos mostrados aquí) switch es a menudo empleada para comprobar una entrada en el teclado y ejecutar las sentencias que correspondan; pudiendo llamar a otras funciones y/o procedimientos adecuados. Observe un menú como ejemplo.



Nota: Tratándose de un caracter individual (tipo de dato char) siempre se escribirá en comillas simples: case 'a', case '5', etc.

En el fondo, switch es una escalera if - else if muy ordenada que sólo evalúa igualdades; nunca expresiones relacionales ni lógicas.

Estructuras de control

2009/07/18
Condicionales o de decisión: if

Este tipo de estructuras permiten decidir qué líneas de código se ejecutarán, según una condición concreta. En español, la sentencia if es parecida a la frase "Si... [Condición], entonces... [Resolución]".

La forma más simple de la sentencia es

if(condición) sentencia;

ó

if(condición)
|||||||sentencia;

Cuando se escriba más de una sentencia dentro de la misma estructura deben agregarse llaves de inicio y fin.

if(condición) {
|||||||sentencia0;
|||||||sentencia1;
|||||||sentencia2;
}

Si la condición es cierta, las sentencias se ejecutarán. De lo contrario, el programa continuará justo después del final del bloque if.

En ocasiones es conveniente analizar varias condiciones. Asímismo es conveniente tener una salida o escapatoria para cuando ninguna condición se cumple. Es entonces cuando se emplea la escalera if-else if.

if(condición)
|||||||sentencia;
else if(condición)
|||||||sentencia;
else if(condición) {
|||||||sentencia0;
|||||||sentencia1;
|||||||sentencia2;
}
else if(condición)
|||||||sentencia;
else |||||||||||||||||||||//Se cumplirá sólo si las anteriores son falsas
|||||||sentencia;|||||

Una condición es una expresión lógica; con operadores relaciones y lógicos, tal como 5 <= 2 y 42 == 20 + 20 + 2, falso y verdadero, respectivamente.

Las condiciones se evalúan de arriba a abajo. Cuando una condición sea cierta se ejecutan las sentencias asociadas a ella y se ignora el resto de condiciones. Si ninguna es cierta, y existe 'else', será 'else' la que se ejecute. Si no hay 'else' y todas las condiciones fallan, no ocurrirá ninguna acción.

Ejemplos:







Encuentre las diferencias.

Elementos básicos

2009/07/10
A continuación, el esqueleto de un programa:

  • Comentarios
  • #include y archivos de cabecera
  • La función main()
  • El caracter de nueva línea (\n)
  • Puntos y comas, llaves
  • Compilación

Ejemplo:
-----------------------------------------------------

/* Esto es un comentario */
// También es un comentario

#include '<'stdio.h'>' ||| // <---NO lleva comillas.
main()
{
|||||||
printf (" ¡Mirad! ¡Mi primer programa! \n");
|||||||return 0;
}

-----------------------------------------------------

Comentarios

Lo primero que vemos al examinar el ejemplo son las 2 formas de escribir comentarios en C. La primera, con un signo de apertura (/*) y uno de cierre (*/). La segunda, asimilada de C++, consta solamente de dos barras.

El motivo y la utilidad de los comentarios es principalmente como herramienta de aclaración, recordatorio, o apunte sobre el programa. Es decir, como documentación propia. Existe la posibilidad de que tiempo después de haber desarrollado un programa, el programador se olvide por completo de él; cuando el programador retome su programa, los comentarios que haya hecho en el código le harán más sencillo entender y recordar exactamente qué había hecho. Otra razón sería explicar brevemente lo que alguna parte del código hace. Esto ayuda mucho cuando alguien más tiene que ver el código. Incluso al depurar, el empleo de comentarios es por demás útil.

Los comentarios no afectan sobre el funcionamiento del binario ejecutable ni sobre el tamaño del mismo, así como tampoco afectan de intromisión al código. La razón es que el compilador ignora todo lo que haya entre las marcas de comentarios (/* */), o entre marca y fin de línea (// ).


#include y archivos de cabecera

En el ejemplo, la primera línea valiosa de código es #include

La instrucción #include le comunica al preprocesador de C (un programa llamado por el compilador) que hay que buscar un archivo y colocar el contenido en el lugar correspondiente. stdio.h es ése archivo. El lugar de búsqueda obedece a la indicación que rodea a stdio.h. Si los signos son comillas dobles ("stdio,h"), el preprocesador buscará el archivo en el directorio actual. Por el contrario, si son llaves lo que rodean el nombre del archivo (), el preprocesador buscará en un directorio diferente del actual (/usr/include y c:\Compilador\include son 2 ejemplos).

stdio.h es quizá uno de los archivos fundamentales de un programa: sus funciones se encargan de la entrada y salida. Provee de funciones como printf(). Su nombre significa "standard input-output header file". Y sí, fue escrita por el desarrollador del compilador (por lo que es posible que en distintos compiladores haya diferencias mínimas).

Función main()

Es la función que se llama cuando se ejecuta el programa. Cada programa debe tener una y sólo una función principal, pues si hubiera más de una, ¿por dónde comenzaría el programa? De todos modos el compilador detectaría un error como ése. Es la función de donde parte el funcionamiento del programa: al llegar a la llave que cierra la función, el programa termina de ejecutarse (aunque hay otros modos de salir del programa).

Esta función puede estar colocada al principio, en medio o al final del fichero donde se escribe el código. Da igual. Sin embargo, por claridad es recomendable colocar la función al principio.

En el ejemplo sólo existe la función main(). En programas más complejos es conveniente dividir las tareas y emplear mas funciones.


Caracter de línea nueva (\n)

Una de las cosas que más escribo es el símbolo '\n', siempre con printf(). Lo menciono ahora porque su uso es frecuente y sería útil familiarizarse con él.

Básicamente, y según cómo se emplee, hace 2 cosas: generar el fín de línea y generar una línea nueva.

Ejemplos:

-----------------------------------------------------------------------
// 1)
#include '<'stdio.h'>'
main()
{
|||||||printf("\n\n\n Apuesto a que el prompt terminará pegado a mí");
}


Ese código se mostraría así:


Tres líneas vacías. Al final se junta con el prompt.
-----------------------------------------------------------------------

// 2)
#include '<'stdio.h'>'
main()
{
|||||||
printf(" Hola, enfermera \n\n");

}

Visualización:

Muestra el texto y termina la línea. Luego, línea vacía. Observe el prompt ahora.

-----------------------------------------------------------------------


Puntos y comas y llaves

En C, la mayoría de las sentencias terminan en punto y coma.

x=y;
a = b + c + d * 5;
sqrt(num);

Excepto al declarar una función, así como tampoco en la llave inicial ni final de cualquier función o estructura.

int calculo()
{
|||||||x=y; a = b + c + d * 5; sqrt(num);
}

Observe cómo las sentencias fueran colocadas intencionalmente en la misma línea. Esto es válido, ya que la función de los punto y coma (;) es precisamente reconocer el final de una sentencia. Aunque... No es muy agradable leer código escrito así.

Nota: ¡Recuerde la indentación! Por favor escriba con sangría.


Compilación

Por lo pronto, y tratándose de archivos pequeños, este proceso es bastante sencillo una vez que se conoce.

En mi caso, desde la línea de comandos hago esto:
1) Me coloco en el directorio donde esté guardado el código fuente
2) Llamo al compilador, escribiendo el nombre del programa como parámetro.
3) Ejecuto.
4) Si es necesario, depuro y vuelvo al paso 1.

Al final, lo que escribiría sería algo como:
$ gcc NombrePrograma.c -o NombreNuevo.loquesea

Si usted utiliza otro compilador, averigüe cuáles son los detalles y especificaciones de su compilador y los pasos a seguir.