You are on page 1of 29

SENTENCIAS

C.0 Introduccin En C, cualquier expresin finalizada en un punto y coma ; forma una sentencia. De todos los tipos, las estructuras (o sentencias ) de control son las que controlan la ejecucin de las instrucciones de un programa. La programacion estructurada se basa en la utilizacin de un reducido nmero de estructuras que permiten hacer que un programa sea suficientemente legible, reduciendo considerablemente el nmero de errores, y facilitando enormemente la deteccin y solucin de estos. La caracterstica fundamental de la programacin estructurada consiste en que todas las estructuras tienen un nico punto de entrada y un nico punto de salida. Esto permite descomponer fcilmente un problema en subproblemas, reduciendo la complejidad y facilitando la programacin.

En C diferenciamos tres tipos de sentencias de control: -Sentencias condicionales o selectivas. -Sentencias de iteracin o repetitivas (bucles). -Sentencias de salto. Se recomienda evitar la utilizacin de este ultimo tipo de sentencias.

C.1 Sentencias condicionales Hay tres sentencias condicionales en C: if, else y switch

C.1.1 Sentencia if La sentencia if nos permite elegir si se ejecuta o no un bloque de instrucciones. La "expresin" del if es una expresin que debe ser evaluada: falsa si es cero y verdadera si vale distinto de cero. Ejemplo: #include <stdio.h> int main () { int x; printf(Dame un numero); scanf(%d,&x); if (x>0) { printf(El numero %d es positivo,x); } return 0; }

C.1.2 Sentencia else Una sentencia if cuando incluye un else, permite ejecutar un bloque de cdigo si se cumple la condicin y otro bloque diferente de cdigo si la condicin no se cumple. Ejemplo: #include <stdio.h> void main ()

{ int x; printf(Dame un numero: ); scanf(%d,&x); if (x>=0) { printf(El numero %d es positivo, x); } else { printf(El numero %d es negativo, x); } }

C.1.3 Sentencia else colgante Ejemplo: #include<stdlib.h> int main() { float nota; printf ("Dame una nota: ") scanf ("%f", &nota) if (nota>9){ printf("Sobresaliente");} else if(nota >=7){ printf("Notable);} else if(nota >=5){ printf("Aprobado");} else{ printf ("Suspenso);} return 0; }

C.1.4 Sentencia switch Permite seleccionar entre multiples alternativas posibles. La expresin del switch es una variable int o char, que puede tomar los valores, entre otros, dados por "opcin 1", "opcion 2", etc. Ejemplo: #include <stdio.h> void main() { int nota; printf(Calificacin: ); scanf(%d, &nota); switch (nota) { case 0: case 1: case 2: case 3: case 4: printf(Suspenso); break; case 5: case 6:

printf(Aprobado); break; case 7: case 8: printf(Notable); break; case 9: printf(Sobresaliente); break; case 10: printf(Matrcula); break; default: printf(Error); } }

C.2 Sentencias de control: Iteracin Las instrucciones de iteracin tambin llamados bucles, se ejecutan hasta que se cumpla alguna condicin predeterminada en el bucle en el caso del for o tambin en los casos del while y do-while. Podemos destacar los antes mencionados bucles que son los bucles for,while y do-while.

C.2.1 Bucles for: Tienen una gran potencia y flexibilidad, y tienen un esquema muy sencillo y definido. Este esquema es as: for(inicializacin del bucle; condicin; incremento). Ahora vamos a proceder a definir cada una de las partes del esquema bsico, inicializacin (exp1): es una asignacin que se utiliza para comenzar la variable del bucle, esto es de la variable de la que parte el bucle. Condicin (exp2): es una expresin relacional que hace que el bucle concluya cuando no se cumpla. Por ltimo el incremento (exp3): es la parte que determina como cambia la variable hasta que el bucle concluye. Es importante sealar que cada parte ha de ser separado por ; .Para que deje de ejecutarse el bucle como antes hemos mencionado depende de la condicin, que deber de ser falsa para que el bucle se detenga. Debemos tener en cuenta que a diferencia de otros bucles este no llegar a ejecutarse si la condicin es falsa, ya que la condicin se comprueba antes de entrar en el bucle.

Un sencillo ejemplo: #include <stdio.h> int main( ) { int x; for(x=1; x<=100; x++) printf (%d,x); return 0; } Una de las utilidades del bucle for es en el bucle infinito, que pese a que puede hacerse con todos los bucles es el for con el que se usa. Estos bucles infinitos son usados para que el bucle no concluya nunca hasta que en el cuerpo se encuentre un break. Por otro lado la construccin de este bucle for es muy sencilla, for ( ; ; ).

C.2.2 Bucles while: Tiene cierta semejanza con el bucle for, as es en el uso de una inicializacin, una condicin y un incremento. Otra de sus similitudes es el momento en el que analizan la condicin que en ambos es antes de ejecutar el bucle. Sin embargo, en su esquema bsico aunque parezcan diferentes, son el mismo:

while (condicin) { cuerpo; incremento; } Algunas de las veces podremos saber antes de empezar el bucle cuantas veces se va a ejecutar.

Ejemplo: char esperar_caracter (void) { char c; c=\0; while (c!=A) c=getchar ( ); return c; }

C.2.3 Bucles do-while: Este es el nico bucle que al menos se va a ejecutar una vez puesto que este bucle examina la condicin una vez se ha ejecutado el bucle, esto es, al final del mismo. El esquema bsico de este bucle sera algo as: do { cuerpo; } while (condicin); Este bucle es muy til por ejemplo en mens dado que el men debe de ejecutarse al menos una vez.

Ejemplo: #include <stdio.h> int main() { int digito=0; do { printf("%d ",digito++); } while (digito<=9); }

C.3 Sentencias de salto Hay cuatro sentencias de salto en C: break, return, goto y continue. Suelen estar condicionadas (que solo las ejecute el programa en un determinado caso). Se desaconseja la utilizacin de este tipo de sentencia de control, sobre todo el goto, ya que su uso implica un aumento de la probabilidad de cometer errores, dificulta la legibilidad del cdigo y es mucho mas difcil corregir errores y cambiar secuencias de cdigo.

C.3.1 Sentencia break La instruccin de salto break se usa para interrumpir (romper) la ejecucin normal de un bucle, es decir, la instruccin break finaliza la ejecucin de un bucle y, por tanto, el control del programa se transfiere (salta) a la primera instruccin despus del bucle.

Ejemplo: #include <stdio.h> int main() { int n, a;

a = 0; do { printf( "Introduzca un numero entero: " ); scanf( "%d", &n ); if ( n == 0 ) { printf( "ERROR: El cero no tiene opuesto.\n" ); break; /* En el caso de que n sea un cero, el bucle se interrumpe. */ } printf( "El opuesto es: %d\n", -n ); a += n; } while ( n >= -10 && n <= 10 ); printf( "Suma: %d", a ); return 0; }

C.3.2 Sentencia return La instruccin de salto return es utilizada en lenguaje C para devolver el control de ejecucin desde la funcin que contiene el return a la rutina que la invoc y para indicar el valor de retorno de una funcin. Ejemplo: #include <iostream> int z; void funcion(); int main() { for(z=0;z<=5;z++) { printf("%i\n",z); funcion(); system("pause"); } return 0; Indica al ordenador que el programa ha fnalizado sin errores. } void funcion() { printf("Hola\n"); if(z==3){printf("Z vale 3\n"); return;} El return termina la funcin y entonces printf("Z no vale 3\n"); no se ejecutar printf("Z no vale 3\n"); }

C.3.3 Sentencia goto La instruccin de salto goto se puede usar en un programa, para transferir incondicionalmente el control del mismo a la primera instruccin despus de una etiqueta, o dicho de otra forma, al ejecutar una instruccin goto, el control del programa se transfiere (salta) a la primera instruccin despus de una etiqueta.

Ejemplo: #include <stdio.h> int main() { int n, a; a = 0; do { printf( "Introduzca un numero entero: " ); scanf( "%d", &n ); if ( n == 0 ) { printf( "ERROR: El cero no tiene opuesto.\n" ); goto etiqueta_1; /* En el caso de que n sea un cero, el control de programa salta a la primera instruccin despus de etiqueta_1. */ } printf( "El opuesto es: %d\n", -n ); a += n; } while ( n >= -10 && n <= 10 ); etiqueta_1: printf( "Suma: %d", a ); return 0; }

C.3.4 Sentencia continue La instruccin de salto continue siempre se usa para interrumpir (romper) la ejecucin normal de un bucle. Sin embargo, el control del programa no se transfiere a la primera instruccin despus del bucle, como s hace la instruccin break, es decir, el bucle no finaliza, sino que, finaliza la iteracin en curso, transfirindose el control del programa a la condicin de incremento de contadores y despus a la condicin de salida del bucle, para decidir si se debe realizar una nueva iteracin o no.

Ejemplo: #include <stdio.h> int main() { int n, a; a = 0; do { printf( "Introduzca un numero entero: " ); scanf( "%d", &n ); if ( n == 0 ) { printf( "ERROR: El cero no tiene opuesto.\n" ); continue; /* En el caso de que n sea un cero, la iteracin en curso del bucle

se interrumpe aqu. */ } printf( "El opuesto es: %d\n", -n ); a += n; } while ( n >= -10 && n <= 10 ); printf( "Suma: %d", a ); return 0; }

Todos los programas necesitan, en algn momento, almacenar nmeros o datos ingresado por el usuario. Estos datos son almacenados en variables, y en C++ como en otros lenguajes estas variables deben tener un tipo.

1. Los tipos de variables


Existen varios tipos de variables, y cada uno corresponde a un tamao mximo de un nmero, un carcter o incluso una verdad. Cuanto mayor sea el nmero que pueda admitir, mas espacio en memoria ocupar.

1.1 bool
Por lo general utiliza 1 byte de memoria, valores: true o false.

1.2 char
Utiliza generalmente 1 byte de memoria, permite almacenar un carcter, valores; 256 caracteres.

1.3 unsigned short int


Utiliza generalmente 2 bytes de memoria, valores: de 0 a 65 535

1.4 short int


Utiliza generalmente 2 bytes de memoria, valores: de -32768 a 32767.

1.5 unsigned long int


Utiliza generalmente 4 bytes de memoria, valores: de 0 a 4 294 967 295.

1.6 long int

Utiliza generalmente 4 bytes de memoria, valores: de -2 147 483 648 a 2 147 483 647.

1.7 int (16 bits)


Utiliza generalmente 2 bytes de memoria, valores: de -32 768 a 32 767.

1.8 int (32 bits)


Utiliza generalmente 4 bytes de memoria, valores: de -2 147 483 648 a 2 147 483 647.

1.9 unsigned int (16 bits)


Utiliza generalmente 2 bytes de memoria, valores: de 0 a 65 535.

1.10 unsigned int (32 bits)


Utiliza generalmente 2 bytes de memoria, valores: de 0 a 4 294 967 295.

1.11 double
Utiliza generalmente 8 bytes de memoria, valores: de 2.2e-308 a 3.4e-38.

1.12 float
Utiliza generalmente 4 bytes de memoria, valores: de 1.2e-308 a 3.4e-38. Atencin! El tamao de las variables en memoria puede variara de un PC a otro.

2. Declaracin y asignacin de variables


2.1 Declaracin
Para declarar una variable, basta con indicar su tipo y su nombre. Existen ciertas convenciones en cuanto al nombre de las variables. Algunos prefieren separar las partes de un nombre con '_', otros prefieren escribir una mayscula para separarlas. Ejemplo:

int recetaDelMes;

int receta_del_mes;

Lo importante es que utilices siempre la misma convencin para tus programas.

2.2 Asignar un valor


Es posible asignar un valor a una variable al momento de declararla:

int recetaDelMes = 12301;

Tambin es posible declarar varias variables en una misma lnea, pero en este caso, todas las variables de la lnea tendrn el mismo tipo.

int recetaDelMes = 12301, recetaDelAo = 45644545;

3. Error al definir un tipo de variable (Enteros con signo)


Qu pasa si el tipo que hemos elegido es muy pequeo? Si el nmero es mayor al mximo admitido por el tipo, entonces el valor de la variable ser el valor mnimo admitido por este tipo.

unsigned short int numero = 65535; cout << numero << endl; numero++; cout << numero << endl;

Si ejecutamos este cdigo, la segunda lnea no escribir 65536, sino 0. Esto es idntico para todos los tipos.

4. Error al definir un tipo de variable(Enteros sin signo)


Para enteros sin signo, sucede lo mismo, una vez que el tipo alcanza su tamao mximo, pasa a su valor mnimo.

short int numero = 32767; cout << numero << endl; numero++;

cout << numero << endl;

Si ejecutamos este cdigo, la segunda lnea no escribir 32768, sino -

8: Constantes

Tabla de contenidos 8.1. Sustitucin de valores 8.2. Punteros 8.3. Argumentos de funciones y valores de retorno 8.4. Clases 8.5. Volatile 8.6. Resumen 8.7. Ejercicios 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

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.
BUFSIZE

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.
32768.

Expresiones
En cualquier programa, necesario procesar los datos de entrada para generar los datos de salida. El elemento bsico de C para procesar los datos son las expresiones. Estas expresiones utilizan unos operandos, a saber: constantes, variables, funciones, u otra expresin; y

unos operadores, de los tipos: aritmticos, relacionales, lgicos, manejo de bits, asignacin, asignacin compacta, auto incremento, auto decremento y condiciones. Por ltimo se usan parntesis para definir en qu orden deben evaluarse las expresiones. Valordos = 9,20 * (2,0 + Valor) Operadores aritmticos Emplean operandos numricos, y producen como resultado otro valor numrico. Hay dos tipos: Unarios: se aplicar un nico operando. Son: +: no tiene efecto aparente, -: cambia el signo del valor. Binarios: se aplican a los operandos. Son: +: suma, -: resta, *: multiplicacin, /: divisin, %: mdulo (devuelve el resto de la divisin). Todos estos operadores se evalan de izquierda a derecha. Esto quiere decir que las expresiones se empezarn a ejecutar de izquierda a derecha.
Caracteres: las variables de tipo carcter son en realidad valores numricos representados como caracteres. Por tanto, se puede operar con ellos.

' 5'' 1'= 5 As, la resta de dos caracteres da un nmero y la suma de un carcter con un numero da otro carcter. Operadores Relacionales Emplean dos operandos numricos, y se obtiene como resultado otro valor del mismo tipo. Son adems, todos binarios. <,>, <=, >=: devuelven 1 si se cumple la condicin que representan, y 0 en otro caso. ==: devuelve 1 si los dos operandos son iguales, y 0 en caso contrario. =(Ver nota): devuelve 1 si los dos operandos son distintos, y 0 en caso contrario. Ejemplos: (tomando variables de tipo entero con nombres h,j y k, con valores 1, 2 y 3 respectivamente). h < j sera 1 (h+j) >= k sera 1 K = 3 sera 0 Ya que 1 es menor que dos. Ya que 1+2 =3, que es = a 3. Ya que 3 no es distinto de 3.(Ver nota)

Adems, un operando por si mismo puede ser un resultado. As, la expresin:

K sera 3

Ya que su valor es 3.

Estos operadores se evalan de izquierda a derecha. Esto debe ser tenido en cuenta a la hora de concatenar expresiones: 5 > h > 2 sera 0 Ya que 5 > h es verdadero, por lo que devuelve 1, y 1 < 2 sera 0.

Para terminar con los operadores relacionales, hay que recordar que los caracteres son al fin y al cabo valores numricos, por lo que podemos comprarlos. Sin embargo, no es recomendable, ya que solo se pueden suponer relaciones entre las letras minsculas, maysculas y caracteres numricos, del estilo: 0 < < 9 a < < z A < < Z Adems, nunca suponer que una suma de valores numricos decimales, vaya a dar un nmero entero. Por ejemplo 0.1 + 0.2 + 0,7, el resultado de la suma puede ser 0.9999999999998, que no es 1. Nota: el smbolo utilizado antes, es en realidad el smbolo cerrar exclamacin. Este no se ha colocado porque este tipo de fuente de letra no contiene ese smbolo. Operadores Lgicos De nuevo, toman operandos numricos y producen otro, pero este de tipo entero. Son: (Ver nota): de tipo unario. Representa el No lgico. Si el operando vale 0, devuelve 1, y si vale distinto de 0, devuelve 1. &&: de tipo binario. Representa el Y lgico. Si ambos valores son distintos de 0, devuelve 1. En otro caso, devuelve 0. ||: de tipo binario. Representa el O lgico. Devuelve 0 si los dos operandos son 0, y 1 en caso contrario. Estos operadores se evalan de izquierda a derecha. Nota: de nuevo, este smbolo es el de cerrar exclamacin. Operadores de Manejo de Bits Usan operandos de tipo entero, y se aplican a todos los bits de dichos operandos. Son: ~: de tipo unario. Invierte todos los bits del operando. Los 0 pasar a ser 1, y los 1 sera 0. &: de tipo binario. Pone a 1 los bits si ambos son 1, y a 0 si alguno es 0.

|: de tipo binario. Pone a 1 si alguno es igual a 1, y a 0 si ambos son 0.


^: de tipo binario. Pone a 0 si ambos son iguales, y a 1 si son distintos.

<<: de tipo binario. Desplaza a la izquierda los bits del operando de la izquierda, tantas posiciones como indique el operando de la derecha. Puede provocar overflow. Los bits que quedan en la derecha se rellenan con ceros. >>: similar al anterior, pero hacia la derecha. Los bits que quedan en la izquierda son indefinidos (pueden aparecer 1s o 0s). Un ejemplo de su uso, es la multiplicacin por dos. Debido a que la codificacin de los datos es binaria en los computadores, desplazar los bits de un nmero X posiciones, equivale a multiplicar o dividir X veces por 2. As: 5 << 1 sera 10
4 >> 1 sera 2

Este mtodo tiene una ventaja respecto a una multiplicacin o divisin normal y corriente, y es que es muchsimo ms rpido. Sin embargo, y debido a que los ordenadores de hoy en da son cada vez ms potentes, no todos los programadores aprovechan este mtodo. Asignacin La asignacin, es dar un valor a una variable (u otro objeto que pueda guardar datos). As pues, permite dos operandos, el de la izquierda ser dicho objeto, y el de la derecha ser otra expresin cualquiera. Dicho esto, podemos decir que lo siguiente NO seran asignaciones: Valor + 1 = 10
Carcter / 10 = a

Y sin embargo, seran vlidas: Valor = 10 1 Carcter = a * 10 A=7+5


B = (a = 7 + 5) Este tipo de asignaciones (en cascada que se llaman) no se recomiendan, debido a que suele inducir a errores.

Internamente, cuando se hace una asignacin, el valor (o resultado) de la expresin de la derecha, se convierte al tipo del operando de la izquierda. Esto es, si hacemos: char letra=a;
int valor=letra;

En la variable valor, se guardar el valor de la variable tipo char, transformado a int. En este caso, eso es sencillo, pues cada char tiene un valor asociado, siendo distinta su representacin. Esto significa, que si nosotros tenemos un: char letra=a, letra no vale a, sino un valor numrico asociado, pero que se representa con una a. Sin embargo, esto lleva a problemas cuando los tipos son de rangos distintos. Si el operando de la izquierda es de un tipo de mayor rango que el del operando de la derecha, no hay problema. Pero si es a la inversa, s que lo hay. 1* Si un tipo entero se asigna a otro tipo entero pero de menor rango, se copian los bits menos significativos. Si es un nmero grande, los bits ms significativos se habrn perdido. 2* Si un valor en coma flotante se asigna a una variable de tipo entero, se trunca antes de realizar la asignacin. 3* Si un valor en coma flotante se asigna a una variable en coma flotante, se puede producir un redondeo que ser tanto mayor cuanto menor sea la precisin del tipo de variable (float, double, long double, etc). Asignacin Compacta Se basa en unir el operador de asignacin =, con otro operador. Son todos binarios, siendo el operando de la izquierda igual que en la asignacin, el que va a recibir el valor, y el de la derecha, que se usa para operar con el de la derecha. Esto es: int i=0; i += 1; i = i + 1; //Sera lo mismo que //este.

Los operadores que se pueden usar junto al de asignacin, son: +,-,*,/,%,&,|,^,>>,<< En la asignacin compacta, primero se evala la expresin de la derecha, como si llevase parntesis. Por tanto, no es lo mismo: X = x*y+1; X *= y + 1; Que sera equivalente a: x = x*(y+1). //que este otro

Conversin Forzada Sabemos pues, que en una asignacin se produce una conversin de tipos. Del tipo de la expresin de la derecha, al tipo del operador de la izquierda. Es especialmente til, cuando se quieren realizar operaciones numricas con ciertas condiciones. Por ejemplo, si queremos una divisin con coeficiente entero. int coef=0; float num=7; float div=5; coef = num / div; //coef valdra 1.

coef = (int) num / div; //coef valdra 1. Como acabamos de ver, la conversin forzada se basa en colocar el tipo al que queremos transformar la expresin, delante de esta y entre parntesis. Operadores de Auto-incremento/decremento Existen dos operadores en C, que permiten utilizar el valor de una variable, y anterior o posterior mente a su uso, modificar su valor en 1 unidad. Estos operadores son ++ y --. Si se utilizan como prefijos, las variables se modifican, y acto seguido se utilizan. En caso de utilizarlos como postfijos, primero se usan las variables, y luego se modifican. As: int i =0;
int a = i++;

Aqu, a valdra 0, porque primero se asigna el valor, e i valdra 1, porque se ha incrementado. Pero si cambiamos la segunda lnea por:

int a = ++i;

Tanto a como i valdran 1, porque primero se incrementa el valor, y despus se hace la asignacin. Sin embargo, NO es recomendable utilizar estos operadores en una expresin donde aparezca ms de una vez la variable a la que afectan, pues no est asegurado cual de las veces que aparezca la variable se evaluar antes, por ejemplo:

Num / 2 + 5 * (3 + num++)

Tampoco es recomendable usarlo como parte de segundos operandos en expresiones lgicas. Por ejemplo:

(i>7) && (j++ > 2)

Debido a que si la primera expresin no se cumple, el segundo argumento no se evala, y la variable j no se vera modificada. Operador Condicional Es un operador ternario, que utiliza operandos numricos. Su sintaxis es: Expresion1 Ver Nota expresin2 : expresin3 Siendo posibles dos resultados. Si expresin 1 es verdadera, o lo que es lo mismo, DISTINTA de 0, se devolver expresin2. En caso contrario, se devolver expresin 3. Hay que recordar que este operador es excluyente, y si no se devuelve una expresin, esta ni siquiera se evala. Nota: este smbolo es en realidad el de cerrar interrogacin. En problema es el mismo que el anterior con el smbolo de exclamacin. Operador SizeOf Como dijimos en el tutorial de variables, cada tipo de dato tiene un tamao distinto. Este depende del compilador que utilicemos, y de la mquina donde se ejecute. Por ello, podemos valernos del operador sizeof, que devuelve el tamao del tipo deseado. Su uso es:

Instruccin break en Lenguaje C


Para qu sirve la instruccin break en C?
En lenguaje C, para escribir una instruccin de salto break (interrumpir), se utiliza la sintaxis: break; La instruccin de salto break se usa para interrumpir (romper) la ejecucin normal de un bucle, es decir, la instruccin break finaliza (termina) la ejecucin de un bucle y, por tanto, el control

delprograma se transfiere (salta) a la primera instruccin despus del bucle. Ejemplo 1: Estdiese el siguiente cdigo fuente: #include <stdio.h> int main() { int n, a; a = 0; do { printf( "Introduzca un numero entero: " ); scanf( "%d", &n ); if ( n == 0 ) { printf( "ERROR: El cero no tiene opuesto.\n" ); break; /* En el caso de que n sea un cero, el bucle se interrumpe. */ } printf( "El opuesto es: %d\n", -n ); a += n; } while ( n >= -10 && n <= 10 ); printf( "Suma: %d", a ); return 0; } El programa puede ser la solucin del problema siguiente: Escriba un programa que: 1) Pida por teclado un nmero (dato entero). 2) Si el nmero introducido por el usuario es distinto de cero, muestre por pantalla el mensaje: "El opuesto es: <-nmero>".

3) Repita los pasos 1 y 2, mientras que, el usuario introduzca un nmero mayor o igual que -10 y menor o igual que 10. Pero, si el usuario introduce un cero, el bucle tambin finaliza, mostrndose por pantalla el mensaje: "ERROR: El cero no tiene opuesto.".

4) Muestre por pantalla la suma de los nmeros introducidos por el usuario. En pantalla:

Introduzca un nmero entero: 15

El opuesto es: -15 Suma: 15 La traza del programa es:

El bucle ha finalizado porque la condicin ( n >= -10 && n <= 10 ) es falsa, ya que, 15 no es mayor o igual que -10 y menor o igual que 10. Sin embargo, el bucle tambin puede finalizar, no porque sea falsa la condicin ( n >= -10 && n <= 10 ), sino, porque se ejecute la instruccin break. Esto ocurrir cuando el usuario introduzca un cero. Por ejemplo:

Introduzca un nmero entero: 8 El opuesto es: -8 Introduzca un nmero entero: -7 El opuesto es: 7 Introduzca un nmero entero: 0 ERROR: El cero no tiene opuesto. Suma: 1

La traza en este caso es:

Normalmente, cuando en un bucle se utiliza una instruccin break, la ejecucin de sta se condiciona. En el ejemplo 1, el bucle se interrumpe si la condicin ( n == 0 ) es verdadera. Ntese que, dicha condicin no est contemplada en la condicin de salida estndar del bucle, por lo que, a la condicin ( n == 0 ) se le considera condicin de salida interna del bucle. Ejemplo 2: No obstante, el problema tambin se puede resolver sin hacer uso de la instruccinbreak: #include <stdio.h> int main() { int numero, acumulador; acumulador = 0; do { printf( "Introduzca un numero entero: " ); scanf( "%d", &numero ); if ( numero == 0 ) { printf( "ERROR: El cero no tiene opuesto.\n" ); } else { printf( "El opuesto es: %d\n", -numero );

acumulador += numero; } } while ( numero >= -10 && numero <= 10 && numero != 0 ); printf( "Suma: %d", acumulador ); return 0; }

You might also like