2. :
es un paradigma de programación orientado a mejorar la
claridad, calidad y tiempo de desarrollo de un programa de
computadora, utilizando únicamente subrutinas y tres
estructuras: secuencia, selección (if y switch)
e iteración (bucles for y while), considerando innecesario y
contraproducente el uso de la instrucción de transferencia
incondicional (GOTO), que podría conducir a "código
espagueti", que es mucho más difícil de seguir y de
mantener, y era la causa de muchos errores de
programación.
Surgió en la década de 1960, particularmente del trabajo
de Böhm y Jacopini,1
y una famosa carta ,La sentencia goto
considerada perjudicial, de Edsger Dijkstra en 19682
— y
fue reforzado teóricamente por el teorema del programa
estructurado, y prácticamente por la aparición de
lenguajes como ALGOL con adecuadas y ricas estructuras
de control.
3. A finales de los años 1970 surgió una nueva forma de
programar que no solamente daba lugar a programas fiables
y eficientes, sino que además estaban escritos de manera
que facilitaba su mejor comprensión, no sólo proveyendo
ventajas durante la fase de desarrollo, sino también
posibilitando una más sencilla modificación posterior.
El teorema del programa estructurado, propuesto por
Böhm-Jacopini, demuestra que todo programa puede
escribirse utilizando únicamente las tres instrucciones de
control siguientes:
Secuencia
Instrucción condicional.
Iteración (bucle de instrucciones) con condición al
principio.
Solamente con estas tres estructuras se pueden escribir
todos los programas y aplicaciones posibles. Si bien
los lenguajes de programación tienen un mayor repertorio
de estructuras de control, éstas pueden ser construidas
mediante las tres básicas citadas.
4. El teorema del programa estructurado proporciona la base
teórica de la programación estructurada. Señala que tres
maneras de combinar programas son suficientes para
expresar cualquier función computable: secuencia,
selección e iteración. Esta observación no se originó con el
movimiento de la programación estructurada. Estas
estructuras son suficientes para describir el ciclo de
instrucción de una unidad central de procesamiento, así
como el funcionamiento de una máquina de Turing.
Por lo tanto un procesador siempre está ejecutando un
"programa estructurado" en este sentido, incluso si las
instrucciones que lee de la memoria no son parte de un
programa estructurado. Sin embargo, los autores
usualmente acreditan el resultado a un documento escrito
en 1966 por Böhm y Jacopini, posiblemente
porque Dijkstra había citado este escrito.
El teorema del programa estructurado no responde a cómo
escribir y analizar un programa estructurado de manera
útil. Estos temas fueron abordados durante la década de
1960 y principio de los años 1970, con importantes
contribuciones de Dijkstra, Robert W. Floyd, Tony
Hoarey y David Gries.
5. A finales del siglo XX casi todos los científicos están
convencidos de que es útil aprender y aplicar los conceptos
de programación estructurada. Los lenguajes de
programación de alto nivel que originalmente carecían de
estructuras de programación,
como FORTRAN, COBOL y BASIC, ahora las tiene.
Ventajas de la programación estructurada comparada con
el modelo anterior (hoy llamado despectivamente código
espagueti).
Los programas son más fáciles de entender, pueden ser
leídos de forma secuencial y no hay necesidad de hacer
engorrosos seguimientos en saltos de líneas (GOTO)
dentro de los bloques de código para intentar entender
la lógica.
La estructura de los programas es clara, puesto que las
instrucciones están más ligadas o relacionadas entre sí.
6. Reducción del esfuerzo en las pruebas y depuración. El
seguimiento de los fallos o errores del programa
("debugging") se facilita debido a su estructura más
sencilla y comprensible, por lo que los errores se pueden
detectar y corregir más fácilmente.
Reducción de los costos de mantenimiento.
Análogamente a la depuración, durante la fase de
mantenimiento, modificar o extender los programas
resulta más fácil.
Los programas son más sencillos y más rápidos de
confeccionar.
Se incrementa el rendimiento de los programadores,
comparado con la forma anterior que utiliza GOTO.
7. Los programas estructurados con frecuencia están
compuestos de simples estructuras de flujo de programa
jerárquicas. Estas son secuencia, selección y repetición:
"Secuencia" se refiere a una ejecución ordenada de
instrucciones.
En "selección", una de una serie de sentencias es
ejecutada dependiendo del estado del programa. Esto es
usualmente expresado con palabras clave como
if..then..else..endif, switch, o case. En algunos lenguajes
las palabras clave no se puede escribir textualmente,
pero debe ser delimitada (stropped).
En la "repetición" se ejecuta una sentencia hasta que el
programa alcance un estado determinado, o las
operaciones han sido aplicadas a cada elemento de una
colección. Esto es usualmente expresado con palabras
clave como while, repeat, for o do..until. A menudo se
8. recomienda que cada bucle sólo debe tener un punto de
entrada (y en la programación estructural original,
también sólo un punto de salida, y pocos lenguajes
refuerzan esto).
En el siguiente ejemplo, el programa pide al usuario que
introduzca un número. El programa dividirá dicho número
entre 2 e imprimirá el resultado mientras que este sea par,
y terminará cuando el número sea impar:
#include <stdio.h>
int main(void) {
int numero;
fputs("Introduzca un número entero par: ",
stdout);
scanf("%d", &numero);
if (!numero) {
fputs("Error: numero no valido.n",
stderr);
return -1;
}
int i = 1;
while (numero%2 == 0) {
printf ("%.3d| %d/2 = %d.n", i++,
numero, numero /= 2);
}
9. printf ("No se puede seguir dividiendo: El
numero %d es impar.n", numero);
return 0;
}
Las funciones son las estructuras más importantes dentro
del lenguaje de programación C (y en general de cualquier
lenguaje procedural). Permiten una programación
estructurada y simplifican la lectura del código; pero lo
más importante es que, una función sencilla que realiza una
tarea bien específica, puede ser reutilizada con extrema
facilidad en cualquier otro programa.
El uso y construcción de funciones propias es una tarea
fácil y eficiente. La construcción de una función involucra
dos pasos:
1. Declaración de la función (prototipo). Esto consiste en
declarar la función indicando el nombre, el tipo de
retorno que posee, y el número y tipo de argumentos
que recibe. Esta declaración puede realizarse o bien
en el mismo archivo fuente, o en un header file
(típicamente con extensión ".h") e incluirse mediante
la directiva #include.
2. Definición de la función., o implementación del código
mismo. Que puede realizarse también en un archivo
separado que se incluye en la línea de compilación.
10. /* Programa que imprime una serie de potencias de�
2 y -
3�������������������������������
�������
*/
#include <stdio.h>
int power(int x, int n);� /* Prototipo de la
funci�n� */
main()
{
� int i;
� for(i = 0; i < 10; i++)
��� printf("%d %d %dn", i, power(2,i), power(-
3,i));
}
/* Definici�n de la funci�n
Power�������������������� */
int power(int x, int n)
{
� int i, p = 1;
� for(i=1; i <= n; i++)
��� p = p * x;
� return p;
}
Para llamar una función se escribe su nombre seguido por
una lista de argumentos encerrados entre paréntesis.
11. 1-Una función retorna un resultado del tipo declarado al
definir la función; por eso puede ser empleada en cualquier
expresión donde sea válida una variable del tipo retornado.
En nuestro caso, cada printf llama dos veces a la
función power().
2-Los nombres de los argumentos, así como el de las
variables son locales a las funciones. El primer valor pasado
se corresponde con el primer argumento de la función, es
segundo valor con el segundo argumento, y así, return
... devuelve el valor calculado.
3- La expresión retornada debe ser del tipo declarado. Si
la función posee retorno void, significa que no retorna
nada, lo mismo ocurre para funciones que poseen
argumento void.
En general, en cualquier lenguaje de programación de alto
nivel, se permiten dos maneras de pasaje de argumentos:
por valor y por referencia, uno soportado en forma
estándar y el otro a través de una forma alternativa.
Cuando un argumento se pasa por valor, la función llamada
recibe una copia del argumento, pudiendo modificarla
libremente sin alterar el valor original.
12. Cuando un argumento se pasa por referencia, más que el
valor mismo del argumento, lo que se pasa es la dirección
de memoria donde ese valor está almacenado. Por lo tanto,
la función llamada puede modificar el valor original
directamente.
La forma de pasajes de argumentos estándar del lenguaje
C es realizar este pasaje por valor. Si, en cambio, el
argumento pasado es un arreglo, lo que en realidad se pasa
a la función llamada es la dirección de memoria del primer
elemento del arreglo.
/* Ejemplo de tipos de pasaje de argumentos� */
#include <stdio.h>
void Permuta(int v1, int v2);
void PermutaArray(int v12[]);
main()
{
� int x=1, y=2;
� int a[] = {1,2};
� printf("Antes:�� x=%d, y=%dn",x,y);
� Permuta(x,y);
� printf("Despu�s: x=%d, y=%dn",x,y);
� printf("Antes:�� a={%d,%d}n",a[0],a[1]);
� PermutaArray(a);
� printf("Despu�s: a={%d,%d}n",a[0],a[1]);
}
/* Permuta dos variables???�� */
void Permuta(int x, int y)
{
� int aux;
� aux = x;
� x=y;
13. � y=aux;
}
/* Permuta dos elementos de un arreglo???�� */
void PermutaArray(int x[])
{
� int aux;
� aux = x[0];
� x[0]=x[1];
� x[1]=aux;
}
Según el lugar donde son declaradas puede haber dos tipos
de variables.
Globales: las variables permanecen activas durante todo
el programa. Se crean al iniciarse este y se destruyen de la
memoria al finalizar. Pueden ser utilizadas en cualquier
función.
Locales: las variables son creadas cuando el programa
llega a la función en la que están definidas. Al finalizar la
función desaparecen de la memoria.
Si dos variables, una global y una local, tienen el mismo
nombre, la local prevalece sobre la global dentro de la
función en que ha sido declarada.
Dos variables locales pueden tener el mismo nombre
siempre que estén declaradas en funciones diferentes.
14. /* Uso de variable con distintos �mbitos� */
#include <stdio.h>
void Func(void);
int VarX = 25;����� /* Variable global���
*/
void main()
{
� printf("Valor de VarX: %dn", VarX);
� Func();
� printf("Valor de VarX: %dn", VarX);
}
void Func()
{
� int VarX = 40;� /* Local a la funci�n,
oculta la global*/
� printf("Valor de VarX: %dn", VarX);