Está en la página 1de 17

ESTRUCTURA ALGORITMICAS

SECUENCIALES - asignacin - entrada - salida DECISION - simples - dobles - multiples (case) REPETITIVAS - While - Do while - For

Estructuras Condicionales En este captulo se revisan los distintos mtodos con los que C controla el flujo lgico de un programa. Como se revis en el captulo anterior, los operadores relaciones binarios que se usan son: ==, !=, <, <=, > y >= adems los operadores lgicos binarios: ||, && y el operador lgico unario de negacin !, que slo toma un argumento. Los operadores anterior son usados con las siguientes estructuras que se muestran.

3.1 La sentencia if Las tres formas como se puede emplear la sentencia if son: if (condicion) sentencia;

...o if (condicion) sentencia1; else sentencia2; ...o if (condicion1) sentencia1; else if (condicion2) sentencia2; ... else sentencian; El flujo lgico de esta estructura es de arriba hacia abajo. La primera sentencia se ejecutar y se saldr de la estructura if si la primera condicin es verdadera. Si la primera condicin fue falsa, y existe otra condicin, se evala, y si la condicin es verdadera, entonces se ejecuta la sentencia asociada. Si existen ms condiciones dentro de la estructura if, se van evaluando stas, siempre y cuando las condiciones que le precedan sean falsas. La sentencia que esta asociada a la palabra reservada else, se ejecuta si todas las condiciones de la estructura if fueron falsas. Por ejemplo: main() { int x, y, w; ........ if (x>0) { z=w; ....... } else { z=y; ....... } }

3.2 El operador ? El operador ternario condicional ? es ms eficiente que la sentencia if. El operador ? tiene el siguiente formato: expresion1 ? expresion 2 : expresion3; Que es equivalente a la siguiente expresin: if (expresion1) then expresion2 else expresion3; Por ejemplo, para asignar el mximo de a y b a la variable z, usando ?, tendramos: z = (a>b) ? a : b; que es lo mismo que: if (a > b) z = a; else z = b; El uso del operador ? para reemplazar las sentencias if ... else no se restringe slo a asignaciones, como en el ejemplo anterior. Se pueden ejecutar una o ms llamadas de funcin usando el operador ?ponindolas en las expresiones que forman los operandos, como en el ejemplo siguiente: f1(int n) { printf("%d ",n); } f2() { printf("introducido\n"); } main() { int t; printf(": "); scanf("%d",&t); /* imprime mensaje apropiado */ t ? f1(t) + f2() : printf("Se di un cero\n"); }

3.3 La sentencia switch Aunque con la estructura if ... else if se pueden realizar comprobaciones mltiples, en ocasiones no es muy elegante, ya que el cdigo puede ser difcil de seguir y puede confundir incluso al autor transcurrido un tiempo. Por lo anterior, C tiene incorporada una sentencia de bifurcacin mltiple llamada switch. Con esta sentencia, la computadora comprueba una variable sucesivamente frente a una lista de constantes enteras o de caracter. Despus de encontrar una coincidencia, la computadora ejecuta la sentencia o bloque de sentencias que se asocian con la constante. La forma general de la sentencia switch es: switch (variable) { case constante1: secuencia de sentencias break; case constante2: secuencia de sentencias break; case constante3: secuencia de sentencias break; ... default: secuencia de sentencias } donde la computadora ejecuta la sentencia default si no coincide ninguna constante con la variable, esta ltima es opcional. Cuando se encuentra una coincidencia, la computadora ejecuta las sentencias asociadas con el case hasta encontrar la sentencia break con lo que sale de la estructura switch. Las limitaciones que tiene la sentencia switch ... case respecto a la estructura if son:

Slo se tiene posibilidad de revisar una sola variable. Con switch slo se puede comprobar por igualdad, mientras que con if puede ser con cualquier operador relacional. No se puede probar ms de una constante por case. La forma como se puede simular el ltimo punto, es no teniendo sentencias asociados a un case, es decir, teniendo una sentencia nula donde slo se pone el caso, con lo que se permite que el flujo del programa caiga al omitir las sentencias, como se muestra a continuacin:

switch (letra) { case 'a': case 'e': case 'i': case 'o': case 'u': numvocales++; break; case ' ': numesp++; break; default: numotras++; break; } 3.4 Ejercicios 1. Escribir un programa que lea dos caracteres, e imprima su valor cuando se pueda interpretar como un nmero hexadecimal. Aceptar letras maysculas y minsculas para los valores del 10 al 15. 2. Leer un valor entero. Suponer que el nmero es un da de la semana. Suponer que 0 corresponde a Domingo y as sucesivamente. Imprimir el nombre del da. 3. Dados como entrada 3 enteros representando la fecha como da, mes, ao, imprimir la fecha del da anterior. Por ejemplo para una entrada como: 1 3 1992 La salida ser: Fecha anterior a 1-3-1992 es 29-02-1992 4. Escribir un programa el cual lea dos valores enteros. Si el primero es menor que el segundo, que imprima el mensaje ``Arriba''. Si el segundo es menor que el primero, que imprima el mensaje ``Abajo''. Si los nmeros son iguales, que imprima el mensaje ``igual''. Si hay un error en la lectura de los datos, que imprima un mensaje conteniendo la palabra ``Error'' y haga exit( 0 );

#include <stdio.h> #include <conio.h> #include <iostream.h> int main () { clrscr(); for (int i=1;i<=20;i++) { cout<<i; if (i%3==0) cout<<" Es multiplo de 3" <<endl; else cout<<" No es multiplo de 3"<<endl; } getch(); return 0; }

include <stdio.h> #include <conio.h.> int main () { int A, B, C; printf("Inserte valor para A: "); scanf("%d",&A); printf("Inserte valor para B: "); scanf("%d",&B); printf("Inserte valor para C: "); scanf("%d",&C); printf("\n%d + %d - %d + 100 = %d",A, B, C, (A+B+C-100)); getch(); }

#include <stdio.h> #include <conio.h> int main ()

{ int a, b; printf("Inserte valor a: "); scanf("%d",&a); printf("Inserte valor b: "); scanf("%d",&b); printf("(%d-%d) (%d+%d) = %d",a, b, a, b,((a-b)*(a+b))); getch(); }

#include <stdio.h> #include <conio.h> int main () { int numero, sum_dig=0; printf("Inserte un numero de 3 digitos: "); scanf("%d",&numero); if (numero>=100) { int num=numero; //salvamos en num, la variable numero while (numero!=0) { sum_dig=sum_dig+(numero%10); //para sacar el ultimo digito de numero numero=numero/10; //elimina el ultimo digito de numero } printf("La suma de los digitos de %d es : %d",num, sum_dig); } else printf("\a ERROR: El digito no tiene 3 digitos"); getch(); }

#include <stdio.h> #include <conio.h> int main () { int numero; printf("Inserte num. de dos digitos pares: ");

scanf("%d",&numero); int aux=numero; if(numero<100 && numero>9) { int d1=numero%10; numero=numero/10; int d2=numero%10; if(d1%2==0 & d2%2==0) printf("El promedio d los digitos de %d es: %d",aux,(d1+d2)/2); } else printf("\aERROR: el numero no tiene dos digitos"); getch(); }

#include <stdio.h> #include <conio.h> int facto (int x) { int f=1; for (int i=1;i<=x;i++) {f=f*i;} return (f); } int main () { int n, serie=2, suma=0; printf ("Inserte cantidad de terminos a generar: "); scanf ("%d",&n); for (int i=1;i<=n;i++) { printf ("%d! + ",serie); suma=suma+(facto(serie)); serie=serie+2; } printf (" = %d",suma); getch(); }

#include <stdio.h> #include <conio.h> int main () { int serie=1; bool sw=true; do { printf("%d, ",serie); if (sw) serie+=4; else serie-=2; sw=!sw; } while (serie<=23); getch(); }

#include<stdio.h> #include<conio.h> int main () { int n, c=1, serie=5; printf("Cantidad de terminos: "); scanf("%d",&n); while(c<=n) { printf("%d,",serie); serie+=5; c++; } getch(); }

El concepto de constante (expresin con la palabra reservada const) se cre para permitir a los programadores marcar la diferencia entre lo que puede cambiar y lo que no. Esto facilita el control y la seguridad en un proyecto de programacin. Desde su origen, const ha sido utilizada para diferentes propsitos. Mientras tanto FIXME:it trickled back en el lenguaje C en el que su significado cambi. Todo esto puede parecer un poco confuso al principio, y en este captulo aprender cundo, porqu y cmo usar la palabra reservadaconst. Hacia el final se expone una disertacin sobre volatile, que es familia de const (ambos se refieren a los cambios) y su sintaxis es idntica. El primer motivo para la creacin de const parece que fue eliminar el uso de la directiva del preprocesador #define para sustitucin de valores. Desde entonces se usa para punteros, argumentos de funciones, tipos de retorno, objetos y funciones miembro. Todos ellos tienen pequeas diferencias pero su significado es conceptualmente compatible. Se tratarn en las siguientes secciones de este captulo. 8.1. Sustitucin de valores Cuando se programa en C, se usa libremente el preprocesador para crear macros y sustituir valores. El preprocesador simplemente hace un reemplazo textual y no realiza ninguna comprobacin de tipo. Por ello, la sustitucin de valores introduce pequeos problemas que se pueden evitar usando valores constantes. El uso ms frecuente del preprocesador es la sustitucin de valores por nombres, en C es algo como:

#define BUFSIZE 100

BUFSIZE es un nombre que slo existe durante el preprocesado. Por tanto, no ocupa memoria y se puede colocar en un fichero de cabecera para ofrecer un valor nico a todas las unidades que lo utilicen. Es muy importante para el mantenimiento del cdigo el uso de sustitucin de valores en lugar de los tambin llamados nmeros mgicos. Si usa nmeros mgicos en su cdigo. no solamente impedir al lector conocer su procedencia o significado si no que complicar innecesariamente la edicin del cdigo si necesita cambiar dicho valor. La mayor parte del tiempo, BUFSIZE se comportar como un valor ordinario, pero no siempre. No tiene informacin de tipo. Eso puede esconder errores difciles de localizar. C++ utiliza const para eliminar estos problemas llevando la sustitucin de valores al terreno del compilador. Ahora, puede escribir:

const int bufsize = 100;

Puede colocar bufsize en cualquier lugar donde se necesite conocer el valor en tiempo de compilacin. El compilador utiliza bufsize para hacer propagacin de constantes[61], que significa que el compilador reduce una expresin constante complicada a un valor simple realizando los clculos necesarios en tiempo de compilacin. Esto es especialmente importante en las definiciones de vectores:

char buf[bufsize];

Puede usar const con todos los tipos bsicos(char, int, float y double) y sus variantes (as como clases y todo lo que ver despus en este captulo). Debido a los problemas que introduce el preprocesador deber utilizar siempre const en lugar de #define para la sustitucin de valores. 8.1.1. const en archivos de cabecera Para poder usar const en lugar de #define, debe ser posible colocar las definiciones const en los archivos de cabecera como se haca con los #define. De este modo, puede colocar la definicin de una constante en un nico lugar y distribuirla incluyendo el archivo de cabecera en las unidades del programa que la necesiten. Una constante en C++ utiliza enlazado interno, es decir, es visible slo desde el archivo donde se define y no puede verse en tiempo de enlazado por otros mdulos. Deber asignar siempre un valor a las constantes cuando las defina, excepto cuando explcitamente use la declaracin extern:

extern const int bufsize;

Normalmente el compilador de C++ evita la asignacin de memoria para las constantes, pero en su lugar ocupa una entrada en la tabla de smbolos. Cuando se utiliza extern con una constante, se fuerza el alojamiento en memoria (esto tambin ocurre en otros casos, como cuando se solicita la direccin de una constante). El uso de la memoria debe hacerse porque extern dice usa enlazado externo, es decir, que varios mdulos deben ser capaces de hacer referencia al elemento, algo que requiere su almacenamiento en memoria. Por lo general, cuando extern no forma parte de la definicin, no se pide memoria. Cuando la constante se utiliza simplemente se incorpora en tiempo de compilacin. El objetivo de no almacenar en memoria las constantes tampoco se cumple con estructuras complicadas. Cuando el compilador se ve obligado a pedir memoria no puede realizar propagacin de constantes (ya que el compilador no tiene forma de conocer con seguridad que valor debe almacenar; si lo conociese, no necesitara pedir memoria). Como el compilador no siempre puede impedir el almacenamiento para una constante, las definiciones de constantes utilizan enlace interno, es decir, se enlazan slo con el mdulo en que se definen. En caso contrario, los errores de enlace podran ocurrir con las expresiones constantes complicadas ya que causaran peticin de almacenamiento en diferentes mdulos. Entonces, el enlazador vera la misma definicin en mltiples archivos objeto, lo que causara un error en el enlace. Como las constantes utilizan enlace interno, el enlazador no intenta enlazar esas definiciones a travs de los mdulos, y as no hay colisiones. Con los tipos bsicos, que son los se ven involucrados en la mayora de los casos, el compilador siempre realiza propagacin de constantes. 8.1.2. constantes seguras El uso de las constantes no est limitado a la sustitucin de los #define por expresiones constantes. Si inicializa una variable con un valor que se produce en tiempo de ejecucin y sabe que no cambiar durante la vida de la variable, es una buena prctica de programacin hacerla constante para que de ese modo el compilador produzca un mensaje de error si accidentalmente alguien intenta modificar dicha variable. Aqu hay un ejemplo:

//: C08:Safecons.cpp // Using const for safety #include <iostream>

using namespace std;

const int i = 100; // Typical constant const int j = i + 10; // Value from const expr long address = (long)&j; // Forces storage char buf[j + 10]; // Still a const expression

int main() { cout << "type a character & CR:"; const char c = cin.get(); // Can't change const char c2 = c + 'a'; cout << c2; // ... } ///:~

Listado 8.1. C08/Safecons.cpp

Puede ver que i es una constante en tiempo de compilacin, pero j se calcula a partir de i. Sin embargo, como i es una constante, el valor calculado para j es una expresin constante y es en si mismo otra constante en tiempo de compilacin. En la siguiente lnea se necesita la direccin de j y por lo tanto el compilador se ve obligado a pedir almacenamiento para j. Ni siquiera eso impide el uso de j para determinar el tamao de buf porque el compilador sabe que j es una constante y que su valor es vlido aunque se asigne almacenamiento, ya que eso se hace para mantener el valor en algn punto en el programa.

En main(), aparece un tipo diferente de constante en el identificador c, porque el valor no puede ser conocido en tiempo de compilacin. Eso significa que se requiere almacenamiento, y por eso el compilador no intenta mantener nada en la tabla de smbolos (el mismo comportamiento que en C). La inicializacin debe ocurrir, an as, en el punto de la definicin, y una vez que ocurre la inicializacin, el valor ya no puede ser cambiado. Puede ver que c2 se calcula a partir de c y adems las reglas de mbito funcionan para las constantes igual que para cualquier otro tipo, otra ventaja respecto al uso de #define. En la prctica, si piensa que una variable no debera cambiar, debera hacer que fuese una constante. Esto no slo da seguridad contra cambios inadvertidos, tambin permite al compilador generar cdigo ms eficiente ahorrando espacio de almacenamiento y lecturas de memoria en la ejecucin del programa. 8.1.3. Vectores Es posible usar constantes para los vectores, pero prcticamente est dando por hecho que el compilador no ser lo suficientemente sofisticado para mantener un vector en la tabla de smbolos, as que le asignar espacio de almacenamiento. En estas situaciones, const significa un conjunto de datos en memoria que no pueden modificarse. En cualquier caso, sus valores no puede usarse en tiempo de compilacin porque el compilador no conoce en ese momento los contenidos de las variables que tienen espacio asignado. En el cdigo siguiente puede ver algunas declaraciones incorrectas.

//: C08:Constag.cpp // Constants and aggregates const int i[] = { 1, 2, 3, 4 }; //! float f[i[3]]; // Illegal struct S { int i, j; }; const S s[] = { { 1, 2 }, { 3, 4 } }; //! double d[s[1].j]; // Illegal int main() {} ///:~

Listado 8.2. C08/Constag.cpp

En la definicin de un vector, el compilador debe ser capaz de generar cdigo que mueva el puntero de pila para dar cabida al vector. En las definiciones incorrectas anteriores, el compilador se queja porque no puede encontrar una expresin constante en la definicin del tamao del vector. 8.1.4. Diferencias con C Las constantes se introdujeron en las primeras versiones de C++ mientras la especificacin del estndar C estaba siendo terminada. Aunque el comit a cargo de C decidi entonces incluir consten C, por alguna razn, vino a significar para ellos una variable ordinaria que no puede cambiarse. En C, una constante siempre ocupa espacio de almacenamiento y su mbito es global. El compilador C no puede tratar const como una constante en tiempo de compilacin. En C, si escribe:

const int bufsize = 100; char buf[bufsize];

aparecer un error, aunque parezca algo razonable. bufsize est guardado en algn sitio y el compilador no conoce su valor en tiempo de compilacin. Opcionalmente puede escribir:

const int bufsize;

en C, pero no en C++, y el compilador C lo acepta como una declaracin que indica que se almacenar en alguna parte. Como C utiliza enlace externo para las constantes, esa semntica tiene sentido. C++ utiliza normalmente enlace interno, as que, si quiere hacer lo mismo en C++, debe indicar expresamente que se use enlace externo usando extern.

extern const int bufsize; // es declaracin, no definicin

Esta declaracin tambin es vlida en C. En C++, const no implica necesariamente almacenamiento. En C, las constantes siempre necesitan almacenamiento. El hecho de que se necesite almacenamiento o no

depende de cmo se use la constante. En general, si una constante se usa simplemente para reemplazar un nmero por un nombre (como hace #define), entonces no requiere almacenamiento. Si es as (algo que depende de la complejidad del tipo de dato y de lo sofisticacin del compilador) los valores pueden expandirse en el cdigo para conseguir mayor eficiencia despus de la comprobacin de los tipos, no como con#define. Si de todas formas, se necesita la direccin de una constante (an desconocida, para pasarla a una funcin como argumento por referencia) o se declara como extern, entonces se requiere asignar almacenamiento para la constante. En C++, una constante que est definida fuera de todas las funciones tiene mbito de archivo (es decir, es inaccesible fuera del archivo). Esto significa que usa enlace interno. Esto es diferente para el resto de identificadores en C++ (y que las constantes en C) que utilizan siempre enlace externo. Por eso, si declara una constante con el mismo nombre en dos archivos diferentes y no toma sus direcciones ni los define como extern, el compilador C++ ideal no asignar almacenamiento para la constante, simplemente la expandir en el cdigo. Como las constantes tienen implcito el mbito a su archivo, puede ponerlas en un archivo de cabecera de C++ sin que origine conflictos en el enlace. Dado que las constante en C++ utilizan por defecto enlace interno, no puede definir una constante en un archivo y utilizarla desde otro. Para conseguir enlace externo para la constante y as poder usarla desde otro archivo, debe definirla explcitamente como extern, algo as:

extern const int x = 1; // definicin, no declaracin

Sealar que dado un identificador, si se dice que es extern, se fuerza el almacenamiento para la constante (aunque el compilador tenga la opcin de hacer la expansin en ese punto). La inicializacin establece que la sentencia es una definicin, no una declaracin. La declaracin:

extern const int x;

en C++ significa que la definicin existe en algn sitio (mientras que en C no tiene porqu ocurrir as). Ahora puede ver porqu C++ requiere que las definiciones de constantes incluyan la inicializacin: la inicializacin diferencia una declaracin de una definicin (en C siempre es una definicin, aunque no est inicializada). Con una declaracin const extern, el compilador no hace expansin de la constante porque no conoce su valor.

La aproximacin de C a las constantes es poco til, y si quiere usar un valor simblico en una expresin constante (que deba evaluarse en tiempo de compilacin) casi est obligado a usar#define.

También podría gustarte