Programación práctica en lenguaje C

262

description

Apuntes utilizados en el módulo de "Tecnicas de Programación" perteneciente al Ciclo Formativo de Grado Superior "Desarrollo de Productos Electrónicos" de la familia Electricidad-Electrónica.El documento está orientado al aprendizaje de los fundamentos de la programación estructurada usando como base el lenguaje C. Incluye numerosos ejemplos y se proponen ejercicios al final de cada capítulo.Además, contiene información sobre cómo programar, de manera básica, los puertos 'serie' y 'paralelo' de un PC.

Transcript of Programación práctica en lenguaje C

  • CAPTULO 1

    Principios Fundamentales

  • Captulo 1: Principios fundamentales Programacin en C

    1.1 INTRODUCCINEl lenguaje C es actualmente uno de los ms utilizados por aquellosprogramadores que buscan la estructura de un lenguaje de alto nivel con lapotencia y eficacia de un lenguaje ensamblador.Es utilizado para prcticamentecualquier tarea de programacin.

    El motivo de este documento es el de complementar los conocimientos tericosadquiridos a lo largo del curso con ejercicios de tipo prctico que ayuden aasimilar y comprender todas y cada una de las partes de las que se componeeste lenguaje de programacin.La materia recogida sigue un orden secuencial. Cada uno de los captuloscontendrn un repaso de teora con datos de inters y un nmero determinadode ejercicios en los que se requiere un dominio de los apartados anteriores.

    1.2 COMPONENTES DE UN PROGRAMA EN C

    Todos los programas en C comparten unas caractersticas comunes. Parafamiliarizarse con estos elementos se propone el siguiente programa:

    /* Primer programa en lenguaje C */

    #include "stdio.h"

    main(){

    printf("Este es el primer programa en C");}

    Una vez compilado y ejecutado, el programa muestra en pantalla el texto:Este es el primer programa en C

    Los elementos que contiene el programa son de uso comn y a continuacin sedescribe brevemente su misin:

    /* Primer programa en lenguaje C */Es un COMENTARIO. En C, los comentarios empiezan con la secuencia /* yterminan con */. El compilador ignora todo lo que est entre los smbolos decomienzo y final de comentario.

    Se puede poner un comentario en cualquier parte del programa. En C estndarde ANSI no se pueden anidar (uno dentro de otro) comentarios, como muestra elsiguiente comentario dentro de un comentario, que generar un error decompilacin:

    /* esto es /* un error */ */

    Turbo C tiene una opcin de anidar, pero haciendo esto se convierte en notransportable (el cdigo fuente no se puede llevar a otro compilador de C oa otro ordenador).

    #include "stdio.h"

    Representa una DIRECTIVA, es decir una instruccin que va dirigida alcompilador. Indica que debe leer el archivo de cabecera stdio.h y que su

    Cap.1-2

  • Captulo 1: Principios fundamentales Programacin en C

    contenido servir para cargar adecuadamente las funciones de librera (rutinasque ya estn compiladas) utilizadas en el programa.

    El nombre de archivo se puede especificar tanto en maysculas como enminsculas, pero el mtodo tradicional es en minsculas. El archivo decabecera STDIO.H contiene, entre otras cosas, informacin relativa a lafuncin de biblioteca printf().

    Obsrvese que la directiva #include no termina con un punto y coma. La raznde esto es que #include no es una palabra clave C que pueda definir unasentencia.

    El archivo fuente que se leer debe encerrarse entre comillas dobles oparntesis de ngulo, por ejemplo:#include "stdio.h"#include

    Si se encierra el archivo entre comillas, se busca el archivo primero en eldirectorio de trabajo actual. Si no se encuentra, se busca en cualquierdirectorio especificado en la lnea de rdenes. Finalmente, si el archivotodava no se ha encontrado, el compilador busca los directorios estndar.

    En caso de encerrarse el archivo entre parntesis en ngulo, el compiladorbuscar primero en el archivo en los directorios que se especifican en lalnea de rdenes de compilador. Si no se encuentra el compilador busca en losdirectorios estndar. En ningn momento el compilador busca el directorioactual de trabajo.Es vlido que los "archivos incluidos" tengan directivas # include. Estosarchivos se denominan includes anidados.

    Otra directiva utilizada muy frecuentemente es # define que se usa paradefinir un identificador y una cadena que el compilador sustituir por elidentificador cada vez que se encuentre en el archivo fuente. El estndar ANSIse refiere al identificador como nombre de MACRO y al proceso de sustitucincomo sustitucin de macro. El formato general para esta directiva es:

    # define identificador cadena_de_macro

    No hay punto y coma detrs de esta sentencia. Puede haber cualquier nmero deespacios entre el identificador y la cadena, pero, una vez que comienza lacadena, slo puede terminarla una nueva lnea. Ejemplo:# define MAX 100

    Esto hace que el compilador de C sustituya por el valor 100 cada vez que enarchivo fuente se encuentre con el nombre MAX.

    main()Representa una funcin, Todos los programas en C constan de una o msfunciones, cada una de las cuales contiene una o ms sentencias. En C, unafuncin es una subrutina con nombre que realiza una sola tarea y a la que sepuede llamar desde otras partes del programa. Las funciones son los bloquesconstituyentes de C. Una sentencia especifica una accin a llevar a cabo porel programa. En otras palabras, Las sentencias son las partes del programa querealmente realizan las operaciones. Las sentencias se encuentran dentro de lasfunciones.

    Para indicar las funciones se utiliza una notacin convencional que ha llegadoa se estndar en los texto de C. Una funcin tendr parntesis despus delnombre de la funcin.

    Cap.1-3

  • Captulo 1: Principios fundamentales Programacin en C

    Todas las sentencias de C terminan en punto y coma (;). C no reconoce el finalde lnea como un lmite. Esto significa que no hay restricciones sobre laposicin de las sentencias dentro de una lnea. Adems, se pueden situar doso ms sentencias en una lnea.

    La forma ms simple de una funcin de C:

    nombre_de_funcin(){secuencia de sentencias.........

    }

    Donde nombre_de_funcin es el nombre de la funcin y la secuencia desentencias pueden ser una o ms sentencias. Salvo en escasas excepciones, sepuede llamar a una funcin por el nombre que se quiera. Pero ste se debecomponer slo con letras maysculas y minsculas del alfabeto, los dgitos del0 al 9 y el carcter subrayado. C es SENSIBLE AL TAMAO, lo que significa queC diferencia entre letras maysculas y minsculas, es decir Mifunc y mifuncson nombre distintos para C.

    Aunque un programa en C puede contener diversas funciones, la nica funcinque DEBE tener es main() ("principal"), la funcin main() es la funcin en laque comienza la ejecucin de un programa. Es decir, cuando el programacomienza a operar, empiezan ejecutando las sentencias que hay dentro de lafuncin main(), empezando por la primera sentencia que hay despus de la llavede apertura. La ejecucin del programa termina cuando (conceptualmente) sealcanza la llave de cierre.

    Dependiendo del compilador que se utilice y de como estn configuradas susopciones, al compilar el programa nos indicar que no hay valor de retorno demain(). Es opcional y puede ignorarse. Ms adelante se aprender cmo devolverun valor desde main().

    Otro componente importe de todos los programas de C son las FUNCIONES DEBIBLIOTECA. El C estndar ANSI especifica un conjunto mnimo de funciones debiblioteca que se tienen que suministrar con todos los compiladores de C y queel programa puede utilizar. A esta coleccin de funciones se le conocehabitualmente como la BIBLIOTECA ESTNDAR DE C. La biblioteca estndarcontiene funciones para llevar a cabo E/S de disco (entrada/salida), manejode cadenas de caracteres, operaciones matemticas y mucho ms. Cuando elprograma est compilado, el cdigo para las funciones de biblioteca se aadeautomticamente al programa. En la mayora de otros lenguajes como COBOL,Pascal, estas funciones estn integradas en el lenguaje. La ventaja detenerlas como funciones de biblioteca radica en su mayor flexibilidad.Prcticamente todos los programas de C que se creen utilizarn funciones dela biblioteca estndar de C.

    printf("Este es el primer programa en C");Una de las funciones de biblioteca ms comunes se llama printf(). Esta es unafuncin de salida de uso general de C. Aunque printf() es muy verstil, suforma ms simple es:

    printf("cadena-a-mostrar");

    La funcin printf() muestra en pantalla los caracteres contenidos entre lascomillas dobles de inicio y fin (las comillas dobles no se muestran enpantalla). En C uno o ms caracteres encerrados entre comillas dobles se llamaCADENA. A la cadena entre comillas que hay entre los parntesis de printf()se la llama ARGUMENTO. En C, la llamada a una funcin de biblioteca es unasentencia; por eso debe terminar con un punto y coma.

    Para llamar a una funcin, se especifica su nombre seguido de la lista de

    Cap.1-4

  • Captulo 1: Principios fundamentales Programacin en C

    argumentos que se va a pasar, entre parntesis. Si la funcin no requiereningn argumento, no se especificarn argumentos -y la lista entre parntesisaparecer vaca-. Si hay ms de un argumento, los argumentos deben estarseparados por comas.

    1.3 IDENTIFICADORES

    Los operadores manipulan variables y constantes para formar expresiones. Estoscuatro -variables, constantes, operadores y expresiones- son el abecedario dellenguaje C.

    NOMBRES DE IDENTIFICADORES

    El lenguaje C define IDENTIFICADORES como los nombres que se utilizan parareferenciar variables, funciones, etiquetas y otros objetos definidos por elusuario. En C un identificador puede tener de uno a varios caracteres. Elprimer carcter DEBE ser una letra o un subrayado, los restantes caracterespueden ser cualquier combinacin de caracteres alfabticos y numricos(incluido el smbolo de subrayado).

    En Turbo C son significativos los 32 primeros caracteres de un identificador.Esto significa que si dos variables tienen en comn los 32 primeros caracteresy difieren slo en el 33, Turbo C no las discernir.

    El lenguaje C trata las maysculas y minsculas como diferentes. Por ejemplocontador, Contador y CONTADOR son tres identificadores distintos.

    Un identificador no puede ser una palabra clave de C y no debera tener elmismo nombre de las funciones que se escriben a que estn en la biblioteca deC.

    DECLARACIN DE VARIABLES Y ASIGNACIN DE VALORESUna VARIABLE es una posicin de memoria con nombre que puede guardar distintosvalores. En C, a diferencia de otros lenguajes de computadora, todas lasvariables se deben declarar antes de poder utilizarlas. Una declaracin devariable tiene un importante propsito: le dice al compilador de C qu tipode variable se est utilizando.

    C soporta 5 tipos diferentes bsicos:

    char, int, float, double, void.

    Para declarar una variable se utiliza esta forma general:

    tipo nombre_de_variable

    Donde tipo es un tipo de dato de C y nombre_de_variable es el nombre de lavariable. Por ejemplo a continuacin se declara que contador es de tipo int:int contador;

    En C una declaracin de variable es una sentencia y debe terminar con un puntoy coma.

    Se puede declarar ms de una variable del mismo tipo utilizando una listaseparada por comas. Por ejemplo:float x, y, z;

    En C se pueden dar valores a la mayora de las variables a la vez que sedeclaran poniendo un signo igual y una constante despus del nombre de lavariable, el formato general de la inicializacin es:

    Cap.1-5

  • Captulo 1: Principios fundamentales Programacin en C

    tipo nombre_de_variable = constante;

    As como hay distintos tipos de variables, hay distintos tipos de constantes:

    Un carcter constante se especifica colocando el carcter entre comillassimples. Los enteros se especifican con nmeros enteros. Los valores en puntoflotante deben incluir un PUNTO DECIMAL. Ejemplos de declaracin de variableseran:

    char ch = A;

    int primero = 0 ;

    float balance = 123.23 ;

    Para asignar un valor a una variable, se pone su nombre a la izquierdade un signo de igual. A la derecha del signo "igual" se pone el valor que sequiere dar a la variable. En C, una operacin de asignacin es una sentencia;por tanto, debe terminar con un punto y coma. La forma general de unasentencia de asignacin es:

    nombre_de_variable = valor;

    num = 100;

    CONSTANTES

    En C las constantes se refieren a los valores fijos que el programa nopuede alterar.

    Las constantes en C pueden ser cualquier tipo bsico. Las constantes decaracteres estn encerradas entre comillas simples. Por ejemplo, a y % sonconstantes de caracteres.

    Las constantes enteras son nmeros sin componente de fraccin. Porejemplo 10 y -100. Las constantes de punto flotante requieren el uso del puntodecimal seguido por el componente fraccional. Ejemplo 3.14.

    C permite especificar constantes enteras en hexadecimal u octal en vezde en decimal si se prefiere. Una constante en hexadecimal debe comenzar por0x (un cero seguido de una x). Una constante octal comienza con un cero.Ejemplos:

    int hex = 0xFF ; /* 255 en decimal */

    int oct = 011 ; /* 9 en decimal */

    C soporta otro tipo de constante adems de las de tipos de datospredefinidos: la cadena ("string"). Una cadena es un conjunto de caracteresque se encierran entre comillas dobles. Por ejemplo "esto es una cadena".

    No confundir las cadenas con los caracteres. Se encierra una constantede un slo carcter con comillas simples; por ejemplo v, sin embargo, "v"es una cadena que contiene un slo carcter.

    El uso de comillas simples para encerrar todas las constantes decaracteres funciona para la mayora de los caracteres imprimibles, peroalgunos, como retorno de carro, es imposible de introducir por teclado. Poresta razn, C proporciona las constantes especiales de caracteres de barrainvertida que se muestran a continuacin:

    Cap.1-6

  • Captulo 1: Principios fundamentales Programacin en C

    Cdigo Significado

    \b Retroceso\f Alimentador de hojas\n Nueva lnea\r Retorno de carro\t Tabulador horizontal\" Doble comilla\ Comilla simple\0 Nulo (para cadenas)\\ Barra invertida\v Tabulador vertical\a Alerta\N Constante octal ( N es constante octal)\x Constante hexadecimal

    Se usa un cdigo de barra invertida de la misma forma que cualquier otrocarcter. Ejemplo: ch = \t;.

    VARIABLES GLOBALES Y LOCALES

    Hay dos lugares bsicos donde se declara una variable: dentro de unafuncin y fuera de todas las funciones. Estas variables se llaman variablesLOCALES y variables GLOBALES, respectivamente.

    Las variables locales (declaradas dentro de una funcin) slo las puedenreferenciar las sentencias que estn dentro de esa funcin. No son conocidasfuera de su propia funcin. Una de las cosas ms importantes que hay queentender sobre las variables locales es que solamente existen mientras se estejecutando la funcin en la que estn declaradas. Es decir, una variable localse crea al llamar a su funcin y se destruye cuando se sale por lo que nopueden mantener sus valores entre llamadas.

    A diferencia de las variables locales, las variables globales sonconocidas a lo largo de todo el programa y las puede utilizar cualquier trozode cdigo del programa. Adems, mantendrn su valor durante toda la ejecucindel programa. Las variables globales se crean declarndolas fuera de cualquierfuncin. Por ejemplo:

    Cap.1-7

  • Captulo 1: Principios fundamentales Programacin en C

    # include "studio.h"

    int max; /* Esta es una variable global */

    main(){

    max = 10;f1();

    }

    f1(){

    int i; /* Variable local */

    for(i = 0; i < max; i++)

    printf("%d",i);}

    Aqu, tanto main() como f1() aluden a la variable global max. Lavariable local i es definida dentro de la funcin f1().

    En C, una variable local y una variable global pueden tener el mismonombre. Por ejemplo, ste es un programa vlido:

    # include "stdio.h"

    int contador; /* contador como variable global */

    main(){

    contador = 10 ;f1() ;printf ("contador en main(): %d\n", contador") ;

    }

    f1(){

    int contador; /* contador como variable local */contador = 100;printf("contador en f1() : %d\n", contador);

    }

    El programa muestra esta salida de pantalla.

    contador en f1() : 100contador en main() : 10

    En main(), la referencia a contador es a la variable global. Dentro def1(). Tambin hay definida una variable local llamada contador. Cuando seencuentra la sentencia de asignacin dentro de f1(), el compilador miraPRIMERO para ver si hay una variable local llamada contador. Puesto que lahay, se utiliza la variable local, no la global del mismo nombre. Es decir,cuando las variables locales y globales comparten el mismo nombre, elcompilador utilizar siempre la variable local.

    Las variables globales son muy tiles cuando muchas funciones delprograma utilizan los mismos datos. Sin embargo, se deberan utilizanvariables locales donde se pueda, ya que un uso excesivo de variables globalestiene algunas consecuencias negativas. Primero, las variables globales

    Cap.1-8

  • Captulo 1: Principios fundamentales Programacin en C

    utilizan memoria todo el tiempo que el programa est en ejecucin, no slocuando se necesitan. En situaciones en las que la memoria es un recursoescaso, esto podra suponer un problema. Segundo, la utilizacin de unavariable global donde servira una variable local hace a una funcin menosgeneral, ya que confa en algo que se debe definir fuera de s misma.

    Se deben entender dos aspectos importantes de las variables. En primerlugar, dos variable globales no pueden tener el mismo nombre. Si lo tienen,el compilador no sabra qu variable usar. Intentar declarar dos variablesglobales con el mismo nombre va a hacer que el compilador d un mensaje deerror. En segundo lugar, una variable local en una funcin puede tener elmismo nombre que una variable local en otra funcin sin conflicto. La raznpara esto es que el cdigo y los datos en la funcin estn completamenteseparados del de la otra funcin. Simplemente, las sentencias dentro de unafuncin no tienen conocimiento de las de otras funciones. Sin embargo deberecordarse que no deben tener el mismo nombre dos variables en la mismafuncin.

    TIPOS DE DATOS

    Todas las variables en C se deben declarar antes de usarlas. Esnecesario porque el compilador debe saber qu tipo de datos es una variableantes de poder compilar cualquier sentencia en la que se use. En C hay cincotipos bsicos:

    carcter (character)

    entero (integer)

    punto flotante (floating-point)

    doble punto flotante (double-floating-point)

    sin valor (valueless)

    Las palabras claves para declarar variables de estos tipos sonrespectivamente:

    char, int, float, double y void

    En la tabla siguiente se presenta el tamao y el rango de cada tipo dedato de C para el IBM PC.

    Tipo Ancho en bit Rango

    char 8 -128 a 127

    int 16 -32768 a 32767

    float 32 3.4E-38 a 3.4E+38

    double 64 1.7E-308 a 1.7E+308

    void 0 sin valor

    Se usan variables del tipo char para guardar caracteres ASCII de 8 bitscomo A, B o C. Adems, se puede usar una variable char como un entero"pequeo" -128 a 127 y en lugar de un entero cuando la situacin no requierenmeros mayores. Las variables de tipo int pueden guardar cantidades enterasque no requieran parte fraccional. Se usan variables de este tipo paracontrolar los bucles y las sentencias condicionales. Se incluyen variables delos tipos float y double en programas que necesiten componente fraccional ocuando la aplicacin requiera nmeros grandes que pueden almacenar. Un doubleen C puede almacenar un nmero mucho mayor.

    Cap.1-9

  • Captulo 1: Principios fundamentales Programacin en C

    MODIFICADORES DE TIPO DE DATOS DE C

    Los tipos de datos bsicos excepto el tipo void se pueden modificarutilizando modificadores de tipo de C para que se ajusten ms adecuadamentea las necesidades especficas surgidas en un programa. Estos modificadores detipo son:

    signed

    unsigned

    long

    short

    El modificador de tipo precede al nombre del tipo. Por ejemplo, estodeclara un entero long:

    long int i;

    signed.- Utilizado para especificar un tipo de datos de caracteres consigno (mdulo y signo) en notacin de complemento a dos1 en tipos de datoschar e int. Ejemplo:

    signed char variable; -> -128 a 127 /* Redundantes puesto que por

    signed int variable; -> -32768 a 32767 defecto son con signo */

    unsigned.- Seala al compilador que no debe considerar el bit de signocomo tal y usar todos los bit en las operaciones aritmticas. Esto tiene elefecto de doblar el tamao del valor entero posible. Las variables sin signosolamente pueden contener valores positivos. Puede aplicarse a variables detipo char e int. Ejemplo:

    unsigned char variable; -> 0 a 255

    unsigned int variable; -> 0 a 65535

    short.- Declara enteros cortos2. Ejemplo:

    short int variable; -> -32768 a 32767

    long.- Declara variables int o double de doble longitud. Cuando seaplica a un int dobla la longitud en bits, del tipo de base que se modifica.Cuando long se aplica a double prcticamente dobla la precisin.

    long int variable; -> -2.147.483.648 a 2.147.483.647long double variable; -> 3,4 E-4932 a 1,1 E+4932 (vara segn el PC)

    Los modificadores unsigned y signed se pueden utilizar en combinacincon long y short. dentro de los enteros (int). Ejemplo:

    unsigned short int variable; -> 0 a 65535

    1Los nmeros negativos se presentan utilizando el mtodo de complemento a dos. En este mtodo, todos los bit del nmero

    estn invertidos y se aade 1 a este nmero. El indicador del signo es el bit de mayor ("1" para n negativo).El complemento a dos facilita a la CPU la realizacin de operaciones aritmticas.

    2En teora, el modificador short reduce a la mitad el tamao de un short int, por eso si nuestro compilador utiliza

    enteros de 32 bits un short int tendr una longitud de 16 bits. Sin embargo puede que no tenga efecto en nuestro entorno. Lamayora de los compiladores de C de PCs utiliza enteros de 16 bits, ya que este es el tamao de palabra de la familia deprocesadores 8086. El estndar ANSI de C establece que el menor tamao aceptable para un int es de 16 bits. Tambin estableceque el menor tamao de un short int es de 16 bits. Por eso en muchos entorno entornos no hay diferencia entre un int y un shortint.

    Cap.1-10

  • Captulo 1: Principios fundamentales Programacin en C

    unsigned long int variable; -> 0 a 4.294.967.295

    signed short int variable; -> -32768 a 32767

    signed long int variable; -> -2.147.483.648 a 2.147.483.647

    C permite usar una notacin abreviada para declarar enteros unsigned,short o long sin int (se asume por defecto). Ejemplo:

    unsigned x; /* declaran variables enteras sin

    unsigned int x; signo */

    1.4 OPERADORES

    Un operador es un smbolo que le dice al compilador que realicemanipulaciones matemticas o lgicas especficas.

    C tiene tres clases generales de operadores:

    - Aritmticos

    - Relacionales y Lgicos

    - Manipuladores de bits

    OPERADORES ARITMTICOSLos operadores aritmticos son:

    - Resta y menos unario (monario)

    + Suma

    * Multiplicacin

    / Divisin

    % Mdulo divisin

    ++ Incremento unario (monario)

    -- Decremento unario (monario)

    Menos unario (un operando) multiplica su operando por -1. As cualquiernmero precedido por el signo menos cambia el signo del nmero.

    Los operadores +, -, / y * funcionan de la misma manera en C que en lamayora de los lenguajes de computadora. Pueden utilizarse con cualquiera delos tipos de datos.

    Cuando se aplica / a un entero o carcter, la computadora truncarcualquier resto; Por ejemplo, 10/3 ser igual a 3 en la divisin entera.

    El operador mdulo de la divisin % recoge el resto de una divisinentera sin embargo, no se puede utilizar % sobre los tipo float o double.

    Dos operadores utilsimos que no se encuentran en otros lenguajes de

    Cap.1-11

  • Captulo 1: Principios fundamentales Programacin en C

    computadora son los operadores de incremento ++ y decremento --.

    El operador ++ aade 1 a su operando y el -- le resta uno. Por ejemplo:x++ ; /* equivale a x = x + 1 */

    x-- ; /* equivale a x = x - 1 */

    Estos operadores pueden preceder o seguir su operando:

    x++ ; o ++x ;

    x-- ; o --x ;

    Hay diferencia cuando se usa en una operacin. Cuando un operadorincremento o decremento precede a su operando, C realiza la operacin deincremento o de decremento antes de usar el valor del operando. Cuando eloperador sigue al operando, C usa el valor del operando antes de incrementaro decrementarlo. Ejemplo:

    x = 10 ;

    y = ++x ; /* y vale 11 porque la variable x incrementa primero y despus

    x = 10 ; se le asigna a la variable y */

    y = x++ ; /* y = 10 porque 1 asigna el valor y despus incrementa */

    En ambos casos el valor final de x es 11, la diferencia es cuando lohace.

    La prioridad de los operadores aritmticos es:

    Ms alta ++ --

    - (unario)

    * / %

    Ms baja + -La computadora evala de izquierda a derecha los operadores con el mismo

    nivel de prioridad. Se puede usar parntesis para alterar el orden deevaluacin. El lenguaje trata todos los parntesis de la misma manera queprcticamente todos los lenguajes: fuerza sus operaciones, o un conjunto deellas, a tener un nivel de prioridad mayor.

    El uso de parntesis redundantes o adicionales no provocar errores oralentizacin de la ejecucin de un programa.

    OPERADORES RELACIONES Y LGICOSLos operadores relacionales comparan 2 valores y devuelven un resultado

    verdadero o falso, basado en la comparacin. Los operadores lgicos agrupanvalores de verdadero/falso. En C, verdad es cualquier valor distinto de cero,mientras que falso es cero.

    Cap.1-12

  • Captulo 1: Principios fundamentales Programacin en C

    Los operadores relacionales y lgicos son:

    RELACIONALES LGICOS

    > Mayor que && AND

    >= Mayor o igual que || OR< Menor que ! NOT

    ch1) printf ("mayor que");

    ...

    Los operadores lgicos se usan para soportar las operaciones bsicaslgicas AND, OR y NOT de acuerdo con la siguiente tabla de verdad que usa "1"para verdad y "0" para falso.

    A B A AND B A OR B NOT A

    0 0 0 0 1

    0 1 0 1 1

    1 0 0 1 0

    1 1 1 1 0

    OPERADOR &&.- El resultado es verdadero si los dos operandos sonverdadero.

    OPERADOR ||.- El resultado es verdadero si al menos uno de los operandoses verdadero.

    OPERADOR !.- El resultado es verdadero si el operando el falso yviceversa.

    Los operadores lgicos y relaciones tienen una prioridad ms baja quelos operadores aritmticos. Esto quiere decir que una expresin como:

    10 + contador > a + 12

    Se evala como si se hubiera escrito (10 + contador) > (a + 12).

    Cap.1-13

  • Captulo 1: Principios fundamentales Programacin en C

    Se puede agrupar cualquier nmero de operaciones relacionales utilizandooperandos lgicos. Por ejemplo:

    variable1 > max || !(max == 100) && variable2 >= < > Desplazamiento a la derecha

  • Captulo 1: Principios fundamentales Programacin en C

    bits para enmascarar ciertos bits, como el de paridad3.

    Generalmente, las operaciones sobre bits AND, OR y XOR aplican susoperaciones directamente sobre cada bit en la variable individualmente.Producen un resultado basado en la comparacin de los bits correspondientesde cada operando.

    Por ejemplo, la funcin siguiente lee primero un carcter desde elpuerto de comunicaciones serie (RS-232) usando la funcin (de Turbo C)bioscom() y despus pone el bit de paridad a cero. Se puede usar la funcinbioscom()4 para acceder a los puertos serie asncronos en un IBM PC ocompatible.

    # include "bios.h"

    ...

    char coge_car_desde_puerto(){

    char = ch;

    ch = bioscom (2, 0, 0); /* coge un carcter desde COM1 */

    return(ch & 127);}

    El operador AND (&) activa un bit si los dos bits que se comparan son"1". Ejemplo "A" & 127:

    1 1 0 0 0 0 0 1 (contiene una "A" con paridad)&

    0 1 1 1 1 1 1 1 127 en binario

    0 1 0 0 0 0 0 1 "A" sin paridad

    El operador OR (|) activa un bit (bit = "1") si al menos uno de los bitsque se comparan es "1". Ejemplo 128 | 3:

    1 0 0 0 0 0 0 0 128 en binario|

    0 0 0 0 0 0 1 1 3 en binario

    1 0 0 0 0 0 1 1 resultado

    3Se usa el bit de paridad para confirmar que el resto de bits en el byte permanece sin cambios. Es usualmente el bit

    ms alto de cada byte.

    4BIOSCOM: I/O COMUNICACIONES RS-232

    int bioscom(int cmd, char abyte, int port) /* prototipo en bios.h */

    Valores de cmd:

    0.- Asigna parmetros de comunicaciones (con abyte).1.- Situa un byte (abyte).3.- Recibe un carcter (valor de retorno en los 8 bits de menor peso)4.- Retorno del estado

    port: 0 para COM1, 1 para COM2, etc.

    Los 8 bits de mayor peso del valor de retorno contiene los bits de estado.El valor de los 8 bits de menor peso depende del cmd especificado.

    Cap.1-15

  • Captulo 1: Principios fundamentales Programacin en C

    Un OR EXCLUSIVO (XOR) pondr activo un bit si y solo si los bits que secomparan son diferentes. Ejemplo 127^120:

    0 1 1 1 1 1 1 1^

    0 1 1 1 1 0 0 0

    0 0 0 0 0 1 1 1 resultado

    La tabla de verdad de una puerta XOR es:

    A B A XOR B

    0 0 0

    0 1 1

    1 0 1

    1 1 0

    Los operadores de desplazamiento >> y n de posiciones de bit

    Y el formato general de desplazamientos a la izquierda es:

    variable 1; 0 1 1 0 0 0 0 0 96

    x >> 2; 0 0 0 1 1 0 0 0 24

    El operador complemento a 1 (~) invertir el estado de cada bit en lavariable especificada. Todos los bit que contiene "1" se ponen a "0", todoslos "0" se ponen a "1".

    Cap.1-16

  • Captulo 1: Principios fundamentales Programacin en C

    Ejemplo:ch = 7 ; /* ch = 0 0 0 0 0 1 1 12 */

    ch = ~ch ; /* ch = 1 1 1 1 1 0 0 02 */

    NOTACIN SIMPLIFICADA EN SENTENCIAS DE ASIGNACINC tiene una taquigrafa especial que simplifica la codificacin de

    ciertos tipos de sentencias de asignacin. Ejemplo:x = x + 10 ;

    Se puede escribir en lenguaje C como:x += 10 ;

    El par de operadores += le dice al compilador que asigne a x el valorde s mismo ms 10.

    Esta notacin funcionar para todos los operadores binarios (2operandos) en C. El formato general de esta taquigrafa es:

    variable op= expresin ;

    OPERADOR COMA ","

    Se usa el operador coma para encadenar diversas expresiones.Esencialmente, su efecto es provocar una secuencia de operaciones a realizar.Cuando se usa en la parte derecha de una sentencia de asignacin, el valor dela expresin entera es el valor de la ltima expresin de la lista separadapor comas, por ejemplo:

    despus de que la computadora ejecute:y = 20;

    x = ( y = y - 5 , 30 / y ) ;

    x tendr el valor 2 ya que el valor original 20 de y se reduce en 5 ydespus ese valor divide a 30, dando 2 como resultado.

    En algunos casos se puede pensar que el operador coma tiene el mismosentido que el trmino "y", como en la frase >.

    PARNTESIS Y PARNTESIS CUADRADOSEl lenguaje C considera operadores a los parntesis "()" y a los

    parntesis cuadrados "[]". Los parntesis hacen el trabajo de incrementar laprecedencia de las operaciones que estn dentro de las mismas. Los parntesiscuadrados realizan el indexamiento de los arrays (que se discutirn msadelante). Es importante anotar que la mayora de los lenguajes de computadorano consideran operadores a estos smbolos.

    RESUMEN DE PRECEDENCIA

    La tabla siguiente lista la precedencia de todos los operadores de C.Observar que todos los operadores, excepto los unarios y ?, se asocian deizquierda a derecha.

    Cap.1-17

  • Captulo 1: Principios fundamentales Programacin en C

    Ms alta () [] -> .

    ! ~ ++ -- -5 (tipo) *6 &7 sizeof (unarios)

    * / %

    + -

    >

    < >=

    == !=

    &

    ^

    |&&

    ||?

    = += -= *= /= etc.

    Ms baja ,

    1.5 EXPRESIONES

    Los operadores, constantes y variables constituyen expresiones. Unaexpresin en C es cualquier combinacin vlida de estas piezas. Como lamayora de las expresiones tienden a caer en las reglas generales de lgebra,se dan por sabidas. Sin embargo a diferencia de muchos otros lenguajes decomputadora, C permite mezclar diferentes tipos de datos en una mismaexpresin.

    A continuacin se hace un estudio sobre la conversin de tipo enexpresiones y en asignaciones.

    CONVERSIN DE TIPO EN EXPRESIONESCuando se mezclan constantes y variables de diferentes tipos en una

    expresin, C las convierte en el mismo tipo. El compilador C convertir todoslos operadores al tipo de operando ms grande en una operacin segn la basede esta operacin, tal como se describe en estas reglas de conversin de tipo:

    1) Todos los char y short int se convierten en int. Todos los float endouble.

    2) Para todo par de operandos, lo siguiente ocurre en secuencia:

    Si uno de los operandos es un long double, el otro se convierte a longdouble. Si uno de los operandos es double, el otro se convierte a double. Si

    5unario, utilizado para la inversin de signo (por -1)

    6Puntero

    7Direccin de una variable

    Cap.1-18

  • Captulo 1: Principios fundamentales Programacin en C

    uno de los operandos es float el otro operando se convierta a float. Si unode los operandos es unsigned long el segundo se convierte a unsigned long. Siuno de los operandos es long, el otro se convierte a long. Si uno de losoperandos es unsigned el otro se convierte a unsigned.

    Despus que el compilador aplique estas reglas de conversin, cada partede operandos ser del mismo tipo, y el resultado de la operacin ser del tipode los operandos. Ejemplo de conversin de tipos:char v_char ;int v_int ;float v_float ;double v_double ;

    resultado = (v_char / v_int) + (v_float * v_double) - (v_float + v_int)

    conversin 1 -> int -> double -> float

    resultado parcial -> int -> double

    conversin 2 -> double

    resultado parcial -> double -> float

    conversin 3 -> double

    resultado final double

    CONVERSIN DE TIPO EN ASIGNACIONESEn una sentencia de asignacin de la que el tipo del lado derecho

    difiere del de la izquierda, el tipo de la derecha se convierte al de laizquierda.

    Cuando el tipo del lado izquierdo es mayor que el tipo del lado derecho,este proceso no origina problemas. Sin embargo, cuando el tipo del ladoizquierdo es menor que el tipo de la derecha, se puede producir una prdidade datos. Por ejemplo, este programa muestra -24:

    # include "stdio.h"

    main(){

    char ch;int i;

    i = 1000 ;ch = i ;

    printf("%d", ch);}

    Cap.1-19

  • Captulo 1: Principios fundamentales Programacin en C

    La razn de esto radica en que slo los 8 bits menos significativos dei se copian en ch. Dado que esta clase de conversin del tipo de asignacinno es un error de C. no se recibir mensaje de error.

    Una razn por la que se cre C fue para reemplazar el lenguajeensamblador; por tanto debe permitir toda clase de conversiones de tipo. Porejemplo, en algunos casos puede que slo se quieran los bit de menor peso deuna variable, y esta clase de asignacin permite obtenerlas fcilmente.

    OBSERVACIONES:

    - La conversin de entero a carcter o long int a int (segn ordenador)a travs de una asignacin se eliminan los bit ms significativos (8 bit enel primer caso y 16 en el segundo).

    - La conversin de un long double a double o double a float pierde seprecisin (redondeo).

    - Cuando se convierte de un valor en punto flotante a un valor enterose pierde la parte fraccional.

    - La conversin de un int en un float no aadir ni exactitud niprecisin.

    OPERADOR DE MOLDEADO (CASTS)Se puede forzar una expresin a ser de un tipo especfico, usando la

    construccin llamada casts. El formato general de un casts es:

    (tipo) expresin

    Donde tipo es uno de los tipos estndar de datos de C.

    Por ejemplo, puede que se quiera utilizar un valor en punto flotantepara un clculo, pero que se le quiera aplicar el operador mdulo (solamentese puede utilizar sobre valores enteros). Una solucin es la creacin de unavariable entera para utilizar en la operacin de mdulo y asignarle el valorde la variable en punto flotante cuando llegue el momento. Sin embargo, estaes una solucin poco elegante. El otro modo de solventar el problema esutilizando un molde, que origine un cambio de tipo temporal. Por ejemplo:

    ...

    float f;

    f = 100.2 ;

    /* imprimir f como un entero */

    printf ("%d", (int) f) ;

    ...

    Aqu el molde hace que el valor de f se convierta a un int.

    1.6 CARACTERSTICAS BSICAS DE LAS FUNCIONESLas funciones son la verdadera base de C. Como ya conoce, todas las

    sentencias de accin tiene que aparecer dentro de una funcin. Este apartadotrata diversos aspectos importantes de las funciones, aunque ms adelante seprofundizar ms en ellas.

    Cap.1-20

  • Captulo 1: Principios fundamentales Programacin en C

    FUNCIONES CON ARGUMENTOS

    Un argumento de una funcin es un valor que se pasa a la funcin en elmomento que se realiza la llamada. Se pueden crear funciones que tomanargumentos. Por ejemplo:

    /* Ejemplo de los argumentos de una funcin */# include

    main(){

    mul(10,11);}mul(a, b)

    int a, b;{

    printf("%d", a * b);}

    La declaracin mul() pone dentro del parntesis que sigue al nombre dela funcin las variables que recibirn los valores pasados a mul().

    Las funciones que no tomen argumentos no necesitan variables, as queel parntesis estar vaco.

    En el ejemplo anterior, cuando se ha llamado a mul() los valores 10 y11 se pasan (copian) en a y b.

    Es importante mantener dos trminos claros. Primero, el trminoARGUMENTO se refiere al valor usado para llamar a la funcin. El trminoPARMETRO FORMAL se refiere a la variable de una funcin que recibe el valorde los argumentos en la llamada.

    De hecho, las funciones que toman argumentos se llaman funcionesparametrizadas.

    En las funciones de C, los argumentos siempre se separan por comas.

    La distincin importante que hay que entender es que la variableutilizada como argumento en una llamada de funcin no tiene que ver con elparmetro formal que recibe su valor.

    Debe recordarse que el tipo de argumento que se utiliza para llamar auna funcin deber del mismo tipo que el parmetro formal que recibe eseargumento. Por ejemplo, no debera intentarse llamar a mul() con argumentosen coma flotante.

    Existen dos formas de declarar los parmetros de una funcin:

    .- Declaracin clsica

    .- Declaracin moderna

    Cuando se invent el lenguaje C, se utilizaba el denominado mtodoclsico que tras la estandarizacin del lenguaje se modific el modo dedeclaracin de argumentos denominndose declaracin moderna, actualmente lamayora de compiladores de C (entre ellos Turbo C) mantienen los dos formatos,por lo que cumplen fielmente el estndar ANSI para C (aunque se recomienda elformato moderno). La razn de que sea importante conocer el formato clsicoes porque existen literalmente millones de lneas de cdigo C que se pueden

    Cap.1-21

  • Captulo 1: Principios fundamentales Programacin en C

    utilizar. Adems muchos de los programas publicados en libros y revistasutilizan este formato porque funciona con los compiladores -incluidos losantiguos-. Vase la diferencia entre los dos formatos:

    .- Declaracin clsica: La declaracin clsica de parmetros de funcinconsta de dos partes: una lista de parmetros, que va entre parntesis despusdel nombre de la funcin y las declaraciones de parmetros reales, que vanentre el parntesis cerrado y la llave de apertura de la funcin. El formatogeneral de la definicin de parmetros clsica aparece de esta manera:

    tipo nombre_de_funcin (parm1, parm2..., parmN)tipo parm1;tipo parm2;...

    tipo parmN;{

    Cdigo de la funcin}

    Por ejemplo la siguiente funcin aparece en su formato clsico:float f(a, b, ch)int a, b;char ch;{

    ...

    }

    Observar que en la forma clsica puede existir ms de un parmetro enla lista despus del nombre de tipo.

    .- Declaracin moderna: La principal diferencia con el formato clsicoes que todos los parmetros de funciones deben incluir entre los parntesistanto el tipo de variable como el nombre. Esto quiere decir que la lista dedeclaracin de parmetros de una funcin adquiere este formato general:

    tipo nombre_de_funcin(tipo nom_var1, tipo nom_var2,...,tipo nom_varN)

    Como ejemplo la declaracin anterior en su formato moderno:float f(int a, int b, char ch)

    Sin embargo, la siguiente declaracin es incorrecta porque cadaparmetro debe incluir su propio nombre:

    f(int x, y, float z) /* declaracin incorrecta */

    FUNCIONES QUE DEVUELVEN VALORESEn C, una funcin devuelve un valor a la rutina que la llama usando la

    palabra clave return. Para ilustrarlo, puede reescribirse el programa anteriorque imprime el producto de dos nmeros. Obsrvese que este valor se asigna auna variable situando la funcin en la parte derecha de la sentencia deasignacin:

    Cap.1-22

  • Captulo 1: Principios fundamentales Programacin en C

    /* Un programa que utiliza -return- */

    # include

    main(){

    int respuesta;

    respuesta = mul(10 , 11);

    printf("la respuesta es %d \n", respuesta);}/* Esta funcin devuelve un valor */

    mul(int a , int b){

    return a * b ;}

    El valor devuelto por la sentencia return llega a ser el valor de mul()en la rutina que la llama.

    Usando la sentencia return sin ningn valor se puede volver de unafuncin. Adems se puede usar ms de un return en una funcin.

    Hay tipos diferentes de variables, y por tanto tipos diferentes devalores devueltos por una funcin. El tipo que la rutina mul() devuelve es intpor defecto. La forma general de una funcin es:

    tipo nombre_de_funcin(lista_de_parmetros){

    sentencias}

    Aqu tipo especifica el tipo de valor que devuelve una funcin. Unafuncin puede devolver cualquier tipo de dato excepto un array. Si no hay unespecificador del tipo de datos, entonces el compilador de C automticamentesupone que la funcin devuelve un entero. En otros palabras, int es el tipoimplcito cuando no aparece un especificador de tipo. Ese es el motivo de queno se hayan tenido que utilizar declaraciones explcitas de tipo en lasfunciones que se escribieron anteriormente.

    Cuando una funcin devuelve un tipo diferente de un int, se debedeclarar explcitamente. Esta funcin, por ejemplo, devuelve un double:

    /* calcular el volumen de un cubo */

    double (double S1, double S2, double S3).{

    return S1 * S2 * S3;}

    Antes de poder utilizar una funcin que devuelva un valor que no esentero, debe informarse al compilador sobre el tipo de valor de retorno. Sino se hace, el compilador generar el cdigo suponiendo que se estdevolviendo un entero. Hay dos modos de informar al compilador sobre el tipode valor de retorno de una funcin antes de su compilacin:

    A) Mtodo tradicional (obsoleto)

    B) Prototipo de funcin

    Cap.1-23

  • Captulo 1: Principios fundamentales Programacin en C

    MTODO TRADICIONALEl mtodo tradicional de informar al compilador sobre el tipo de valor

    de retorno consiste en especificar, cerca del principio del programa, el tipoy el nombre de la funcin, seguidos de parntesis de apertura y cierre y unpunto y coma. Por ejemplo esta sentencia:

    double volumen();

    Le indica al compilador que volumen() devolver un double. El siguienteprograma utiliza volumen(). Obsrvese donde se declara la funcin:

    # include

    double volumen(); /* informa al compilador sobre volumen() */

    main(){

    double vol;

    vol = volumen(12.2, 5.67, 9.03);

    printf("volumen = %f", vol);}

    /* Esta funcin calcula el volumen de un cubo */

    double volumen(double S1, double S2, double S3){

    return S1 * S2 * S3 ;}

    Si una funcin no devuelve ningn valor el compilador y el compiladores compatible con el C del estndar ANSI, puede declararse la funcin comovoid. Esto le indica al compilador que la funcin no devuelve ningn valor eimpide que se utilice en la parte derecha de una sentencia de asignacin. Elsiguiente programa utiliza una funcin void:

    # include

    void mensaje();

    main(){

    mensaje();}

    void mensaje(){

    printf("Esto es un mensaje");}

    La funcin main() puede devolver un valor entero al sistema operativo. Este valor de retorno se interpreta generalmente como un cdigo determinacin. Un valor de retorno de 0 indica una terminacin satisfactoria.Cualquier otro valor significa que el programa termin a causa de un error.Si no se especifica ningn valor de retorno, la mayora de los compiladoresdevuelven automticamente el valor 0. Aunque no es necesario, muchosprogramadores declaran main() como void cuando no se utiliza un valor deretorno explcito. No es necesario declarar main() por adelantado ya que nole llama ninguna otra funcin en el programa.

    Cap.1-24

  • Captulo 1: Principios fundamentales Programacin en C

    PROTOTIPO DE FUNCINEl segundo modo de informar al compilador sobre el valor de retorno de

    una funcin es utilizando un prototipo de funcin. El prototipo ampla elmtodo descrito en el apartado anterior, declarando tambin el nmero y tiposde los argumentos de la funcin. Los prototipos tambin permiten que Cencuentre e informe sobre cualquier conversin ilegal de tipo entre el tipode argumentos utilizados para llamar a una funcin y la definicin de tipo desus parmetros. Los prototipos tambin facultan al compilador para que informecundo el nmero de argumentos de una funcin no es el mismo que el nmero deparmetros declarados en la funcin.

    La versin original de C no soportaba prototipos de funcin. Los aadiel comit de estandarizacin del ANSI C, y se consideran como una de lasmayores ampliaciones hechas al lenguaje C.

    Aqu se muestra la forma general de definicin de un prototipo defuncin:

    tipo nombre_de_funcin(tipo nombre_de_parmetro 1, tiponombre_de_parmetro 2,...;tipo nombre_de_parmetro N);

    Aqu aparece el programa de clculo de volumen desarrollado en elapartado anterior utilizando un prototipo de funcin:

    # include

    /* este es un prototipo de volumen() */double volumen(double S1, double S2, double S3);

    void main(){

    double vol;

    vol = volumen(12.2, 5.67, 9.03);printf("Volumen: %f", volumen);

    }

    /* Calcula el volumen de un cubo */

    double volumen(double S1, double S2, double S3){

    return S1 * S2 * S3 ;}

    Puede que los prototipos no parezcan importantes en programa tanpequeos como este. Sin embargo, al aumentar los programas, los prototiposayudarn a evitar errores.

    Cuando el comit de estandarizacin de ANSI C aadi losprototipos de funcin a C, se tuvieron que resolver dos problemas menores decompatibilidad entre la versin antigua de C y la versin ANSI C relativos alos prototipos. La primera cuestin fue cmo gestionar el mtodo dedeclaracin tradicional, que no utiliza una lista de argumentos. El estndarANSI especifica que cuando se produce una declaracin de funcin si una listade argumentos, no se indica nada sobre los argumentos de la funcin. Estolleva a una pregunta: cmo se escribe el prototipo de una funcin que no tomaargumentos? Por ejemplo, esta funcin muestra simplemente una lnea de puntos:

    Cap.1-25

  • Captulo 1: Principios fundamentales Programacin en C

    void line(){

    int = i;for( 1=0 ; i < 80 ; i++ )

    printf (".") ;}

    Si se intenta utilizar lo que viene a continuacin como un prototipo,no funcionar, ya que el compilador pensar que se est utilizando el mtodode declaracin tradicional:

    void line();

    El comit ANSI resolvi este problema ampliando el uso de la palabraclave void. Cuando una funcin no tiene parmetros, su prototipo utiliza voiddentro de los parntesis. Por ejemplo, aqu aparece el prototipo adecuado paraline();

    void line(void);

    Este le indica al compilador que la funcin no tiene parmetros, ycualquier llamada a dicha funcin que tenga parmetros es un error. Sinembargo, tambin tiene que asegurarse de utilizar void cuando se define lafuncin. Por ejemplo, line() debe tener este aspecto:

    void line(void){

    int i;for( i = 0 ; i < 80 ; i++ )

    printf(".") ;}

    Aunque no es necesario, por razones de consistencia muchos programadoresdeclaran main() como sigue:

    void main(void)

    Este enfoque tambin se utilizar a partir de ahora. Sin embargo, comopronto se ver main() puede tener argumentos.

    Un segundo asunto relacionado con los prototipos es el modo en queafectan a las conversiones de tipo automticas de C. Debido a algunascaractersticas del entorno en que se desarroll C, cuando se llama a unafuncin que no tiene prototipo, todos los caracteres se convierten en enterosy todos los float en double. Sin embargo, estas conversiones de tipo pareceque violan el propsito de los prototipos. La solucin a este problema es quecuando existe un prototipo, los tipos especificados en el prototipo semantienen, y no se producir ninguna conversin de tipo.

    Los prototipos de funcin ayudan a escribir los programas de forma mssencilla, ya que facilitan que se llame a las funciones en los programas consus tipos y nmeros de argumentos correctos.

    Valores devueltos.- Como se dijo, todas las funciones, excepto las quese declaran de tipo void, devuelven un valor. Este valor es definidoexplcitamente por una sentencia return, o es 0 si no se usa tal sentencia.As, mientras no se declara una funcin como void, se puede usar como unoperando en cualquier expresin vlida de C. Por tanto, cada una de lassiguientes es vlida en C:

    x = abs(y);

    if(max(x,y) > 100) printf("mayor");

    for(ch = getchar(); isdigit(ch);....);

    Cap.1-26

  • Captulo 1: Principios fundamentales Programacin en C

    Sin embargo, una funcin no puede ser el objeto de una asignacin. Unasentencia como

    swap(x, y) = 100 ; /* sentencia errnea */

    es errnea, el compilador de C lo indicar como un error y no compilar unprograma que contenga tal sentencia.

    Aunque todas las funciones que no son de tipo void devuelven valores,las funciones que se escribirn habitualmente sern de tres tipos. El primeroes simplemente de clculo. Se disea esta funcin especficamente pararealizar las operaciones sobre sus argumentos y devolver un valor basado enesa operacin.

    El segundo tipo de funciones manipula informacin y devuelve un valorque indica simplemente si esta manipulacin sali bien o fall.

    El ltimo tipo de funciones no tiene un valor de retorno explcito. Enesencia, la funcin es estrictamente procedural y no produce valor.

    Si no se especifica una asignacin, entonces la computadora simplementedescarta el valor devuelto. Considerar el siguiente programa que usa mul():

    # include

    main(){

    int x, y, z;

    x = 10;y = 20;

    z = mul(x, y); /* 1 */printf("%d", mul(x,y) ); /* 2 */mul(x, y); /* 3 */

    }mul(int a, int b){

    return a*b;}

    La lnea /* 1 */ asigna el valor devuelto por mul() a z. En la lnea/* 2 */, el valor devuelto no est realmente asignado, sino que printf() lousa. Finalmente, el la lnea /* 3 */ el valor devuelto se pierde porque no loasigna a otra variable ni lo usa como parte de una expresin.

    Ejemplo de la utilizacin de funciones de usuario:

    Cap.1-27

  • Captulo 1: Principios fundamentales Programacin en C

    PROGRAMA C EN CDIGO FUENTECOMENTARIO

    /* PEDIDO.C Un ejemplo de las partes bsicasde un programa C */

    DIRECTIVAS DEL PREPROCESADOR

    #include #include

    CUERPO DEL PROGRAMA

    PROTOTIPOS DE FUNCINfloat calc_sub_total( int cantidad, float precio );float calc_tax( float sub_total );

    PROGRAMA PRINCIPAL

    main(){char nombre[30];char producto[30];int cantidad;float precio;float sub_total;float tax;

    clrscr();printf( "\n\nIntroduzca su apellido => " );scanf( "%s", nombre );printf( "\n\nIntroduzca el nombre de un producto => " );scanf( "%s", producto );printf( "\n\nIntroduzca la cantidad y el precio => " );scanf( "%d %f", &cantidad, &precio );

    sub_total = calc_sub_total( cantidad, precio );tax = calc_tax( sub_total );

    clrscr();printf( "\n\nInformacin del pedido\n\n" );printf( "Nombre: %s\n", nombre );printf( "Producto pedido: %s\n\n", producto );printf( "Cantidad solicitada: %d\n\n", cantidad );printf( "Precio por unidad: %3.2f\n", precio );printf( "Sub-total: %3.2f\n", sub_total );printf( "Impuestos: %3.2f\n", tax );printf( "Total: %3.2f\n", ( sub_total + tax ) );

    }

    FUNCIN DE USUARIO 1float calc_sub_total( int cantidad, float precio ){float sub_total;

    sub_total = precio * cantidad;return sub_total;

    }

    FUNCIN DE USUARIO 2float calc_tax( float sub_total ){const float tax_rate = 0.06;

    float tax;

    tax = sub_total * tax_rate;return tax;

    }

    1.7 CONSOLA DE ENTRADA/SALIDA EN C

    La consola de E/S se refiere a las operaciones se producen entre elteclado y la pantalla de la computadora.

    En C no hay instrucciones propias de E/S como en otros lenguajes. En sulugar existen bibliotecas que contienen las funciones que suplen estadefinicin.

    Cap.1-28

  • Captulo 1: Principios fundamentales Programacin en C

    Hay que recordar que las funciones de librera deben tener declarado suarchivo de cabecera (.h) correspondiente.

    FUNCIONES BSICAS DE E/SArchivo de cabecera Entrada Salida

    * getchar() putchar()

    scanf() printf()

    **getch() clrscr()*

    getche() * slo Turbo C

    kbhit()

    *Librera estndar de C, todos los compiladores**Librera de consola no estndar, las funciones indicadas estn en:

    .- Compilador Turbo C

    .- Compilador Microsoft C

    ENTRADA/SALIDA SIMPLELas funciones ms sencillas de entrada/salida de consola son las

    referentes a la lectura y escritura de caracteres sobre la consola: Acontinuacin se describen brevemente.

    para la LECTURA de un carcter desde teclado:

    getchar().- Acepta un carcter y lo imprime por pantalla. Su prototipoes:

    int getchar(void);

    Tiene el inconveniente de esperar a que se pulse la tecla de retorno(< ) para que el dato sea enviado a la computadora. Este efecto es muyengorroso en entornos interactivos.

    getche().- Espera a pulsar una tecla y despus devolver su valor. Lafuncin tambin hace "eco" de la tecla pulsada automticamente en lapantalla. Su prototipo es:

    int getche(void);

    getch().- Es una variacin de getche(); funciona de la misma maneraexcepto que getch() no hace "eco" de los caracteres tecleados.

    kbhit().- Esta funcin se utiliza para determinar si se ha pulsado unatecla o no. Si el usuario ha pulsado una tecla, esta funcin devuelve"verdadero" (distinto de 0), pero no lee el carcter. Si hay unapulsacin de tecla esperando se puede utilizar una de las funcionesvistas anteriormente. Si no hay pendiente ninguna pulsacin de tecla,kbhit() devuelve "falso". Su prototipo es:

    int kbhit(void);

    Cap.1-29

  • Captulo 1: Principios fundamentales Programacin en C

    Un ejemplo para la utilizacin de kbhit() es:

    # include

    int tecla_pulsada, ch;

    main(){

    tecla_pulsada = kbhit();

    if(tecla_pulsada = 0)ch = getch;

    }

    Es muy til cuando se quiere permitir que el usuario interrumpa unarutina sin forzar realmente al usuario a responder continuamente a unindicador como "continuar?".

    Para la VISUALIZACIN de un carcter:

    putchar().- La funcin putchar() muestra un slo carcter en lapantalla. Aunque su parmetro se declara de tipo int, la funcin loconvierte en un unsigned char. Su prototipo de funcin es:

    int putchar(int ch);

    clrscr().- Limpia la pantalla en modo texto. Su prototipo de funcines:

    void clrscr(void);

    ENTRADA/SALIDA CON FORMATOAdems de las sencillas funciones de E/S de consola descritas

    anteriormente, la biblioteca de C estndar contiene dos funciones que realizanla entrada y salida formateada en los tipos de datos predefinidos, queincluyen caracteres, cadenas y nmeros: printf() y scanf(). El trminoformatear se refiere al hecho de que estas funciones pueden leer y escribirdatos en diversos formatos que estn bajo control. La funcin printf() seutiliza para visualizar en pantalla y scanf(), el complemento de printf(),para introducir datos por teclado. Estas funciones se examinan con detalle.

    printf().- La funcin printf() su prototipo es:int printf(char* cadena de control, lista de argumentos);

    Este prototipo de funcin est en el fichero de cabecera stdio.h. LaCADENA DE CONTROL consta de 2 tipo de elementos:

    1 Los caracteres que se imprimirn en la pantalla.

    2 rdenes de formato que definen la manera en que se visualizarn losargumentos.

    Debe haber el mismo nmero de argumentos que de rdenes de formato yambos deben encajar en orden (emparejados de izquierda a derecha).

    En otras palabras, en la funcin printf(), la cadena de control contienelos caracteres que se visualizarn en la pantalla y las rdenes que le dicena printf() cmo visualizar el resto de los argumentos.

    Se pueden poner las rdenes de control de formato en cualquier lugar de

    Cap.1-30

  • Captulo 1: Principios fundamentales Programacin en C

    la 1 cadena de caracteres. Cuando se llama a printf(), sta rastrea la cadenade control. La funcin slo imprime los caracteres regulares que aparecen.Cuando encuentra una orden de formato printf() la memoriza y la usa cuandoimprime los argumentos apropiados.

    Las rdenes de formato de printf() son:

    Cdigo formato

    %c Un slo carcter (en el argumento entre comillas simples)

    %d Entero decimal con signo

    %i Idem

    %e Notacin cientfica ("e" minscula)

    %E Notacin cientfica ("E" mayscula)

    %f Punto flotante

    %g Utiliza %e o %f el que sea ms corto

    %G Utiliza %E o %f el que sea ms corto

    %o Octal sin signo

    %s Cadena de caracteres (en el argumento entre dobles comillas)

    %u Entero decimal sin signo

    %x Hexadecimal sin signo (letra minscula)

    %X Hexadecimal sin signo (letra mayscula)

    %p Muestra un puntero

    %n El argumento asociado es un puntero a entero que se leasigna el n de caracteres escritos hasta el momento

    %% Imprime el carcter "%"

    %hd Muestra un short

    %ho Muestra un short

    %hx Muestra un short

    %hu Muestra un short unsigned int

    %ld Muestra un long

    %lo Muestra un long

    %lx Muestra un long

    %lf Muestra un double

    %le Muestra un double

    %lg Muestra un double

    %Ld Muestra un long double

    Cap.1-31

  • Captulo 1: Principios fundamentales Programacin en C

    %Lf Muestra un long double

    %Le Muestra un long double

    %Lg Muestra un long double

    La funcin printf() permite incluir dentro de la cadena de caractereslas constantes del carcter barra invertida de C (ver apartado de CONSTANTES),resumidos a contnuacin:

    \n Nueva lnea

    \t Tabulador horizontal

    \" Doble comilla

    \\ Barra invertida

    \N Constante octal ( N es el n octal)

    \xN Constante hexadecimal (N es el n hexadecimal)

    Las rdenes de formato (excepto %%, %p y %c) pueden tener modificadoresque especifican el ancho del campo, el n de lugares decimales y el indicadorde justificacin a la izquierda.

    Aqu se muestra la forma general de un especificador de formato. Loselementos opcionales se muestran entre corchetes.

    %[-][longitud_mnima_de_campo][.][precisin]especificador de formato

    Un entero puesto entre el signo % y el orden de formato acta como unespecificador mnimo de ancho de campo. Este completa la salida con blancoso ceros para asegurar que AL MENOS es la longitud mnima. Si una cadena onmero es mayor que el mnimo, se imprimir completa, incluso si desborda elmnimo. El relleno por defecto se hace con espacios. Si se desea rellenar conceros, poner cero antes del especificador de ancho de campo. Por ejemplo:

    %05d

    Rellenar una serie de 5 dgitos con ceros hasta un total de cinco.

    Para especificar el nmero de puestos decimales impresos para un nmeroen punto flotante, poner un punto decimal seguido por el nmero de decimalesque se desean visualizar despus del indicador de ancho de campo. Por ejemplo:

    %10.4d

    Visualizar un nmero que tendr al menos 10 caracteres de largo ycuatro posiciones decimales (si hay ms trunca). Cuando se aplica un formatocomo este a cadenas o enteros, el nmero que sigue al punto especifica lalongitud mxima del campo. Por ejemplo:

    %5.7s

    Visualizar una cadena con al menos 5 caracteres de largo y no menos de7. Si la cadena es ms larga que el ancho mximo del campo, la computadoratruncar los caracteres desde el final.

    Por defecto, toda salida es justificada a la derecha: si el ancho delcampo es mayor que los datos impresos, se pondr en el lado derecho del campo.Se puede forzar que la informacin se justifique a la izquierda poniendo unsigno menos directamente despus de %.

    Cap.1-32

  • Captulo 1: Principios fundamentales Programacin en C

    Por ejemplo:%-10.2f

    Justificar a la izquierda un nmero en punto flotante con dosposiciones decimales en un campo de 10 caracteres.

    Con printf() se puede sacar virtualmente cualquier tipo de formato, acontinuacin se presenta algunos ejemplos:

    printf("2 + 2"); x = 2;

    Visualiza: 2 + 2 y = 3;

    printf("%d", 2+2); z = 10;

    Visualiza: 4 a = (y * z) / x;

    x = 10; printf("%d", a);

    printf("%d", x); Visualiza 15

    Visualiza: 10 x = 2;

    printf("%-5.2f", 123.234); y = 3;

    Visualiza: |123.23| z = 10;printf("%5.2f", 3.234); printf("%d",(y * z) / 2);

    Visualiza: | 3.23| Visualiza: 15printf("%10s","hola"); printf("%-10s","hola");

    Visualiza: | hola| Visualiza: |hola |printf("5.7s","123456789"); printf("\a");

    Visualiza: |1234567| Visualiza: emite pitidoprintf("%s %d", "esto es una cadena", 100);

    Visualizar: esto es una cadena 100

    printf("esto es una cadena %d", 100);

    Visualiza: esto es una cadena 100

    printf("nmero %d es decimal, %f es float", 10, 110.789);

    Visualiza: nmero 10 es decimal, 110.789 es float

    scanf()La funcin scanf() es una rutina de entrada de propsito general. Puede

    leer todos los tipos de datos predefinidos y automticamente los convierte enel formato interno adecuado. Es el reverso de printf(). El formato general descanf() es:

    int scanf(char *cadena de control, lista de argumentos);

    Cap.1-33

  • Captulo 1: Principios fundamentales Programacin en C

    El prototipo de scanf() est en stdio.h la cadena de control consta detres clasificaciones de caracteres:

    A) Especificadores de formato

    B) Caracteres de espacio en blanco

    C) Caracteres de no espacio en blanco

    A) Los especificadores de formato de entrada son precedidos por un signo% y le dicen a scanf() qu tipos de datos se leen a continuacin. Estoscdigos se listan en la tabla adjunta.

    B) Un carcter de espacio en blanco en la cadena de control provocarque scanf() lea, pero no almacene, cualquier nmero (incluido el cero) decaracteres de espacio en blanco hasta el primer carcter de no espacio enblanco.

    C) Un carcter de no espacio en blanco provoca que scanf() lea ydescarte el carcter que "encaja". Por ejemplo:

    "%d,%d"

    Fuerza a scanf() a descartar una coma despus de leer un entero yposteriormente leer otro entero. Si no se encuentra el carcter especificado,terminar scanf() de forma incorrecta.

    Cdigo significado

    %c Lee un slo carcter

    %d Lee un entero decimal

    %i Idem

    %e Lee un n en punto flotante

    %f Idem

    %g Idem

    %o Lee un n octal sin signo

    %s Lee una cadena de caracteres

    %u Lee un entero sin signo

    %x Lee un n hexadecimal sin signo

    %p Lee un puntero

    %n Recibe un valor entero igual al nmero de caracteres ledoshasta el momento

    %[] Inspecciona un juego de caracteres

    Por ejemplo, si se desea leer un entero en la variable cont se debeutilizar la siguiente llamada:

    scanf("%d", &cont);

    Cap.1-34

  • Captulo 1: Principios fundamentales Programacin en C

    Todas las variables usadas para recibir valores a travs de scanf()deben pasarse por sus direcciones (&cont seala la direccin de memoria dondese guardar el valor de la variable cont). Esto significa que todos losargumentos deben ser "apuntados" por sus direcciones. Esta es la manera decrear una "llamada por referencia" y permite alterar el contenido de unargumento.

    Las cadenas se leern en arrays de caracteres, el nombre del array(tabla), sin ningn ndice, es la direccin del primer elemento del array.Suponiendo que la direccin es el nombre de un array de caracteres, para leeruna cadena en la tabla address, usa:

    scanf("%s", address);

    En este caso, address ya es un "puntero" y no necesita precederse porel operador &.

    A los especificadores %d, %i y %u los puede modificar h (%hd, etc)cuando se introducen los datos en una variable short y l (%li, etc) cuando seintroduce una variable long.

    Los especificadores %e, %f y %g son equivalentes. Todos leen nmeros encoma flotante representados bien en notacin cientfica o bien en notacindecimal estndar. Sin modificar introducen un valor en una variable float. Sepueden modificar como en los casos anteriores pero utilizando l cuando seutilizan datos en un double. Para leer un long double, se modifican con un L.

    Los datos escritos en el teclado DEBEN estar separados por espacios,tabuladores o nuevas lneas. La puntuacin como comas, punto y coma ysimilares no cuentan como separadores. Ejemplo:

    scanf("%d%d", &r, &s);

    Aceptar una entrada por teclado como 10 20, pero falla con 10, 20. Comoprintf(), los cdigos de formato de scanf() encajan en orden con las variablesque reciben la entrada en una lista de argumentos.

    Un asterisco"*" puesto detrs de % y antes del cdigo de formato leerdatos del tipo especificado, pero suprimir su asignacin. As:

    scanf("%d%*c%d", &x, &y);

    Dada la entrada 10/20, pondr el valor 10 en x, descarta el signo dedividir y da a y el valor de 20. Esto puede ser muy til cuando se introduceinformacin que contiene caracteres innecesarios.

    Se puede utilizar scanf() para que lea una cadena utilizando elespecificador %s pero probablemente no lo har. Este es el motivo: cuandoscanf() introduce una cadena, detiene su lectura de la cadena al encontrar elprimer espacio en blanco. (un espacio en blanco es tanto un espacio, como untabulador o un salto de lnea). Por ejemplo: para leer entradas como estas enuna cadena:

    Esto es una cadena

    Puesto que hay un espacio despus de "Esto", scanf() detiene la entradade la cadena en ese punto. Ese es el motivo por el que generalmente se utilizagets() para introducir cadenas.

    El especificador %p introduce la direccin de memoria utilizando elformato que termina el entorno de la mquina. El especificador %n indica ascanf() que asigne a la variable apuntada por el correspondiente argumento elnmero de caracteres ledos desde la secuencia de entrada hasta el punto enel que se encuentra %n.

    Cap.1-35

  • Captulo 1: Principios fundamentales Programacin en C

    A %n lo puede modificar l o h para que asigne su valor a una variablelong o short.

    Una caracterstica importante de scanf() se llama conjunto deinspeccin. Un especificador de conjunto de inspeccin se crea poniendo unalista de caracteres entre corchetes. Por ejemplo, aqu hay un especificadorde conjunto de inspeccin que contiene las letras "VEM".

    %[VEM]

    Cuando scanf() encuentra un conjunto de inspeccin, comienza a leer loscaracteres y los asigna al array de caracteres al que apunta el argumentocorrespondiente de conjunto de inspeccin. Tan pronto encuentre un carcterque no forma parte del conjunto de inspeccin, scanf() detiene la lectura deeste especificador y pasa a cualquier otro de la cadena de control.

    Se puede especificar un rango en un conjunto de inspeccin utilizandoel guin "-". Por ejemplo, este conjunto de inspeccin especifica loscaracteres de la A a la Z.

    %[A-Z]

    Cuando el conjunto de inspeccin es muy largo, a veces es ms fcilespecificar lo que no forma parte del conjunto de inspeccin. Para hacer esto,se precede al conjunto con un "^" (acento circunflejo). Por ejemplo:

    %[^0123456789]

    Cuando scanf() encuentra este conjunto de inspeccin, leer cualquiercarcter excepto los dgitos del 0 al 9.

    Se puede especificar una longitud mxima de campo para todos losespecificadores excepto %c, cuya longitud es siempre de un carcter, y %n alque no se aplica el concepto. La longitud mxima de campo se especifica comoun entero sin signo, y precede inmediatamente al carcter especificado deformato. Por ejemplo, esto limita a 20 caracteres la longitud mxima de unacadena asignada a str:

    scanf("%20s", str);

    Si la corriente de entrada (informacin introducida por teclado) fuerams grande de 20 caracteres, entonces la llamada posterior a entrada empezaradonde se dej esta llamada. Por ejemplo, si se introduce

    ABCDEFGHIJKLMNOPQRSTUVWXYZ

    como respuesta a la anterior llamada, scanf(), slo los 20 caracteres -o hastala "T"- tendran que recogerse en str debido al tamao especificado. Estosignifica que los caracteres restantes "UVWXYZ", no se han usado todava ypermanece en el buffer del lnea (memoria intermedia utilizada por el PC paracontener los datos introducidos por teclado). Si se hace otra llamada ascanf(), tal como

    scanf("%s", str);

    entonces "UVWXYZ" se pondran en str.

    Si aparece un espacio en la cadena de control (entre las comillas)ejemplo:

    scanf("%d %d", a,b );

    Entonces scanf() empezar a leer pero no almacenar los espacios enblanco.

    Cap.1-36

  • Captulo 1: Principios fundamentales Programacin en C

    Recordar que si aparece cualquier otro carcter en la cadena de control,scanf() lee y descarta todos los caracteres que coincidan con l hasta queencuentre el primer carcter que no sea coincidente. Por ejemplo, dada lacorriente de entrada 10t20, con:

    scanf("%st%s", &x, &y);

    Se pondr 10 en x y 20 en y. El carcter "t" se descarta porque es un carcterde control.

    Un ltimo punto: debido al uso de entrada con buffer de lnea tiende ahacer de scanf() una funcin que dificulta la interactividad.

    PALABRAS RESERVADAS DEL LENGUAJE

    Como en los otros lenguajes de programacin, C consta de palabras clave(reservadas) y reglas de sintaxis que se aplican a cada palabra clave. Unapalabra clave es esencialmente una orden y, a una gran extensin, las palabrasclave de un lenguaje definen lo que se puede hacer y cmo se har.

    Tal como establece el estndar ANSI, existen 32 palabras reservadas (27originales + 5 ANSI) que aparecern siempre en minscula, y se muestran acontinuacin:

    PALABRAS RESERVADAS ORIGINALES

    auto extern short

    break float sizeof

    case for static

    char goto struct

    continue if switch

    default int typedef

    do long union

    double register unsigned

    else return while

    PALABRAS RESERVADAS INTRODUCIDAS POR ANSI

    const signed volatile

    enum void

    PALABRAS RESERVADAS DE TURBO C

    asm _cs _ds

    _es ss cdel

    far huge interrupt

    near pascal

    La segunda serie de palabras reservadas la introdujo el comit denormalizacin ANSI.

    Cap.1-37

  • Captulo 1: Principios fundamentales Programacin en C

    Muchos compiladores han aadido varias palabras clave adicionales quese utilizan para aprovechar mejor la organizacin de memoria de la familia deprocesadores 8086 y que dan soporte a la programacin con mltiples lenguajesy a las interrupciones.

    Cap.1-38

  • Captulo 1: Principios fundamentales Programacin en C

    EJERCICIOS PROPUESTOS, CAPTULO 11) Suponiendo que todas las variables son de tipo int, indicar el

    valor de cada una de las siguientes expresiones:

    A) x = (5 + 2) * 4;B) x = (3 + 2) / 4 * 5;C) x = y = (2 + 4) * 6;D) x = (int)2.4 * 4.5;E) x = (3 + 3) * 10.5;

    2) Dan el mismo resultado estas expresiones?

    x = y / 3 - 34 * temp -127x = (y / 3) - ( (34 * temp) -127 )

    3) Evaluar las siguientes expresiones:

    A) 2 > 3B) a < bC) 2 == 3D) 3 == 3

    4) Reescribir la siguiente instruccin utilizando el operadorincremental y usando el operador de asignacin aritmtica.

    x = x + 1;

    5) Indicar cul de las siguientes proposiciones son ciertas y culesson falsas:

    A) 10 > 3B) B > DC) 10 > 4 || 7 > 9D) !(10 > 3)E) !(10 == 9)

    6) Construir una expresin para indicar las siguientes condiciones:

    A) num es mayor que 3 y menor que 9.B) ch no es una b ni una c.C) num est entre 3 y 9 ambos inclusive. Pero no es 6.D) num no est entre 3 y 9.

    7) Cul es el valor numrico de las siguientes expresiones:

    A) 7 > 2B) 1 + 3 > 2 && 4 < 1C) x > y || y > x || X == yD) 5 + (7 > 4)

    8) Dadas estas variables:

    char ch;short i;unsigned long ul;float;

    Cul es el tipo que incluye a las dems en esta expresin?

    f / ch -(i * ul);

    Cul es el tipo de la subexpresin i*ul de arriba?

    Cap.1-39

  • Captulo 1: Principios fundamentales Programacin en C

    9) Qu muestra este programa?

    #include main(){

    float f;f = 10/3;printf("%f", f);

    }

    10) Qu imprimir este programa?

    #define NUM 4

    main(){

    char car1, car2;float num;

    car1 = S;car2 = O;num = NUM ;

    printf("%c%c%c-%1d-%2.1f\n", car1, car2, car1, NUM,num);}

    11) Qu imprimir el siguiente programa?

    #include#define EJEMPLO "%s esto es un ejemplo\n"

    main(){

    int x = 0;

    printf (EJEMPLO,EJEMPLO);printf ("%d\n", x++);printf ("%d\n", ++x);printf ("%d\n", x--);printf ("%d\n", x);

    }

    12) Introducir, compilar y ejecutar el primer programa de lateora.

    13) Escribir un programa que declare una variable entera llamadanmero y se le asigne el valor del ao actual. Mostrar el valor en pantalladel modo siguiente:

    El ao actual es: ____

    14) Realizar un programa que lea una cadena que contiene 5 espacios("Esta cadena si la toma scanf()") utilizando la funcin scanf(), por mediodel conjunto de inspeccin.

    15) Escribir un programa que sume y reste 2 nmeros (punto flotante).Los operandos deben ser ledos por teclado.

    16) Calcular la longitud de una circunferencia. Pidindose el radioy dando el resultado en pantalla.

    17) Calcular el nmero de segundos que tiene un ao y presentarlo enpantalla.

    Cap.1-40

  • Captulo 1: Principios fundamentales Programacin en C

    18) Son correctos estos comentarios?

    / ** //* printf("Esto es un comentario?"); */

    19) Empleando funciones creadas por el usuario, realizar un programaque calcule el cuadrado y el cubo de un nmero dado por teclado.

    20) Dada una cantidad en formato decimal, presentar en pantalla suequivalente hexadecimal y octal.

    Cap.1-41

  • CAPTULO 2

    Sentencias de Control en C

  • Captulo 2: Sentencias de control en C Programacin en C

    2.1 INTRODUCCINUn programa es un conjunto de mandatos que puede someterse como unidad,

    a un ordenador y utilizarse para dirigir su comportamiento. Cada uno de losmandatos recibe el nombre de Sentencia o instruccin.

    El conjunto de sentencias de programa son la esencia de cualquierlenguaje. Las sentencias en C son ricas y poderosas y ayudan a explicar lapopularidad del lenguaje.

    A continuacin se realiza una clasificacin de los tipos de sentenciasrecogidas en C:

    SECUENCIAL

    Simple

    Compuesta

    CONDICIONAL

    Simple

    Doble

    Mltiple

    (ruptura)

    (continuacin)

    (por defecto)

    REPETITIVA

    Mientras

    Hacer mientras

    Para (desde Vini. hasta Vfin.) hacer

    INCONDICIONAL

    2.2 SENTENCIAS DE TIPO SECUENCIAL

    Las sentencias se ejecutan en orden natural, una detrs de otra, segnestn escritas en el cdigo fuente del programa; sin embargo, solo losprogramas ms sencillos utilizan nicamente ejecucin secuencial. C ofrecesentencias de control (ver apartados siguientes) que sirven para cambiar elorden secuencial de ejecucin de las instrucciones.

    Las secuencias de tipo secuencial se divide en:

    - Sentencia simple

    - Sentencia compuesta

    Cap.2-2

  • Captulo 2: Sentencias de control en C Programacin en C

    SENTENCIA SIMPLE

    Las sentencias simples, tambin denominadas en ocasiones instruccionesprimitivas, son aquellas que el procesador ejecuta de forma inmediata.

    En C se denomina sentencia a una expresin seguida de ";".

    El formato general es:

    ;

    Como ejemplo se presentan 3 sentencias; una de asignacin, otra deentrada de datos y la ltima de salida de datos:

    x = 12 + (10 * valor) / 5 ;

    scanf("%d", &valor) ;

    printf("Su valor es: %d", variable) ;

    SENTENCIA COMPUESTA

    Una sentencia compuesta es un grupo de sentencias individuales, cada unaseparada de la siguiente por ";", y que son tratadas en su conjunto como unasola sentencia.

    Las sentencias compuestas estn encerradas entre llaves ("{", "}").

    El formato general es:

    {

    sentencia_1 ;

    sentencia_2 ;

    .....

    sentencia_n ;

    }

    Un ejemplo de sentencia compuesta podra consistir en agrupar lassentencias del ejercicio anterior para que sean consideradas como una unidad:

    {

    x = 12 + (10 * valor) / 5 ;

    scanf("%d", &valor) ;

    printf("Su valor es: %d", variable) ;

    }

    2.3 SENTENCIAS CONDICIONALES

    Las sentencias condiciones son aquellas que deciden la ejecucin de unao varias instrucciones en funcin de una condicin dada. Existen tres tiposde sentencias condicionales.

    Cap.2-3

  • Captulo 2: Sentencias de control en C Programacin en C

    - Condicional simple

    - Condicional doble (y operador "?")

    - Condicional mltiple

    SENTENCIA CONDICIONAL SIMPLE

    El formato general es:

    if(expresin) sentencia ;

    En esta instruccin, la condicin es una expresin BOOLEANA. Lasentencia (que puede ser simple o compuesta) se ejecuta solamente SI laevaluacin de la condicin produce el resultado "CIERTO"; si es "FALSA"(expresin = a "0") no se ejecuta la sentencia. Ejemplos:

    Con sentencia simple:

    if(n > 10)

    printf("%d es mayor que 10 \n", n) ;

    Cap.2-4

  • Captulo 2: Sentencias de control en C Programacin en C

    Con sentencia compuesta:

    if(opcion == 1)

    {

    printf("opcion = 1\n") ;

    printf("Introducir variable\n") ;

    scanf("%d", &variable) ;}

    Recordar que en C "verdadero" es cualquier valor que no sea "0" y falsoes "0". Por eso, es perfectamente vlido tener unas sentencias if como lasmostradas:

    if(contador + 1) printf("no es cero") ;

    if(contador) printf("no es cero) ;

    if(i = j)... equivale a if((i = j) != 0)...En la ltima sentencia el resultado es:

    1 Se realiza la asignacin i = j; (el valor de j se transfiere a i)

    2 Se comprueba si i es distinto de "0"

    SENTENCIA CONDICIONAL DOBLE

    El formato general es:

    if(expresin)

    sentencia_1 ;

    else

    sentencia_2 ;

    Si la evaluacin de la condicin produce el resultado "CIERTO" seejecutar la sentencia_1; en caso contrario se lleva a cabo la sentencia_2.

    Ejemplos:if(n % 2 == 0)

    printf("%d es par -even-\n",n) ;

    else

    printf("%d es impar -odd-\n",n) ;

    Cap.2-5

  • Captulo 2: Sentencias de control en C Programacin en C

    /* Uso de la funcin tolower() */

    #include "stdio.h"

    main(){

    int a, c;

    printf("Escribe una tecla mayscula: ");

    a = getchar();c = tolower(a);

    if(a >= A && a

  • Captulo 2: Sentencias de control en C Programacin en C

    EL ESCALONADOR IF-ELSE-IF

    Una construccin corriente es el escalonador if-else-if. Su formatogeneral es:

    if(expresin_1)sentencia_1

    else if(expresin_2)sentencia_2

    else if(expresin_3)sentencia_3

    ....

    else if(expresin_n)sentencia_n

    else

    sentencia_n+1

    Las expresiones se evalan en orden; si alguna es cierta, se ejecuta lasentencia asociada con ella y se acaba la cadena. Si todas son falsas seejecuta la sentencia asociada en el else final (accin por defecto).

    A veces, existe una accin por defecto explcita (fuera de la sentenciaif - else - if), en este caso se puede omitir el ltimo else sentencia_n+1.

    En el siguiente ejemplo del escalonador if-else-if, tan pronto comoaparece una sentencia if, se sobrepasan (puentean) el resto de las sentencias.

    /* conversin de nmeros:decimal -> hexadecimal; hexadecimal -> decimaldecimal -> octal; octal -> decimal */

    #include main(){

    int opcion, valor ;printf("Conversin :\n);printf(" 1: decimal a hexadecimal\n") ;printf(" 2: hexadecimal a decimal\n") ;printf(" 3: decimal a octal\n") ;printf(" 4: octal a decimal\n\n") ;printf("Introduzca opcin: ") ;scanf("%d", &valor) ;if(opcion==1){

    printf("Intro. valor decimal: ") ;scanf("%d", &valor) ;printf("%d en hexa. es: %x", valor, valor) ;

    }else if(opcion==2){

    printf("Intro. valor hexadecimal: ") ;scanf("%x", &valor) ;printf("%x en decimal es: %d", valor, valor) ;

    }else if(opcion==3){

    printf("Intro. valor decimal: ") ;scanf("%d", &valor) ;

    Cap.2-7

  • Captulo 2: Sentencias de control en C Programacin en C

    printf("%d en octal es: %o", valor, valor) ;}else if(opcion==4){

    printf("Intro. valor octal: ") ;scanf("%o", &valor) ;printf("%o en decimal es: %d", valor, valor) ;

    }}

    EL OPERADOR "?"

    Se utiliza para decidir entre dos valores a asignar, dependiendo de laevaluacin de una expresin lgica (binaria).

    Se puede usar el operador "?" para reemplazar las sentencias if/else.De formato general:

    if(condicin)

    expresin

    elseexpresin

    La restriccin clave del operador "?" es que el objeto del if y del elsedebe ser una expresin sencilla, no otra sentencia de C.

    "?" se llama operador "ternario" porque requiere de tres operandos. Susintaxis es:

    variable = condicin ? expresin_1 : expresin_2

    Aqu, condicin es una expresin que se evala a verdadero o falso (Ej.x > 9). Si es verdadero, se le asigna a variable el valor de expresin_1. Sies falso, se le asigna a variable el valor de expresin_2. La razn deloperador "?" es que un compilador de C que use este operador puede producircdigo ms eficiente que si usa la sentencia equivalente if/else. Unosejemplos del operador ternario seran:

    z = (a > b) ? a : b ;printf("Hay %d elemento%s \n", n, n==1 ? "" : "s") ;

    /* convierte un nmero introducido en 1 si es positivo y -1si es negativo */

    include "stdio.h"

    main()

    {

    int i ;printf("Introduzca nmero: ");scanf("%d", &i);

    i = i > 0 ? 1 : -1

    printf("%d", i);

    }

    Cap.2-8

  • Captulo 2: Sentencias de control en C Programacin en C

    SENTENCIA CONDICIONAL MLTIPLE -SWITCH-Aunque el escalonador if-else-if puede realizar comprobaciones

    mltiples, no es elegante. El cdigo puede ser difcil de seguir y puedeconfundir incluso al programador pasado el tiempo. C tiene incorporada unasentencia de bifurcacin mltiple llamada switch. En switch, el ordenadorcomprueba una variable sucesivamente frente a una lista de constantes enteraso de carcter. Despus de encontrar una coincidencia, la computadora ejecutala sentencia o bloque de sentencias que se asocia con la constante. Susintaxis es:

    switch(expresin)

    {

    case constante_1:

    secuencia de sentencias

    break;

    case constante_2:

    secuencia de sentencias

    break;

    case constante_3:

    secuencia de sentencias

    break;

    ....

    default:

    secuencia de sentencias

    break;

    }

    La sentencia switch se diferencia de if en que switch solamente puedeverificar la igualdad, mientras la expresin condicional if puede ser decualquier tipo. Adems, switch slo funcionar con tipos int o char. No sepuede, por ejemplo, utilizar nmero en punto flotante.

    Las secuencias de sentencias asociada con cada case NO son bloques, esdecir, no estn encerrados entre llaves (la sentencia switch entera define unbloque).

    El ordenador ejecuta la secuencia default sino coincide ningunaalternativa. El default es opcional; si no est presente, no se hace nada. Siencuentra una coincidencia, la computadora ejecuta las sentencias asociadascon el case hasta encontrar un break o el final de la sentencia switch. Porejemplo:

    Cap.2-9

  • Captulo 2: Sentencias de control en C Programacin en C

    #include

    main(){

    int i;

    printf("Escriba un nmero: ") ;scanf("%d", &i) ;

    switch(i){

    case 0:

    printf("cero\n") ;break ;

    case 1:case 2:

    printf("un 1 o un 2\n") ;break ;

    case 4:

    break ; /* si es 4 no escribe nada */

    case 5:case 6:

    printf("un 5 o un 6\n") ;break;

    default:

    printf("otros casos\n");break; /* opcional */

    }}

    El estndar ANSI establece que se permiten por lo menos 257 sentenciascase. En la prctica, se debera limitar la cantidad de sentencias case a unnmero mucho menor por razones de eficacia. Adems no puede haber dosconstantes case con valores idnticos en el mismo switch.

    Es posible tener un switch como parte de una secuencia de sentencias deotro switch ms externo. Esto se llama switch anidados. Si las constantes casedel switch ms externo y ms interno contienen valores comunes, no surgirnconflictos. Por ejemplo, el siguiente fragmento de cdigo es perfectamenteaceptable:

    Cap.2-10

  • Captulo 2: Sentencias de control en C Programacin en C

    switch(a){

    case 1:

    switch(b){

    case 1:

    printf("b es verdadero") ;break ;

    case f:

    printf("b es falso") ;break ;

    }

    case 2:

    ....

    }

    Un compilador del estndar ANSI permitir al menos 15 niveles deanidamiento para sentencias switch.

    Sentencia BREAK, funcionamiento en un SWITCH

    Tcnicamente, las sentencias break son opcionales dentro de la sentenciaswitch. Se utilizan para terminar la secuencia de sentencias que est asociadacon cada constante. Si se omite el break, la ejecucin continuar en lassentencias del siguiente case hasta que el ordenador encuentre un break o elfinal del switch. Pensar en los case como en etiquetas1. La ejecucincomienza en la etiqueta que coincide con la variable de control y continuarhasta que el ordenador encuentre la sentencia break o la marca de final delswitch.

    2.4 SENTENCIAS REPETITIVAS (BUCLES)Los bucles permiten repetir un conjunto de instrucciones hasta que se

    cumple cierta condicin. C soporta el mismo tipo de bucles que otros lenguajesestructurados modernos. Los bujes de C son:

    - while (mientras)

    - do - while (hacer - mientras)

    - for (para)

    BUCLE WHILE (Mientras)Su formato general es:

    while(condicin)

    sentencia;

    1Una etiqueta es un nombre de identificador vlido seguido de dos puntos, sirve para sealar al

    compilador un punto del programa.

    Cap.2-11

  • Captulo 2: Sentencias de control en C Programacin en C

    Donde sentencia, puede ser una sentencia vaca, sentencia nica o unbloque de sentencias que se repetirn. La condicin puede ser cualquiercondicin vlida. El bucle itera MIENTRAS la condicin sea VERDAD. Cuandollega a falsa, el control del programa pasa a la lnea que sigue al bucle.

    Este ejemplo muestra una rutina de entrada desde teclado que simplementese repite hasta que se pulsa A:

    espera_de_carac(){

    char ch;ch = \0 ; /* inicializa ch */while(ch != A)

    ch = getch() ;}

    Primero, la rutina inicializa ch a nulo. Desde el momento que ch es unavariable local, su valor es desconocido cuando el ordenador ejecutaespera_de_carac(). El bucle while entonces comienza comprobando para ver sich no es igual a A. Debido a que la rutina inicializa ch a nulo antes demanejarla, la prueba es VERDAD y el bucle comienza. Cada vez que se pulsa unatecla, el programa intenta comprobar de nuevo. Despus de pulsar A, lacondicin llega a ser falsa cuando ch es igual a A.

    El bucle while comprueba la condicin en lo alto del bucle, lo quesignifica que el cdigo del mismo no se ejecuta siempre. En el ejemplo dado,esta es la razn que tiene ch para ser inicializada y evitar que contengaaccidentalmente A. Debido a que while realiza la prueba en lo alto, el whilees bueno para situaciones donde no se quiera ejecutar bucle.

    Cap.2-12

  • Captulo 2: Sentencias de control en C Programacin en C

    Otro ejemplo de while.

    /* traduce los caracteres a un formato codificadoaadiendo 1 a cada letra */

    #include #include

    main(){

    char ch ;

    printf("Introduzca su mensaje.\n") ;ch = getche() ;

    while (ch != \r){

    printf("%c", ch+1) ;ch = getch() ;

    }}

    BUCLE DO-WHILE (Hacer - mientras)Al contr