C+1f

107
Instituto Tecnológico de Ciudad Guzmán Apuntes Programación II Profesor: Ing. Ramón Chávez Bracamontes Academia: Ingeniería Electrónica Fecha: Enero de 2006

Transcript of C+1f

Page 1: C+1f

Instituto Tecnológico de Ciudad Guzmán

Apuntes

Programación II

Profesor: Ing. Ramón Chávez Bracamontes

Academia: Ingeniería Electrónica

Fecha: Enero de 2006

Page 2: C+1f

Programación II

Ingeniería Electrónica 2

Contenido

Contenido ...................................................................................................................................................... 2

Identificación del programa desarrollado por unidades de aprendizaje .................................................. 3

Ubicación de la asignatura ............................................................................................................................. 3

Objetivo general del curso.............................................................................................................................. 3

Temario ............................................................................................................................................................. 3

Bibliografía ........................................................................................................................................................ 3

UNIDAD I “INTRODUCCIÓN” ...................................................................................................................... 4

UNIDAD II “ESTRUCTURAS DE CONTROL Y FUNCIONES”................................................................ 16

UNIDAD III “ARREGLOS” ........................................................................................................................... 32

UNIDAD IV “APUNTADORES Y ESTRUCTURAS” ................................................................................. 42

UNIDAD V “ARCHIVOS” ............................................................................................................................ 53

UNIDAD VI “UTILIZACIÓN DE LIBRERIAS EXTERNAS”..................................................................... 64

Page 3: C+1f

Programación II

Ingeniería Electrónica 3

Identificación del programa desarrollado por unidades de aprendizajeNombre de la asignatura: Programación II (4-2-10)Nivel: LicenciaturaCarrera: Ingeniería electrónicaClave: ECC-9342

Ubicación de la asignaturaa) Relación con otras asignaturas del plan de estudio

Anteriores: ProgramaciónPosteriores: Métodos numéricos, microprocesadores, comunicaciones, optativas

b) Aportación de la asignatura al perfil del egresadoComo auxiliar en la investigación y como herramienta del trabajo profesional al utilizar unlenguaje de alto nivel.

Objetivo general del cursoConocer y aplicar las técnicas de programación, utilizando un lenguaje de alto nivel para el uso dela computadora como elemento de comunicación con el mundo real.

TemarioNúmero Tema SubtemasI Introducción Compilación y encadenamiento

Variables y constantesTipos de datosOperadores y expresionesEntradas y salidas por consola

II Estructuras de control yFunciones

Sentencias de controlFunciones

III Arreglos Arrays y cadenas (unidimensionales,bidimensionales)Funciones de caracteres y cadenas

IV Apuntadores y estructuras EstructurasUnionesEnumeracionesPunteros

V Archivos Archivos (Ficheros)Abrir ficherosCierre ficheroEscritura de caracteres y cadenasLectura de caracteres y cadenasPosición en secuenciales y binariosEscritura y lectura en binarios

Vi Utilización de librerías externas Funciones matemáticasFunciones de conversiónFunciones de fecha y horaFunciones de sistemaFunciones gráficasFunciones de comunicaciónProyectos

BibliografíaTurbo C, Programming for the PC, Howard W. SamsEl lenguaje de programación “C”, Kernigham, Prentice HallProgramación en Turbo C, Schilt

Page 4: C+1f

Programación II

Ingeniería Electrónica 4

UNIDAD I “INTRODUCCIÓN”Objetivo educacional:Conocer los fundamentos del lenguaje de programación “C” y poder generar un programa ejecutable sencillo.

C está caracterizado por ser de uso general, de sintaxis sumamente compacta y de altaportabilidad. Es un lenguaje de nivel medio porque combina elementos de lenguajes de alto nivel,manipulación de bits, bytes, direcciones y elementos básicos como números y caracteres.

La portabiblidad significa que es posible adaptar el software escrito para un tipo decomputadora o sistema operativo en otro. C no lleva a cabo comprobaciones de errores en tiempode ejecución, es el programador el único responsable de llevar a cabo esas comprobaciones

Se trata de un lenguaje estructurado, que es la capacidad de un lenguaje de seccionar yesconder del resto del programa toda la información y las instrucciones necesarias para llevar acabo un determinada tarea. Un lenguaje estructurado permite colocar las sentencias en cualquierparte de una línea. Todos los lenguajes modernos tiende a ser estructurados.

El componente estructural principal de C es la función, subrutina independiente que permitendefinir tareas de un programa y codificarlas por separado haciendo que los programas seanmodulares. Otra forma de estructuración es el bloque de código que es un grupo de sentenciasconectadas de forma lógica que es tratado como una unidad.

El compilador de C lee el programa entero y lo convierte a código objeto o código máquina.Una vez compilado, las líneas de código fuente dejan de tener sentido durante la ejecución. Estecódigo maquina puede ser directamente ejecutado por la computadora. El compilador de Cincorpora una biblioteca estándar que proporciona las funciones necesarias para llevar a cabo lastareas más usuales. En C se puede partir un programa en muchos archivos y que cada uno seacompilado por separado.

En la compilación de un programa consiste en tres pasos. Creación del código fuente,Compilación del programa y Enlace del programa con las funciones necesarias de la biblioteca. Laforma en que se lleve a cabo el enlace variará entre distintos compiladores y entornos, pero la formageneral es:

Page 5: C+1f

Programación II

Ingeniería Electrónica 5

1. PRIMER PROGRAMA

La mejor forma de aprender a programar en cualquier lenguaje es editar, compilar, corregir yejecutar pequeños programas descriptivos. Todos los programas en C consisten en una o másfunciones, la única función que debe estar presente es la denominada main(), siendo la primerafunción que se invoca cuando comienza la ejecución del programa.

Forma general de un programa en C:

#Archivos de cabecera#Archivos de cabeceraDeclaraciones globales

tipo_devuelto main(lista de parámetros){

secuencia de sentencias;}

tipo_devuelto funcion1(lista de parámetros){

secuencia de sentencias;}

tipo_devuelto funcion2(lista de parámetros){

secuencia de sentencias;}

.

.

.

tipo_devuelto funcionN(lista de parámetros){

secuencia de sentencias;}

Page 6: C+1f

Programación II

Ingeniería Electrónica 6

PROGRAMA “1A”

Descripción: Este programa captura un nombre y lo imprime 5 veces en la pantalla.

#include <stdio.h>#include <conio.h>void main(void){

clrscr();printf(“Bienvenidos”);getch ();

}

Vamos a ir comentando cada una de las líneas (sentencias) que aparecen en este programa. Laprimera línea que aparece se denomina ENCABEZAMIENTO y son ficheros que proporcionaninformación al compilador. En este archivo están incluidas las funciones llamadas por el programa.La ubicación de estos ficheros es el directorio C:\TC\INCLUDE\.

La segunda línea del programa indica donde comienza la función main indicando los valoresque recibe y los que devuelve. La primera línea de la función main (clrscr();) limpia lapantalla. y la segunda muestra un mensaje en la pantalla.

2. VARIABLES Y CONSTANTES

Unidad básica de almacenamiento, la creación es la combinación de un identificador, un tipo yun ámbito. Todas las variables en C tienen que ser declaradas antes de ser usadas. El lugar donde sedeclaran las variables puede ser dentro o en la definición de una función, fuera de todas lasfunciones.

TIPOS RANGO TAMAÑO DESCRIPCIÓN

char -128 a 127 1 Para una letra o un dígito.

unsigned char 0 a 255 1 Letra o número positivo.

int -32.768 a 32.767 2 Para números enteros.

unsigned int 0 a 65.535 2 Para números enteros.

long int ±2.147.483.647 4 Para números enteros

unsigned long int 0 a 4.294.967.295 4 Para números enteros

float 3.4E-38 a 3.4E+38decimales(7) 4 Para números con decimales

double 1.7E-308 a 1.7E+308decimales(15) 8 Para números con decimales

long double 3.4E-4932 a 1.1E4932decimales(19) 10 Para números con decimales

Page 7: C+1f

Programación II

Ingeniería Electrónica 7

El nombre de las variables conocido como identificadores debe cumplir las siguientes normas.La longitud puede ir de un carácter a 31. El primero de ellos debe ser siempre una letra. No puedecontener espacios en blanco, ni acentos y caracteres gramaticales. Hay que tener en cuenta que elcompilador distingue entre mayúsculas y minúsculas.

SINTAXIS:

tipo nombre=valor_numerico;

tipo nombre=’letra’;tipo nombre[tamaño]=”cadena de letras”,tipo nombre=valor_entero.valor_decimal;

CONVERSION (casting): Las conversiones automáticas pueden ser controladas por elprogramador. Bastará con anteponer y encerrar entre parentesis, el tipo al que se desea convertir.Este tipo de conversiones solo es temporal y la variable a convertir mantiene su valor.

SINTAXIS:

variable_destino=(tipo)variable_a_convertir;

variable_destino=(tipo)(variable1+variable2+variableN);

PROGRAMA “1B”

Descripción: Convierte un par de números flotantes a enteros y realiza la suma de los mismospresentando el resultado.

#include<stdio.h>#include<conio.h>

void main(void){

float num1=25.75, num2=10.15;int T;

clrscr();T=(int)num1+(int)num2;// T=(int)(num1+num2);printf(“Total: %d”,T);getch();

}

Page 8: C+1f

Programación II

Ingeniería Electrónica 8

AMBITO DE VARIABLE: Según el lugar donde se declaren las variables tendrán un ámbito.Según el ámbito de las variables pueden ser utilizadas desde cualquier parte del programa oúnicamente en la función donde han sido declaradas. Las variables pueden ser:

LOCALES: Cuando se declaran dentro de una función. Las variables locales sólo pueden serreferenciadas (utilizadas) por sentencias que estén dentro de la función que han sido declaradas. Noson conocidas fuera de su función. Pierden su valor cuando se sale y se entra en la función. Ladeclaración es como siempre.

GLOBALES: Son conocidas a lo largo de todo el programa, y se pueden usar desde cualquierparte del código. Mantienen sus valores durante toda la ejecución. Deban ser declaradas fuera detodas las funciones incluida main(). La sintaxis de creación no cambia nada con respecto a lasvariables locales. Inicialmente toman el valor 0 o nulo, según el tipo.

DE REGISTRO: Otra posibilidad es, que en vez de ser mantenidas en posiciones de memoriadel ordenador, se las guarde en registros internos del microprocesador. De esta manera el acceso aellas es más directo y rápido. Para indicar al compilador que es una variable de registro hay queañadir a la declaración la palabra register delante del tipo. Solo se puede utilizar paravariables locales.

ESTÁTICAS: Las variables locales nacen y mueren con cada llamada y finalización de unafunción, sería útil que mantuvieran su valor entre una llamada y otra sin por ello perder su ámbito.Para conseguir eso se añade a una variable local la palabra static delante del tipo.

EXTERNAS: Debido a que en C es normal la compilación por separado de pequeños módulosque componen un programa completo, puede darse el caso que se deba utilizar una variable globalque se conozca en los módulos que nos interese sin perder su valor. Añadiendo delante del tipo lapalabra extern y definiéndola en los otros módulos como global ya tendremos nuestra variableglobal.

TIPOS DEFINIDOS POR EL USUARIO: C permite explícitamente nuevos nombres para tiposde datos. Realmente no se crea un nuevo tipo de dato, sino que se define un nuevo nombre para untipo existente. Esto ayuda a hacer más transportables los programas con dependencias con lasmáquinas, solo habrá que cambiar las sentencias typedef cuando se compile en un nuevo entorno.

SINTAXIS:

tydef tipo nuevo_nombre;

nuevo_nombre nombre_variable[=valor];

Page 9: C+1f

Programación II

Ingeniería Electrónica 9

PROGRAMA “1C”

Descripción: programa que muestra un ejemplo de los diferentes tipos de variables que existen.

#include <stdio.h>#include <conio.h>void func1(void);int numero1=10;extern int numero2=25;void main(void){

int numero3=20;static int numero4=15;register int numero5=30;clrscr();printf(“\n %d, \n %d, \n %d, \n %d, \n %d,”, numero1,

numero2,numero3,numero4,numero5);func1();getch();

}

void func1(void){

printf(“Las globales, que aquí se conocen”);printf(“\n %d, \n %d”, numero1, numero2);

}

LAS CONSTANTES: Se refieren a los valores fijos que no pueden ser modificados por elprograma. Pueden ser de cualquier tipo de datos básicos. Las constantes de carácter van encerradasen comillas simples. Las constantes enteras se especifican con números sin parte decimal y las decoma flotante con su parte entera separada por un punto de su parte decimal.

SINTAXIS:

const tipo nombre=valor_entero;

const tipo nombre=valor_entero.valor_decimal;

const tipo nombre=’carácter’;

La directiva #define es un identificador y una secuencia de caracteres que sustituirá sesustituirá cada vez que se encuentre éste en el archivo fuente. También pueden ser utilizados paradefinir valores numéricos constantes.

SINTAXIS:

#define IDENTIFICADOR valor_numerico

#define IDENTIFICADOR “cadena”

Page 10: C+1f

Programación II

Ingeniería Electrónica 10

PROGRAMA “1D”

Descripción: Este programa desarrolla el perímetro de una circunferencia utilizando un “define”para introducir un dato como constante.

#include <stdio.h>#include <conio.h>#define pi 3.1416float r, p;

void main(void){

clrscr();printf("Este programa encuentra el perímetro de una

circunferencia");printf("\n \n Introduzca el radio");scanf ("%f", &r);p=2*r*pi;printf(“El perímetro es: %f”, p);getch();

}

PROGRAMA “1E”

Descripción: Este programa es un ejemplo de los “define” y “const” para introducir datosconstantes al programa.

#include <stdio.h>#include <conio.h>#define DOLAR 11.53#define TEXTO "Esto es una prueba"#define clr clrscr#define pr printf#define get getchconst int peso=1;void main(void){

clr();pr("El valor del dolar es %.2f pesos",DOLAR);pr("\n%s",TEXTO);pr(“Ejemplo de constantes y defines”);get();

}

3. OPERADORES

C es un lenguaje muy rico en operadores incorporados, es decir, implementados alrealizarse el compilador. Define cuatro tipos de operadores: aritméticos, relacionales, lógicos y anivel de bits. También se definen operadores para realizar determinadas tareas, como lasasignaciones.

ASIGNACION (=): En C se puede utilizar el operador de asignación en cualquierexpresión valida. Solo con utilizar un signo de igualdad se realiza la asignación. El operador destino(parte izquierda) debe ser siempre una variable, mientras que en la parte derecha puede ser

Page 11: C+1f

Programación II

Ingeniería Electrónica 11

cualquier expresión valida. Es posible realizar asignaciones múltiples, igualar variables entre si y aun valor.

SINTAXIS:

variable=valor;

variable=variable1;

variable=variable1=variable2=variableN=valor;

ARITMÉTICOS: Pueden aplicarse a todo tipo de expresiones. Son utilizados para realizaroperaciones matemáticas sencillas, aunque uniéndolos se puede realizar cualquier tipo deoperaciones. En la siguiente tabla se muestran todos los operadores aritméticos.

OPERADOR DESCRIPCIÓN ORDEN

- Resta. 3

+ Suma 3

* Multiplica 2

/ Divide 2

% Resto de una división 2

- signo (monario). 2

-- Decremento en 1. 1

++ Incrementa en 1. 1

LÓGICOS Y RELACIONALES: Los operadores relacionales hacen referencia a larelación entre unos valores y otros Los lógicos se refiere a la forma en que esas relaciones puedenconectarse entre si. Los veremos a la par por la estrecha relación en la que trabajan.

OPERADORES RELACIONALES OPERADORES LÓGICOS

OPERADOR DESCRIPCIÓN ORDEN OPERADOR DESCRIPCIÓN ORDEN

< Menor que. 5 && Y (AND) 10

> Mayor que. 5 | | O (OR) 11

<= Menor o igual. 5 ¡! NO (NOT) 1

>= Mayor o igual 5

= = Igual 6

¡! = Distinto 6

Page 12: C+1f

Programación II

Ingeniería Electrónica 12

A NIVEL DE BITS: Estos operadores son la herramienta más potente, pueden manipularinternamente las variables, es decir bit a bit. Este tipo de operadores solo se pueden aplicar a lasvariables de tipo char, short, int y long. Para manejar los bits debemos conocer perfectamente eltamaño de las variables.

OPERADOR DESCRIPCIÓN ORDEN

& Y (AND) bit a bit. 7

| O (OR) Inclusiva. 9

^ O (OR) Exclusiva. 8

<< Desplazamiento a la izquierda. 4

>> Desplazamiento a la derecha. 4

~ Intercambia 0 por 1 y viceversa. 1

PROGRAMA “1F”

Descripción: Este programa captura 2 variables, realiza una división y entrega como resultado elcociente y el residuo de la operación.

#include <stdio.h>#include <conio.h>void main(void){

clrscr ();int x, y;printf ("Introduzca el dividendo y el divisor:");scanf ("\n %d, %d”, &x, &y);printf ("\n Cociente: %d",x/y);printf (“\n Resto %d”, x%y);getch ();

}

4. E/S POR CONSOLA

La entrada y la salida se realizan a través de funciones de la biblioteca, que ofrece unmecanismo flexible a la vez que consistente para transferir datos entre dispositivos. Las funcionesprintf() y scanf() realizan la salida y entrada con formato que pueden ser controlados.Aparte hay una gran variedad de funciones E/S.

printf: escribe los datos en pantalla. Se puede indicar la posición donde mostrar mediante unafunción gotoxy(columna,fila) o mediante las constantes de carácter. La sintaxis general que seutiliza la función printf() depende de la operación a realizar.

printf(“mensaje [const_carácter]”);printf(“[const_carácter]”);printf(“ident(es)_formato[const_carácter]”,variable(s));

Page 13: C+1f

Programación II

Ingeniería Electrónica 13

En las siguientes tablas se muestran todos los identificadores de formato y las constantes decarácter las que se utilizan para realizar operaciones automáticamente sin que el usuario tenga queintervenir en esas operaciones.

IDENTIFICADORES DEFORMATO

CONSTANTES DE CARÁCTER

IDENTIFICADOR DESCRIPCION CONSTANTE DESCRIPCION

%c Carácter \n Salto de línea

%d Entero \f Salto de página

%e N. Científica \r Retorno de carro

%E N. Científica \t Tabulación

%f Coma flotante \b Retroceso

%o Octal \’ Comilla simple

%s Cadena \” Comillas

%u Sin signo \\ Barra invertida

%x Hexadecimal \? Interrogación

%X Hexadecimal \a Sonido de alerta

%p Puntero

%ld Entero Largo

%h Short

%% signo %

Existen especificadores de formato asociados a los identificadores que alteran su significadoligeramente. Se puede especificar la longitud mínima, el número de decimales y la alineación. Estosmodificadores se sitúan entre el signo de porcentaje y el identificador.

% modificador identificador

El especificador de longitud mínima hace que un dato se rellene con espacios en blanco paraasegurar que este alcanza una cierta longitud mínima. Si se quiere rellenar con ceros o espacios hayque añadir un cero delante antes del especificador de longitud.

printf(“%f ”,numero); //salida normal.

printf(“%10f ”,numero); //salida con 10 espacios.

printf(“%010f “,numero); //salida con los espacios poniendo 0.

Page 14: C+1f

Programación II

Ingeniería Electrónica 14

El especificador de precisión sigue al de longitud mínima (si existe). Consiste en un nulo y unvalor entero. Según el dato al que se aplica su función varia. Si se aplica a datos en coma flotantedetermina el número de posiciones decimales. Si es a una cadena determina la longitud máxima delcampo. Si se trata de un valor entero determina el número mínimo de dígitos.

printf(“%10.4f “,numero); //salida con 10 espacios con 4 decimales.

printf(“%10.15s”,cadena); //salida con 10 caracteres dejando 15 espacios.

printf(“%4.4d”,numero); //salida de 4 dígitos mínimo.

El especificador de ajuste fuerza la salida para que se ajuste a la izquierda, por defecto siemprelo muestra a la derecha. Se consigue añadiendo después del porcentaje un signo menos.

printf(“%8d”,numero); // salida ajustada a la derecha.

printf(“%-8d”,numero); //salida ajustada a la izquierda.

scanf: Es la rutina de entrada por consola. Puede leer todos los tipos de datos incorporados yconvierte los números automáticamente al formato incorporado. En caso de leer una cadena leehasta que encuentra un carácter de espacio en blanco. El formato general:

scanf(“identificador”,&variable_numerica o char);scanf(“identificador”,variable_cadena);

La función scanf() también utiliza modificadores de formato, uno especifica el númeromáximo de caracteres de entrada y eliminadores de entrada.. Para especificar el número máximosolo hay que poner un entero después del signo de porcentaje. Si se desea eliminar entradas hay queañadir %*c en la posición donde se desee eliminar la entrada.

scanf(“%10s”,cadena);scanf(“%d%*c%d”,&x,&y);

En muchas ocasiones se combinaran varias funciones para pedir datos y eso puede traerproblemas para el buffer de teclado, es decir que asigne valores que no queramos a nuestrasvariables. Para evitar esto hay dos funciones que se utilizan para limpiar el buffer de teclado.

fflush(stdin);

fflushall();

Page 15: C+1f

Programación II

Ingeniería Electrónica 15

OTRAS FUNCIONES E/S: El archivo de cabecera de todas estas funciones es STDIO.H.Todas estas funciones van a ser utilizadas para leer caracteres o cadenas de caracteres. Todas ellastienen asociadas una función de salida por consola.

FUNCIONES DESCRIPCIÓN

var_char=getchar(); Lee un carácter de teclado, espera un salto de carro.

var_char=getche(); Lee un carácter con eco, no espera salto de carro.

var_char=getch(); Lee un carácter sin eco, no espera salto de carro.

gets(var_cadena); Lee una cadena del teclado.

putchar(var_char); Muestra un carácter en pantalla.

puts(variables); Muestra una cadena en pantalla.

Constantes enteras en tres bases diferentes

Base 10Decimal

Base 16Hexadecimal (Hex)

Base 8Octal

8 0x08 01010 0x0A 01216 0x10 02065536 0x10000 020000024 0x18 03017 0x11 021

Programas propuestos para la unidad 1

1. Programa que imprima en la pantalla los datos personales del alumno y el horariode las materias que cursa.

2. Programa que calcule las raices de una ecuación de segundo grado solicitando alusuario los parámetros de la ecuación Ax2+Bx+C=0.

3. Programa que lea desde el teclado el precio de un producto x y la cantidad, y comoresultado imprima en la pantalla el subtotal, el iva y el total.

4. Programa que lea 1as calificaciones de un grupo de 10 alumnos (0-100) e imprimael promedio del grupo.

5. Programa imprima en pantalla un menú de un restaurant “x” que incluya losprecios de los alimentos.

Page 16: C+1f

Programación II

Ingeniería Electrónica 16

UNIDAD II “ESTRUCTURAS DE CONTROL Y FUNCIONES”Objetivo educacional:Aplicar las estructuras del lenguaje a la resolución de problemas utilizando programación estructurada

5. SENTENCIAS DE CONTROL

Es la manera que tiene un lenguaje de programación de provocar que el flujo de la ejecuciónavance y se ramifique en función de los cambios de estado de los datos.

if-else: La ejecución atraviese un conjunto de estados bolean que determinan que se ejecutendistintos fragmentos de código.

if (expresion-booleana)Sentencia1;

elseSentencia2;

La cláusula else es opcional, la expresión puede ser de cualquier tipo y más de una (siempreque se unan mediante operadores lógicos).Otra opción posible es la utilización de if anidados, esdecir unos dentro de otros compartiendo la cláusula else.

Un operador muy relacionado con la sentencia if es ¿?. Es un operador ternario que puedesustituir al if. El modo de trabajo es el siguiente, evalúa la primera expresión y si es cierta toma elvalor de la segunda expresión y se le pasa a la variable. Si es falsa, toma el valor de la tercera y lapasa a la variable

varible=condicion ¿? expresion2:expresion3;

PROGRAMA #2A

Descripción: Programa que calcula el número de días vividos.

#include <stdio.h>#include <conio.h>void main(){

char nombre[50];int edad;clrscr();printf("¿Cómo te llamas?\n ");scanf("%s",nombre);printf("¿Cuántos años tienes?\n");scanf("%i",&edad);edad=edad*365;gotoxy(5,10);printf("%s, has vivido %i dias",nombre,edad);gotoxy(40,22);printf("Pulsa cualquier tecla para terminar...");getch();

}

if (expresion-booleana){

Sentencia1;sentencia2;

}else

Sentencia3;

Page 17: C+1f

Programación II

Ingeniería Electrónica 17

PROGRAMA #2B

Descripción: Este programa es un ejemplo de la utilización del IF y ELSE. Decide si el pesointroducido es menor o mayor de media tonelada.

#include <stdio.h>#include <conio.h>void main(void){

int peso;clrscr();gotoxy(5,3);printf(“Introducir peso: “);gotoxy(22,3);scanf(“%d”,&peso);

if(peso<500){gotoxy(5,5);printf(“No es ni media Tn”);}

else{gotoxy(5,5);pritnf(“Es más de media Tn”);}

getch();}

Para probar la utilización de un if anidado realizar un programa que pida una edad. Si la edades igual o menor a 10 poner el mensaje NIÑO, si la edad es mayor a 65 poner el mensajeJUBILADO, y si la edad es mayor a 10 y menor o igual 65 poner el mensaje ADULTO.

SWITCH: Realiza distintas operaciones en base al valor de una única variable o expresión. Esuna sentencia muy similar a if-else, pero esta es mucho más cómoda y fácil de comprender. Si losvalores con los que se compara son números se pone directamente el pero si es un carácter se debeencerrar entre comillas simples.

switch (expresión){case valor1:

sentencia;break;

case valor2:sentencia;break;

case valor3:sentencia;break;

case valorN:sentencia;break;

default:}

Page 18: C+1f

Programación II

Ingeniería Electrónica 18

El valor de la expresión se compara con cada uno de los literales de la sentencia case sicoincide alguno se ejecuta el código que le sigue, si ninguno coincide se realiza la sentenciadefault (opcional), si no hay sentencia default no se ejecuta nada.

La sentencia break realiza la salida de un bloque de código. En el caso de sentenciaswitch realiza el código y cuando ejecuta break sale de este bloque y sigue con la ejecucióndel programa. En el caso que varias sentencias case realicen la misma ejecución se pueden agrupar,utilizando una sola sentencia break.

switch (expresión){case valor1:case valor2:case valor5:

sentencia;break;

case valor4:sentencia;break;

default:}

PROGRAMA #2CDescripción: Este programa es un ejemplo del SWITCH en la utilización para menús

#include <stdio.h>#include <conio.h>void main(void){

int opcion;clrscr();pritnf(“1.ALTAS\n”);pritnf(“2.BAJAS\n”);pritnf(“3.MODIFICA\n”);pritnf(“4.SALIR\n”);pritnf(“Elegir opción: “);scanf(“%d”,&opcion);switch(opcion){

case 1:printf(“Opción Uno”);break;

case 2:printf(“Opción Dos”);break;

case 3:printf(“Opción Tres”);break;

case 4:printf(“Opción Salir”);break;

default:printf(“Opción incorrecta”);

}getch();

}

Page 19: C+1f

Programación II

Ingeniería Electrónica 19

WHILE: Ejecuta repetidamente el mismo bloque de código hasta que se cumpla una condiciónde terminación. Hay cuatro partes en cualquier bucle. Inicialización, cuerpo, iteración yterminación.

[inicialización;]while(terminación){

cuerpo;[iteración;]

}

DO-WHILE: Es lo mismo que en el caso anterior pero aquí como mínimo siempre seejecutara el cuerpo una vez, en el caso anterior es posible que no se ejecute ni una sola vez.

[inicialización;]do{

cuerpo;[iteración;]

}while(terminación);

PROGRAMA #2D

Descripción: Este programa obtiene el número de fibonacci haciendo uso de un cliclo do-while.

#include <stdio.h>#include <conio.h>void main(void){ int n1=0,n2=1,n3; printf("Numero de Fibonacci: %d %d\n",n1,n2); do{ n3=n1+n2; n1=n2+n3; n2=n1+n3; printf("%d %d %d\n",n3,n1,n2);

}while(n1<10000 && n2<10000 && n3<10000);}

FOR: Realiza las mismas operaciones que en los casos anteriores pero la sintaxis es una formacompacta. Normalmente la condición para terminar es de tipo numérico. La iteración puede sercualquier expresión matemática valida. Si de los 3 términos que necesita no se pone ninguno seconvierte en un bucle infinito.

for (inicio;fin;iteración)sentencia1;

for (inicio;fin;iteración){

sentencia1;sentencia2;

}

Page 20: C+1f

Programación II

Ingeniería Electrónica 20

PROGRAMA #2E

Descripción: Este programa muestra números del 1 al 100. Utilizando un bucle de tipo FOR.

#include<stdio.h>#include<conio.h>

void main(void){

int n1=0;for (n1=1;n1<=100;n1++)

printf("%d\n",n1);getch();

}

La sentencia continue lo que hace es ignorar las sentencias que tiene el bucle y saltardirectamente a la condición para ver si sigue siendo verdadera, si es así sigue dentro del bucle, encaso contrario saldría directamente de el.

La sentencia exit() tiene una operatoria más drástica, que la sentencia break, en vez desaltear una iteración, esta abandona directamente el programa dándolo por terminado. Aparte realizaoperaciones útiles como cerrar cualquier archivo que estuviera abierto, vaciado de buffers. Se sueleutilizar cuando se desea abandonar programas cuando se produce algún error fatal e inevitable.

Otra función relacionada con los bucles es kbhit(), lo que hace esta función es la detectarel momento en que se pulsa una tecla (cualquiera). Devuelve 0 cuando no se ha pulsado ningunatecla, cuando se pulsa una tecla devuelve cualquier valor distinto de 0.

PROGRAMA #2F

Descripción: Muestra números hasta que se pulsa una tecla.

#include <stdio.h>#include <conio.h>

void main(void){

long num=0;clrscr();

for( ; ; ){

num++;printf(“%ld\n”,num);if(kbhit())

exit();}getch();

}

Page 21: C+1f

Programación II

Ingeniería Electrónica 21

PROGRAMA #2G

Descripción: Este programa es un ejemplo de if anidados. También es otro ejemplo de cómo hacerun menú.

#include <stdio.h>#include <conio.h>void main(void) { char opcion;

clrscr(); printf("A) Electronica I\n"); printf("B) Electronica II\n"); printf("C) Electronica III\n"); printf("Opción ");scanf("%c",&opcion);

printf("Escogio: "); if(opcion=='A')

printf("Electronica I"); else if(opcion=='B')

printf("Electronica II"); else if(opcion=='C')

printf("Electronica III"); else printf("Asignatura Inexistente"); getch(); }

PROGRAMA #2H

Descripción: Este programa captura x número de años y entrega como resultado el promedio detodos.

#include <stdio.h>#include <conio.h>void main(void) { int alumnos,edad,counter=1; float promedio,sumaedad=0; clrscr(); printf("\nNumero de Alumnos: "); scanf("%d",&alumnos); while(1) { printf("\nEdad alumno %d:",counter); scanf("%d",&edad); sumaedad=sumaedad+edad;

if(counter==alumnos) break;

counter++;}

promedio=sumaedad/counter; printf("\nLa edad promedio de %d alumnos es %lf

años",counter,promedio);getch();

}

Page 22: C+1f

Programación II

Ingeniería Electrónica 22

6. FUNCIONES

Las funciones son los bloques constructores de C, es el lugar donde se produce toda laactividad del programa. Es la característica más importante de C. Subdivide en varias tareasconcurrentes el programa, así sólo se las tendrá que ver con diminutas piezas de programa, de pocaslíneas, cuya escritura y corrección es una tarea simple. Las funciones pueden o no devolver y recibirvalores del programa.

El mecanismo para trabajar con funciones es el siguiente, primero debemos declarar elprototipo de la función, a continuación debemos hacer la llamada y por último desarrollar lafunción. Los dos últimos pasos pueden cambiar, es decir, no es necesario que el desarrollo de lafunción este debajo de la llamada.

Antes de seguir debemos conocer las reglas de ámbito de las funciones. El código de unafunción es privado a esa función, el código que comprende el cuerpo de esa función está oculto alresto del programa a menos que se haga a través de una llamada. Todas las variables que se definendentro de una función son locales con la excepción de las variables estáticas.

SINTAXIS DEL PROTOTIPO:

tipo_devuelto nombre_funcion ([parametros]);

SINTAXIS DE LA LLAMADA:

nombre_funcion([parametros]);

SINTAXIS DEL DESARROLLO:

tipo_devuelto nombre_funcion ([parametros]){

cuerpo;}

Cuando se declaran las funciones es necesario informar al compilador los tamaños de losvalores que se le enviarán y el tamaño del valor que retorna. En el caso de no indicar nada para elvalor devuelto toma por defecto el valor int.

Al llamar a una función se puede hacer la llamada por valor o por referencia. En el caso dehacerla por valor se copia el contenido del argumento al parámetro de la función, es decir si seproducen cambios en el parámetro no afecta a los argumentos. C utiliza esta llamada por defecto.Cuando se utiliza la llamada por referencia lo que se pasa a la función es la dirección de memoriadel argumento, por tanto si se producen cambios estos afectan también al argumento. La llamada auna función se puede hacer tantas veces como se quiera.

Page 23: C+1f

Programación II

Ingeniería Electrónica 23

PRIMER TIPO: Las funciones de este tipo ni devuelven valor ni se les pasa parámetros. Ente casohay que indicarle que el valor que devuelve es de tipo void y para indicar que no recibiráparámetros también utilizamos el tipo void. Cuando realizamos la llamada no hace falta indicarlenada, se abren y cierran los parentesis.

void nombre_funcion(void);

nombre_funcion();

PROGRAMA #2I

Descripción: Este programa indica cuando se esta en una función e imprime el contenido de esta.

#include <stdio.h>#include <conio.h>#include <dos.h>void mostrar(void);

void main(void){ clrscr(); printf("Estoy en la principal\n"); delay(2000);

mostrar(); printf("De vuelta en la principal"); getch();}

void mostrar(void){ printf("Ahora he pasado a la función\n"); delay(2000);}

Page 24: C+1f

Programación II

Ingeniería Electrónica 24

SEGUNDO TIPO: Son funciones que devuelven un valor una vez han terminado de realizar susoperaciones, solo se puede devolver uno. La devolución se realiza mediante la sentencia return,que además de devolver un valor hace que la ejecución del programa vuelva al código que llamo aesa función. Al compilador hay que indicarle el tipo de valor que se va a devolver poniendo delantedel nombre de la función el tipo a devolver. En este tipo de casos la función es como si fuera unavariable, pues toda ella equivale al valor que devuelve.

tipo_devuelto nombre_funcion(void);variable=nombre_funcion();

PROGRAMA #2J

Descripción: Este programa realiza una suma de 2 números por medio de funciones y regresa elresultado a la función principal para imprimirlo.

#include<stdio.h>#include<conio.h>#include<dos.h>

int suma(void);void main(void){

int total;clrscr();printf(“Suma valores\n”);total=suma();pritnf(“\n%d”,total);getch();

}int suma(void){

int a,b,total_dev;printf(“valores: “);scanf(“%d%*c%d”,&a,&b);total_dev=a+b;return total_dev;

}

#include<stdio.h>#include<conio.h>#include<dos.h>

int suma(void);void main(void){

clrscr();printf(“Suma valores\n”);pritnf(“\n %d”,suma());getch();

}

int suma(void){

int a,b;printf(“valores: “);scanf(“%d%*c%d”,&a,&b);return a+b;

}

Page 25: C+1f

Programación II

Ingeniería Electrónica 25

TERCER TIPO: En este tipo las funciones pueden o no devolver valores pero lo importante es quelas funciones pueden recibir valores. Hay que indicar al compilador cuantos valores recibe y de quetipo es cada uno de ellos. Se le indica poniéndolo en los parentesis que tienen las funciones. Debenser los mismos que en el prototipo.

void nombre_funcion(tipo1,tipo2…tipoN);nombre_funcion(var1,var2…varN);

PROGRAMA #2K

Descripción: Este programa captura dos datos y una cadena. Con los datos se realiza una suma y seimprime el resultado y la cadena capturada.

#include <stdio.h>#include <conio.h>void resta(int x,int y,char *cad);

void main(void){ int a,b; char cadena[20]; clrscr(); printf("Resta de valores\n"); printf("Introducir valores y cadena: "); scanf("%d%*c%d",&a,&b); gets(cadena); resta(a,b,cadena); getch();}void resta(int x,int y,char *cad){ printf("Total= %d",x+y); printf("La cadena es: %s",cad);}

PASO DE ESTRUCTURAS A FUNCIONES: Cuando se utiliza o se pasa una estructura comoargumento a una función, se le pasa toda la estructura integra, se le pasa por valor. Esto significaque todos los cambios realizados en el interior de la función no afectan a la estructura utilizadacomo argumento. La única diferencia con los casos anteriores es que, ahora hay que definir comoparámetro de la función una estructura.

SINTAXIS:tipo_devuelto nombre_funcion(struc nombre etiqueta);

nombre_funcion(etiqueta_estructura);

Page 26: C+1f

Programación II

Ingeniería Electrónica 26

PROGRAMA #2L

Descripción: Este programa captura el número de calificaciones y dice cuantas son reprobatorias.

#include <stdio.h>#include <conio.h>int numreprob(int not);

void main(void){ int notas, reprobados;

clrscr(); printf("\nNúmero de notas a leer: "); scanf("%d",&notas); reprobados=numreprob(notas); printf("\nExiste un total de %d alumno(s) reprobado(s)",reprobados);

getch();}

int numreprob(int not){ int c=1,calif,rep=0; while(c<=not) { printf("\nCalificacion de la nota %d: ",c); scanf("%d",&calif); if(calif<7) rep++; c++; } return (rep);}

Page 27: C+1f

Programación II

Ingeniería Electrónica 27

PROGRAMA #2MDescripción: Este programa captura la matricula y la calificación de cualquier numero de alumnose imprime las matriculas y su calificación, esto ocurre asta que se introduce un cero a la matricula.

#include <stdio.h>#include <conio.h>#include <dos.h>void despliega(int *mats,char *califs,int numcap);int leedato(int *mats,char *califs,int maximo);void main(void){ int max=30,matr[29],numalumn; char calif[29]; clrscr();

numalumn=leedato(matr,calif,max); printf("\nEl numero de alumnos capturados es %d",numalumn);

despliega(matr,calif,numalumn);}int leedato(int *mats,char *califs,int maximo){ int n=0; printf("\n ***Introduce la matricula y su calificación. ***"); printf("\n ***Para terminar dale un cero a la matricula. ***"); while(1)

{if(n>=maximo){

printf("\nEl arreglo se encuentra lleno");getch();break;

}printf("\n\nMatricula del alumno %d: ",n+1);scanf("%d",mats);if(*mats==0)break;printf("\nCalificación del alumno %d: ",n+1);scanf("%d",califs);mats++;califs++;n++;

} return n;}void despliega(int *mats,char *califs,int numcap){ int i=1; while(1){ if(i>numcap)

break; printf("\nLa calificación del alumno %d es %d",*mats,*califs); i++; mats++; califs++; } getch();}

Page 28: C+1f

Programación II

Ingeniería Electrónica 28

PROGRAMA #2N

Descripción: Este programa muestra un menú donde se pide que tipo de operación básica desearealiza. Una vez colocando la opción, pide que introduzca dos datos (A y B), realiza la operación ymuestra el resultado.

#include <stdio.h>#include <conio.h>#include <ctype.h>void suma(void);void resta(void);void multi(void);void divi(void);void datos(int *a,int *b);char r;int opcion;float a,b;

void main(void){ do { clrscr(); gotoxy(30,4); printf("OPERACIONES BASICAS"); gotoxy(20,10);printf("1.- SUMA"); gotoxy(20,12);printf("2.- RESTA"); gotoxy(20,14);printf("3.- MULTIPLICACION"); gotoxy(20,16);printf("4.- DIVISION"); gotoxy(50,20);printf("Opci¢n deseada: ");

scanf("%d",&opcion);

switch(opcion) {

case 1: suma(); break; case 2: resta(); break; case 3: multi(); break; case 4: divi(); break; default: gotoxy(50,22);printf("Opcion no valida");

}

gotoxy(20,24); printf("<< Desea realizar otra operaci¢n [S/N] >>"); r=tolower(getch()); } while(r=='s');}

Page 29: C+1f

Programación II

Ingeniería Electrónica 29

void suma(void){ clrscr(); gotoxy(38,4); printf("SUMA"); gotoxy(20,8);printf("Valor de A: "); scanf("%f",&a); gotoxy(20,10);printf("Valor de B: "); scanf("%f",&b); gotoxy(20,14);printf("SUMA A + B= %.2f",a+b);}void resta(void){ clrscr(); gotoxy(37,4); printf("RESTA"); gotoxy(20,8);printf("Valor de A: "); scanf("%f",&a); gotoxy(20,10);printf("Valor de B: "); scanf("%f",&b); gotoxy(20,14);printf("RESTA A - B= %.2f",a-b);}void multi(void){ clrscr(); gotoxy(33,4); printf("MULTIPLICACIóN"); gotoxy(20,8);printf("Valor de A: "); scanf("%f",&a); gotoxy(20,10);printf("Valor de B: "); scanf("%f",&b); gotoxy(20,14);printf("SUMA A X B= %.2f",a*b);}void divi(void){ clrscr(); gotoxy(38,4); printf("DIVISIóN"); gotoxy(20,8);printf("Valor de A: "); scanf("%f",&a); gotoxy(20,10);printf("Valor de B: "); scanf("%f",&b); gotoxy(20,14);printf("SUMA A / B= %.2f",a/b);}

PASO Y DEVOLUCION DE PUNTEROS: Cuando se pasan punteros como parámetros se estahaciendo una llamada por referencia, los valores de los argumentos cambian si los parámetros de lafunción cambian. La manera de pasar punteros es igual que cuando se pasan variables, sólo queahora hay que preceder al nombre del parámetro con un asterisco.

valor_devuelto nombre_funcion(*param1,*param2,…*paramN);nombre_funcion(var1,var2,…varN);

Para devolver un puntero, una función debe ser declarada como si tuviera un tipo puntero devuelta, si no hay coincidencia en el tipo de vuelta la función devuelve un puntero nulo. En elprototipo de la función antes del nombre de esta hay que poner un asterisco y en la llamada hay que

Page 30: C+1f

Programación II

Ingeniería Electrónica 30

igualar la función a un puntero del mismo tipo que el valor que devuelve. El valor que se retornadebe ser también un puntero.

PROTOTIPO:

valor_devuelto *nombre(lista_parametros);

LLAMADA:

puntero=nombre_funcion(lista_parametros);

DESARROLLO:

valor_devuelto *nombre_funcion(lista_parametros){

cuerpo;return puntero;

}

PROGRAMA #2O

Descripción: Busca la letra que se le pasa en la cadena y si la encuentra muestra la cadena a partirde esa letra.

#include <stdio.h>#include <conio.h>void *encuentra(char letra, char *cadena);

void main(void){

char frase[80], *p, letra_busca;clrscr();

printf("Introducir cadena: ");gets(frase);fflush(stdin);printf("Letra a buscar: ");letra_busca=getchar();p=encuentra(letra_busca,frase);if(p)printf("\n %s",p);

getch();}

void *encuentra(char letra, char *cadena){

while(letra!=*cadena && *cadena)cadena++;

return cadena;}

Page 31: C+1f

Programación II

Ingeniería Electrónica 31

LA FUNCIÓN MAIN: Método para pasar información a la función main mediante el uso deargumentos, el lugar desde donde se pasan esos valores es la línea de ordenes del sistema operativo.Se colocan detrás del nombre del programa.

Hay dos argumentos especiales ya incorporados, argc y argv que se utilizan para recibiresa información. En argc contiene el número de argumentos de la línea de ordenes y es un entero.Siempre vale como mínimo 1, ya que el nombre del programa cuenta como primer argumento. Elcaso de argv es un puntero a un array de punteros de caracteres donde se irán guardando todos losargumentos. Todos ellos son cadenas.

Si la función main espera argumentos y no se le pasa ninguno desde la línea de ordenes, esmuy posible que de un error de ejecución cuando se intenten utilizar esos argumentos. Por tanto lomejor es siempre controlar que el número de argumentos es correcto.

Otro aspecto a tener en cuenta es que el nombre de los dos argumentos (argc y argv) sontradicionales pero arbitrarios, es decir que se les puede dar el nombre que a nosotros nos interese,manteniendo eso si el tipo y el número de argumentos que recibe.

SINTAXIS:

void main(int argc, char *argv[]){

cuerpo;}

PROGRAMA #2P

Descripción: Este programa requiere ejecutarse en la línea de comandos del DOS: escribir elnombre del programa y otros dos parámetros numéricos.

#include <stdio.h>#include <conio.h>

void main(int argc, char *argv[]){

clrscr();

if(argc!=3) //controlo el nº de argumentos{

printf("Error en nº de argumentos");exit(0);

}

printf("Suma de valores\n");printf("Total= %d",atoi(argv[1])+atoi(argv[2]));getch();

}

Page 32: C+1f

Programación II

Ingeniería Electrónica 32

RECURSIVIDAD: Es el proceso de definir algo en términos de si mismo, es decir que lasfunciones pueden llamarse a si mismas, esto se consigue cuando en el cuerpo de la función hay unallamada a la propia función, se dice que es recursiva. Una función recursiva no hace una nuevacopia de la función, solo son nuevos los argumentos.

La principal ventaja de las funciones recursivas es que se pueden usar para crear versiones dealgoritmos más claras y sencillas. Cuando se escriben funciones recursivas, se debe tener unasentencia if para forzar a la función a volver sin que se ejecute la llamada recursiva.

EJEMPLO:

int fact(int numero){

int resp;

if(numero==1)return 1;

resp=fact(numero-1)*numero;return(resp);

}

Programas propuestos para la unidad 2

1. Programa que pida 3 numeros enteros y en base a ellos indicar cual es el mayor ycual es el menor.

2. Programa que lee un número entero positivo y como resultado tendra que indicar sies un número primo.

3. Programa que crea un cuadro de ciertas medidas mediante el uso de una funcióndefinida por el usuario.

4. Programa que convierta de grados Fahrenheit a Centigrados o viceversa

Page 33: C+1f

Programación II

Ingeniería Electrónica 33

UNIDAD III “ARREGLOS”Objetivo educacional:El alumno aplicará el concepto de arreglos en la manipulación de datos.

7. ARRAYS Y CADENAS

Un array es una colección de variables del mismo tipo que se referencian por un nombre encomún. A un elemento especifico de un array se accede mediante un índice. Todos los array constande posiciones de memoria contiguas. La dirección mas baja corresponde al primer elemento. Losarrays pueden tener de una a varias dimensiones.UNIDIMENSIONALES

El array más común en C es la cadena (array de caracteres terminado por un nulo). Todos losarray tienen el 0 como primer elemento. Hay que tener muy presente el no rebasar el último índice.La cantidad de memoria requerida para guardar un array está directamente relacionada con su tipo ysu tamaño.

SINTAXIS:

tipo nombre_array [nº elementos];

tipo nombre_array [nº elementos]={valor1,valor2,valorN};

tipo nombre_array[]={valor1,valor2,valorN};

INICIALIZACIÓN DE UN ELEMENTO:

nombre_array[indice]=valor;

UTILIZACIÓN DE ELEMENTOS:

nombre_array[indice];

PROGRAMA #3A

Descripción: Reserva 100 elementos enteros, los inicializa todos y muestra el 5º elemento.

#include <conio.h>#include <stdio.h>void main(void){ int x[100]; int cont; clrscr(); for(cont=0;cont<100;cont++)

x[cont]=cont;

printf("%d",x[4]); getch();}

Page 34: C+1f

Programación II

Ingeniería Electrónica 34

El uso más común de los arrays unidimensionales es con mucho las cadenas, conjunto decaracteres terminados por el carácter nulo (‘\0’). Por tanto cuando se quiera declarar una arrays decaracteres se pondrá siempre una posición más. No es necesario añadir explícitamente el carácternulo el compilador lo hace automáticamente.

SINTAXIS:

char nombre[tamaño];

char nombre[tamaño]=”cadena“;char nombre[]=”cadena”;

BIDIMENSIONALES:

C admite arrays multidimensionales, la forma más sencilla son los arrays bidimensionales. Unarray bidimensional es esencialmente un array de arrays unidimensionales. Los arraybidimensionales se almacenan en matrices fila-columna, en las que el primer índice indica la fila yel segundo indica la columna. Esto significa que el índice más a la derecha cambia más rápido queel de más a la izquierda cuando accedemos a los elementos.

SINTAXIS:

tipo nombre_array[fila][columna];

tipo nomb_array[fil][col]={{v1,v2,vN},{v1,v2,vN},{vN}};

tipo nomb_array[][]={{v1,v2,vN},{v1,v2,vN},{vN}};

INICIALIZACIÓN DE UN ELEMENTO:

nombre_array[indice_fila][indice_columna]=valor;

UTILIZACIÓN DE UN ELEMENTO:

nombre_array[indice_fila][indice_columna];

Para conocer el tamaño que tiene un array bidimensional tenemos que multiplicar las filas porlas columnas por el número de bytes que ocupa en memoria el tipo del array. Es exactamente igualque con los array unidimensionales lo único que se añade son las columnas.

filas * columnas * bytes_del_tipo

Un uso muy común de los arrays bidimensionales es crear un array de cadenas. En este tipo dearray el número de filas representa el número de cadenas y las columnas representa la longitud decada una de esas cadenas.

Page 35: C+1f

Programación II

Ingeniería Electrónica 35

PROGRAMA #3B

Descripción: Introduce 10 cadenas y luego las muestra en pantalla en orden descendente de cómose capturaron.

#include <conio.h>#include <stdio.h>void main(void){ char texto[10][80]; int indice; clrscr(); for(indice=0;indice<10;indice++) {

printf("%2.2d:",indice+1);gets(texto[indice]);

} printf("pulsa tecla"); getch(); clrscr();

for(indice=9;indice>=0;indice--) printf("%s\n",texto[indice]); getch();}

8. FUNCIONES DE CARACTERES Y CADENAS

La biblioteca estándar de C tiene un rico y variado conjunto de funciones de manejo decaracteres y caracteres. En una implementación estándar, las funciones de cadena requieren elarchivo de cabecera STRING.H, que proporciona sus prototipos. Las funciones de caracteresutilizan CTYPE.H, como archivo de cabecera.

ISALPHA: Devuelve un entero. DISTINTO DE CERO si la variable es una letra del alfabeto, encaso contrario devuelve cero. Cabecera: <ctype.h>.

int isalpha(variable_char);ISDIGIT: Devuelve un entero. DISTINTO DE CERO si la variable es un número (0 a 9), en caso

contrario devuelve cero. Cabecera <ctype.h>.

int isdigit(variable_char);

ISGRAPH: Devuelve un entero. DISTINTO DE CERO si la variable es cualquier carácterimprimible distinto de un espacio, si es un espacio CERO. Cabecera <ctype.h>.

int isgraph(variable_char);

ISLOWER: Devuelve un entero. DISTINTO DE CERO si la variable esta en minúscula, en casocontrario devuelve cero. Cabecera <ctype.h>.

int islower(variable_char);

Page 36: C+1f

Programación II

Ingeniería Electrónica 36

ISPUNCT: Devuelve un entero. DISTINTO DE CERO si la variable es un carácter de puntuación,en caso contrario, devuelve cero. Cabecera <ctype.h>

int ispunct(variable_char);

ISUPPER: Devuelve un entero. DISTINTO DE CERO si la variable esta en mayúsculas, en casocontrario, devuelve cero. Cabecera <ctype.h>

int isupper(varible_char);MEMSET: Inicializa una región de memoria (buffer) con un valor determinado. Se utiliza

principalmente para inicializar cadenas con un valor determinado. Cabecera<string.h>.

memset (var_cadena,’carácter’,tamaño);

STRCAT: Concatena cadenas, es decir, añade la segunda cadena a la primera, la primera cadenano pierde su valor origina. Lo único que hay que tener en cuenta es que la longitud dela primera cadena debe tener la longitud suficiente para guardar la suma de las doscadenas. Cabecera <string.h>.

strcat(cadena1,cadena2);

STRCHR: Devuelve un puntero a la primera ocurrencia del carácter especificado en la cadenadonde se busca. Si no lo encuentra, devuelve un puntero nulo. Cabecera <string.h>.

strchr(cadena,’carácter’);strchr(“texto”,’carácter’);

STRCMP: Compara alfabéticamente dos cadenas y devuelve un entero basado en el resultado dela comparación. La comparación no se basa en la longitud de las cadenas. Muyutilizado para comprobar contraseñas. Cabecera <string.h>.

strcmp(cadena1,cadena2);strcmp(cadena2,”texto”);

RESULTADO

VALOR DESCRIPCIÓN

Menor a Cero Cadena1 menor a Cadena2.

Cero Las cadenas son iguales.

Mayor a Cero Cadena1 mayor a Cadena2.

STRCPY: Copia el contenido de la segunda cadena en la primera. El contenido de la primera sepierde. Lo único que debemos contemplar es que el tamaño de la segunda cadena seamenor o igual a la cadena donde la copiamos. Cabecera <string.h>.

strcpy(cadena1,cadena2);

strcpy(cadena1,”texto”);

Page 37: C+1f

Programación II

Ingeniería Electrónica 37

STRLEN: Devuelve la longitud de la cadena terminada en nulo. El carácter nulo no secontabiliza. Devuelve un valor entero que indica la longitud de la cadena. Cabecera<string.h>.

variable=strlen(cadena);

STRNCAT: Concatena el número de caracteres de la segunda cadena en la primera cadena. Laprimera no pierde la información. Hay que controlar que la longitud de la primeracadena debe tener longitud suficiente para guardar las dos cadenas. Cabecera<string.h>.

strncat(cadena1,cadena2,nº de caracteres);

STRNCMP: Compara alfabéticamente un número de caracteres entre dos cadenas. Devuelve unentero según el resultado de la comparación. Los valores devueltos son los mismosque en la función strcmp. Cabecera <string.h>.

strncmp(cadena1,cadena2,nº de caracteres);

strncmp(cadena1,”texto”,nº de caracteres);

STRNCPY: Copia un número de caracteres de la segunda cadena a la primera. En la primeracadena se pierden aquellos caracteres que se copian de la segunda. Cabecera<string.h>.

strncpy(cadena1,cadena2,nº de caracteres);

strncpy(cadena1,”texto”,nº de caracteres);

STRRCHR: Devuelve un puntero a la última ocurrencia del carácter buscado en la cadena. Si nolo encuentra devuelve un puntero nulo. Cabecera <string.h>.

strrchr(cadena,’carácter’);strrchr(“texto”,’carácter’);

STRPBRK: Devuelve un puntero al primer carácter de la cadena que coincida con algún carácterde la cadena a buscar. Si no hay correspondencia devuelve un puntero nulo. Cabecera<string.h>.

strpbrk(“texto”,”cadena_de_busqueda”);strpbrk(cadena,cadena_de_busqueda);

TOLOWER: Devuelve el carácter equivalente al de la variable en minúsculas, si la variable es unaletra y la deja como esta si la letra esta en minúsculas. Cabecera <ctype.h>.

variable_char=tolower(variable_char);

TOUPPER: Devuelve el carácter equivalente al de la variable en mayúsculas, si la variable es unaletra y la deja como esta si la letra esta en minúsculas. Cabecera <ctype.h>.

variable_char=toupper(variable_char);

Page 38: C+1f

Programación II

Ingeniería Electrónica 38

PROGRAMA #3CDescripción: Cuenta el numero de letras y números que hay en una cadena. La longitud debe sersiempre de cinco por no conocer aún la función que me devuelve la longitud de una cadena.

#include <conio.h>#include <stdio.h>#include <ctype.h>void main(void){ int ind,cont_num=0,cont_text=0;

char temp; char cadena[6]; clrscr(); printf("Introducir 5 caracteres: "); gets(cadena); for(ind=0;ind<5;ind++) {

temp=isalpha(cadena[ind]);if(temp) cont_text++;else cont_num++;

} printf("El total de letras es %d\n",cont_text); printf("El total de n£meros es %d\n",cont_num); getch();

}

PROGRAMA #3DDescripción: Utilizando el resto de funciones nos va a dar información completa del valor quecontiene la variable.

#include<conio.h>#include<stdio.h>#include<ctype.h>void main(void){ char letra;

clrscr(); printf("Introducir valor: "); letra=getchar(); if(isdigit(letra)) printf("Es un numero"); else {

if(islower(letra)) printf("Letra en minuscula");else printf("Letra en mayuscula");if(ispunct(letra)) printf("Caracter de puntuaci¢n");if(!isgraph(letra)) printf("Es un espacio");

} getch();}

Page 39: C+1f

Programación II

Ingeniería Electrónica 39

PROGRAMA #3E

Descripción: Copia, concatena, mide e inicializa cadenas.

#include<conio.h>#include<stdio.h>#include<string.h>

void main(void){ char *origen,destino[20]; clrscr();

printf("Introducir origen: "); gets(origen); strcpy(destino,origen); printf("%s\n%s\n\n",destino,origen); getch(); memset(destino,'\0',20); menset(destino,'x',6);

if(strlen(origen)<14) { printf("Se pueden concatenar\n"); strcat(destino,origen); } else printf("No se pueden concatenar\n");

printf("%s",destino); getch();

}

PROGRAMA #3F

Descripción: Pide una contraseña de entrada. Luego pide 10 códigos de 6 dígitos. Por último pidelos 3 primeros dígitos de los códigos que deseas ver.

#include <conio.h>#include <stdio.h>#include <string.h>#include <dos.h>

void main(void){ int cont;

char ver_codigo[4]; char contra[6]="abcde"; char tu_contra[6]; char codigos[10][7]; clrscr(); printf("Contraseña "); gets(tu_contra);

Page 40: C+1f

Programación II

Ingeniería Electrónica 40

clrscr(); if(strcmp(tu_contra,contra))

{ printf("ERROR"); delay(2000); exit(0); } printf("Introducir codigos\n"); for(cont=0;cont<10;cont++); { printf("%2.2d: ",cont-1); gets(codigos[cont]); } clrscr(); printf("Codigo a listar? "); gets(ver_codigo);

for(cont=0;cont<10;cont++); { if(strncmp(ver_codigo,codigos[cont],3))

printf("%s\n",codigos[cont]);}

getch();}

PROGRAMA #3G

Descripción: En el cuadro de la izquierda busca la primera coincidencia y muestra la cadena apartir de esa coincidencia. En el cuadro de la derecha busca la última coincidencia y muestra lacadena a partir de ese punto.

#include<stdio.h>#include<conio.h>#include<string.h>

void main(void){ char letra; char *resp; char cad[30]; clrscr();

printf("Cadena: "); gets(cad); printf("Buscar Letra: "); letra=getchar();

resp=strchr(cad,letra);

if(resp) printf("%s",resp); else printf("No esta");

getch();}

#include<stdio.h>#include<conio.h>#include<string.h>

void main(void){

char letra;char *resp;char cad[30];clrscr();

printf("Cadena: ");gets(cad);printf("Buscar Letra: ");letra=getchar();

resp=strrchr(cad,letra);

if(resp)printf("%s",resp);

elseprintf("No Esta");

getch();}

Page 41: C+1f

Programación II

Ingeniería Electrónica 41

PROGRAMA #3H

Descripción: En este ejemplo se busca en una cadena a partir de un grupo de caracteres. Si noencuentra coincidencia con ninguna letra en la cadena muestra un mensaje de error.

#include <stdio.h>#include <conio.h>#include <string.h>

void main(void){ char letras[5];

char *resp; char cad[30]; clrscr();

printf("Introducir cadena: "); gets(cad);

printf("Posibles Letras (4): "); gets(letras); resp=strpbrk(cad,letras);

if(resp) printf("%s",resp); else

printf("Error");getch();

}

PROGRAMA #3I

Descripción: El programa permite leer desde teclado caracteres que no sean numéricos.

#include <stdio.h>#include <conio.h>#include <ctype.h>

void main(void){ char x=0,y=0;

clrscr(); printf("Programa que solo capta caracteres no numéricos "); printf("Introduzca carácter: "); scanf("%c",&y);

x=isalpha(y); if(x)

printf("\nEl carácter capturado:%c",y); getch();}

Page 42: C+1f

Programación II

Ingeniería Electrónica 42

PROGRAMA #3J

Descripción: El programa lee un carácter (que no sea vocal) y determina a cuantas posiciones seencuentra de las dos vocales mas próximas a el y cuales son. Además considera mayúsculas yminúsculas indistintamente.

#include <stdio.h>#include <conio.h>#include <ctype.h>#include <string.h>#include <stdlib.h>

void main(void){ char letra, *rep, *ret; char alfa[]="abcdefghijklmn¤opqrstuvwxyz", vocal[]="aeiou";

clrscr(); printf("Introduzca el caracter: ");

letra=tolower(getchar()); if(isalpha(letra)) { rep=strchr(vocal,letra); if(rep)

{printf("No acepta vocales");getch();exit(0);

} else {

ret=strchr(alfa,letra);printf("La posicion de la letra es: %d",(ret+1)-alfa);

} } getch();}

Programas propuestos para la unidad 3

1. Programa que utilice al menos 3 funciones de cadena.

2. Programa que pida el nombre y no acepte caracteres diferentes a los alfabéticos yla edad que solo sean valores numéricos entre 1 y 100.

3. Escribir un programa que convierta un número romano (en forma de cadena decaracteres) en un número arábigoReglas de conversiónM=1000, D=500, C=100, L=50, X=10, V=5, I=1

4. Se introduce una frase por teclado. Se desea imprimir cada palabra de la frase enlíneas diferentes y consecutivas.

5. Escribir un programa que permita escribir en sentido inverso una cadena decaracteres.

Page 43: C+1f

Programación II

Ingeniería Electrónica 43

UNIDAD IV “APUNTADORES Y ESTRUCTURAS”Objetivo educacional:El alumno utilizará los apuntadores y estructuras para la realización de programas más eficientes.

9. ESTRUCTURAS, UNIONES, ENUMERACIONES

C proporciona formas diferentes de creación de tipos de datos propios. Uno de ellos es laagrupación de variables bajo un mismo nombre, Otra es permitir que la misma parte de memoriasea definida como dos o más tipos diferentes de variables y también crear una lista de constantesentera con nombre.

ESTRUCTURAS

Una estructura es una colección de variables que se referencia bajo un único nombre,proporcionando un medio eficaz de mantener junta una información relacionada. Las variables quecomponen la estructura se llaman miembros de la estructura y está relacionado lógicamente con losotros. Otra característica es el ahorro de memoria y evitar declarar variables que técnicamenterealizan las mismas funciones.

SINTAXIS:

struct nombre{var1;var2;varN;};.

.

.struct nombre etiqueta1,etiquetaN;

Los miembros individuales de la estructura se referencian utilizando la etiqueta de la estructurael operador punto(.) y la variable a la que se hace referencia. Los miembros de la estructura debenser inicializados fuera de ella, si se hace en el interior da error de compilación.

etiqueta.variable;

PROGRAMA #4ADescripción: El programa es un ejemplo de apuntadores y estructuras

#include <stdio.h>#include <conio.h>void main(void){ int opcion=0; struct ficha{ char nombre[40];

char apellido[50]; unsigned edad;} empleado,usuario;

struct nombre{var1;var2;varN;}etiqueta1,etiquetaN;

Page 44: C+1f

Programación II

Ingeniería Electrónica 44

do { clrscr(); gotoxy(2,4);printf("1.-Empleados");

gotoxy(2,5);printf("2.-Usuarios"); gotoxy(2,6);printf("0.-Visualizar");

gotoxy(2,7);printf("Elegir Opcion: "); scanf("%d",&opcion);

if(opcion==0) break;

if(opcion==1) {

gotoxy(2,10);printf("Nombre: ");gets(empleado.nombre);

gotoxy(2,11);printf("Apellido: "); gets(empleado.apellido); gotoxy(2,12);printf("Edad: "); scanf("%d",&empleado.edad);

} else {

gotoxy(2,10);printf("Nombre: "); gets(usuario.nombre); gotoxy(2,11);printf("Apellido: "); gets(usuario.apellido); gotoxy(2,12);printf("Edad: "); scanf("%d",&usuario.edad);

} }while(opcion!=0); gotoxy(2,18);printf("%s %s\n",empleado.nombre,empleado.apellido); gotoxy(2,19);printf("%u a¤os",empleado.edad); gotoxy(30,18);printf("%s %s\n",usuario.nombre,usuario.apellido); gotoxy(30,19);printf("%u a¤os",usuario.edad); getch();}

Las operaciones más comunes es asignar el contenido de una estructura a otra estructura delmismo tipo mediante una única sentencia de asignación como si fuera una variable es decir no esnecesario ir elemento por elemento. Otra operación muy común son los arrays de estructuras. Paradeclarar un array de estructuras, se debe definir primero la estructura y luego declarar la etiquetaindicando el número de elementos.

SINTAXIS:

struct nombre{var1;var2;varN;

}etiqueta[nº elementos];

Como ejemplo de array de estructuras deberemos crear una lista de correos utilizandoestructuras para guardar la información. Las operaciones que deben hacerse son añadir datos, borrardatos y realizar listados. El número de registros que va a mantener es de 100. Se deberá controlarque no supere el límite máximo.

Page 45: C+1f

Programación II

Ingeniería Electrónica 45

UNIONES

Una unión es una posición de memoria que es compartida por dos o más variables diferentes,generalmente de distinto tipo, en distintos momentos. La declaración es similar a la estructura.Cuando se crea una etiqueta de la unión el compilador reserva memoria para el mayor miembro dela unión. El uso de una unión puede ayudar a la creación de código independiente de la máquina yahorra memoria en la declaración de variables. Para referencia a un elemento de la unión se haceigual que si fuera una estructura.

SINTAXIS:

union nombre{var1;var2;varN

};..union nombre etiqueta1,etiquetaN;

PROGRAMA #4B

Descripción: Este programa pide un nombre y luego imprime el nombre con las iniciales.

#include <stdio.h>#include <conio.h>#include <stdlib.h>union persona {

char nombre[10]; char inicial; } pers;

int main() { printf("Escribe tu nombre: "); gets(pers.nombre);

printf("\nTu nombre es: %s\n",pers.nombre); printf("\nTu inicial es: %c\n",pers.inicial);

getch(); return 0; }

union nombre{var1;var2;varN

}etiqueta1,etiquetaN;

Page 46: C+1f

Programación II

Ingeniería Electrónica 46

ENUMERACIONES

Es un conjunto de constantes enteras con nombre que especifica todos los valores válidos queuna variable de ese tipo puede tener. La definición es muy parecida a las estructuras, la palabraclave enum señala el comienzo de un tipo enumerado. El valor del primer elemento de laenumeración es 0 aunque se puede especificar el valor de uno o más símbolos utilizando unaasignación.

SINTAXIS:

enum nombre{lista_de_enumeraciones}etiqueta1,etiquetaN;

enum nombre{lista_de_enumeraciones};...enum nombre etiqueta1,etiquetaN;

PROGRAMA #4C

Descripción: Este programa hace conversiones de moneda.

#include <stdio.h>#include <conio.h>void main(void){ enum moneda{dolar,penique=100,medio=50,cuarto=25}; enum moneda dinero; clrscr(); printf("Valor de la moneda: ");

scanf("%d",&dinero);

switch(dinero) { case dolar:

printf("Con ese valor es un Dolar"); break;

case penique: printf("Con ese valor es un penique"); break;

case medio: printf("con ese valor es Medio-Dolar"); break;

case cuarto: printf("Con ese valor es un cuarto"); break;default: printf("Moneda Inexistente");

} getch();}

Page 47: C+1f

Programación II

Ingeniería Electrónica 47

10.PUNTEROS

Un puntero es una variable que contiene una dirección de memoria. Esa dirección es laposición de n objeto (normalmente una variable) en memoria. Si una variable va a contener unpuntero, entonces tiene que declararse como tal. Cuando se declara un puntero que no apunte aninguna posición valida ha de ser asignado a un valor nulo (un cero).

SINTAXIS:

tipo *nombre;

OPERADORES: El & devuelve la dirección de memoria de su operando. El * devuelve el valorde la variable localizada en la dirección que sigue. Pone en m la dirección de memoria de la variablecuenta. La dirección no tiene nada que ver con el valor de cuenta. En la segunda línea pone el valorde cuenta en q.

m= &cuenta;q=*m;

PROGRAMA #4D

Descripción: Devuelve la direccion de memoria.

#include <stdio.h>#include <conio.h>void main(void){ int *p;

int valor; clrscr(); printf("Introducir valor: "); scanf("%d",&valor); p=&valor; printf("Dirección de memoria de valor es: %p\n",p); printf("El valor de la variable es: %d",*p); getch();}

PROGRAMA #4E

Descripción: Realiza la asignación de un puntero a otro puntero

#include <conio.h>#include <stdio.h>void main(void){

int x;int *p1, *p2;p1=&x;p2=p1;printf(“%p”,p2);getch();

}

Page 48: C+1f

Programación II

Ingeniería Electrónica 48

ARITMÉTICA: Dos operaciones aritméticas que se pueden usar como punteros, la suma y la resta.Cuando se incrementa un puntero, apunta a la posición de memoria del siguiente elemento de sutipo base. Cada vez que se decrementa, apunta a la posición del elemento anterior.

COMPARACIÓN: Se pueden comparar dos punteros en una expresión relacional. Generalmente, lacomparación de punteros se utiliza cuando dos o más punteros apuntan a un objeto común.

if(p<q) printf (“p apunta a menor memoria que q”);

ARRAY DE PUNTEROS: Los punteros pueden estructurarse en arrays como cualquier otro tipo dedatos. Hay que indicar el tipo y el número de elementos. Su utilización posterior es igual que losarrays que hemos visto anteriormente, con la diferencia de que se asignan direcciones de memoria.

DECLARACIÓN:

tipo *nombre[nº elementos];

ASIGNACIÓN:

nombre_array[indice]=&variable;

UTILIZAR ELEMENTOS:

*nombre_array[indice];

p1++;p1--;p1+12;

Page 49: C+1f

Programación II

Ingeniería Electrónica 49

PROGRAMA #4F

Descripción: Este programa es un ejemplo del número de pila en el que se almacena.

#include <stdio.h>#include <conio.h>#include <stdlib.h>void guarda(int i);int recupera(void);int *top, *p1, pila[50];void main(void){ int valor;

clrscr();top=pila;

p1=pila;do{

printf("Introducir un valor: "); scanf("%d",&valor); if(valor!=0)

guarda(valor); else

printf("En lo alto: %d\n",recupera());}while(valor!=-1);

}void guarda(int i){ if(p1==(top+50)) {

printf("Pila desbordada"); exit(1); }

p1++; *p1=i;}int recupera(void){ if(p1==top) { printf("Pila vacía"); exit(1); } p1--; getch(); return *(p1+1);}

Page 50: C+1f

Programación II

Ingeniería Electrónica 50

PROGRAMA #4G

Descripción: Este programa se introduce un número y se le asigna el dia respecto al número.

#include <stdio.h>#include <conio.h>void dias(int n);void main(void){ int num; clrscr();

printf("Introducir no. de Día: ");scanf("%d",&num);

dias(num);getch();

}

void dias(int n){ char *dia[]={"No. de día no Valido",

"Lunes","Martes","Miércoles","Jueves","Viernes","Sábado","Domingo"};

printf("%s",dia[n]);}

PUNTEROS A CADENAS: Existe una estrecha relación entre punteros y los arrays. Se asigna ladirección del primer elemento del array y así se conoce el comienzo del array, el final lo sabemosmediante el nulo que tienen todas las cadenas al final. Con esta relación se puede declarar unacadena sin tener en cuenta la longitud de la cadena. Otra característica importe es la posibilidad espoder pasar cadenas a las funciones.

SINTAXIS:

char *nombre;

char *nombre[];

Page 51: C+1f

Programación II

Ingeniería Electrónica 51

PROGRAMA #4H

Descripción: En este ejemplo se pueden incluir primer apellido o el primero y el segundo, lalongitud de la cadena no importa. Mostramos el contenido de apellidos y su dirección de memoria.

#include <stdio.h>#include <conio.h>void main(void){ char *apellidos; clrscr(); printf("Introducir apellidos: "); gets(apellidos); printf("Tus apellidos son: %s",apellidos); printf("La dirección de memoria es: %p",apellidos); getch();}

PUNTEROS A ESTRUCTURAS: C permite punteros a estructuras igual que permite punteros acualquier otro tipo de variables. El uso principal de este tipo de punteros es pasar estructuras afunciones. Si tenemos que pasar toda la estructura el tiempo de ejecución puede hacerse eterno,utilizando punteros sólo se pasa la dirección de la estructura. Los punteros a estructuras se declaranponiendo * delante de la etiqueta de la estructura..

SINTAXIS:struct nombre_estructura etiqueta;struct nombre_estructura *nombre_puntero;

Para encontrar la dirección de una etiqueta de estructura, se coloca el operador & antes delnombre de la etiqueta. Para acceder a los miembros de una estructura usando un puntero usaremosel operador flecha (->).

PROGRAMA #4I

Descripcion: Programa que muestra un ejemplo de como acceder a la estructura usando unpuntero.

#include <stdio.h>#include <conio.h>void main(void){ struct ficha{

int balance; char nombre[80];

}*p; clrscr(); printf("Nombre: "); gets(p->nombre); printf("Balance: "); scanf("%d",&p->balance); printf("%s",p->nombre); printf("\t%d",p->balance);

getch();}

Page 52: C+1f

Programación II

Ingeniería Electrónica 52

ASIGNACIÓN DINAMICA DE MEMORIA: La asignación dinámica es la forma en que unprograma puede obtener memoria mientras se está ejecutando. Hay ocasiones en que un programanecesita usar cantidades de memoria variable.

La memoria se obtiene del montón (región de la memoria libre que queda entre el programa yla pila). El tamaño del montón es desconocido pero contiene gran cantidad de memoria. El sistemade asignación dinámica esta compuesto por las funciones malloc()que asigna memoria a unpuntero y free()que libera la memoria asignada. Ambas funciones necesitan el archivo decabecera stdlib.h.

SINTAXIS:

puntero=malloc(numero_de_bytes);

free(puntero);

PROGRAMA #4J

Descripción: En este ejemplo se puede ver como se le puede asignar memoria en el programa.

#include <stdio.h>#include <conio.h>#include <stdlib.h>#include <string.h>void main(void){ char *c; int t;

clrscr(); c=(char*)malloc(80); if(!c)

{ printf("Fallo al asignar memoria"); exit(1); } printf("Introducir cadena: "); gets(c);

for(t=strlen(c)-1;t>=0;t--)putchar(c[t]);

free(c);getch();

}

INDIRECCIÓN MÚLTIPLE: Que un puntero apunte a otro puntero que apunte a un valor dedestino. En el caso de un puntero a puntero, el primer puntero contiene la dirección del segundopuntero, que apunta al objeto que contiene el valor deseado. La siguiente declaración indica alcompilador que es un puntero a puntero de tipo float.

float **balance;

Page 53: C+1f

Programación II

Ingeniería Electrónica 53

PROGRAMA #4K

Descripción: Programa que demuestra el procedimiento “copia” el cual, copia una cadena en otra.

#include<stdio.h>#include<conio.h>#include<string.h>char *copia(char *cad1, char *cad2);void main(void){ char palabra1[10]; char palabra2[20]; printf("Palabra 1= "); scanf("%s",palabra1); printf("Palabra 2= "); scanf("%s",palabra2); copia(palabra1,palabra2); printf("Palabra 1 + Palabra 2 = %s",palabra2); getch();}char *copia(char *cad1, char *cad2){ char *inicio; inicio=cad2; while(*cad2!='\0')

cad2++; while(*cad1!='\0')

{ *cad2=*cad1; cad2++; cad1++; } *cad2='\0'; cad2=inicio;}

Page 54: C+1f

Programación II

Ingeniería Electrónica 54

Programas propuestos para la unidad 4

1. Programa que lea el nombre, domicilio, telefono y CP. para 10 personas usandoestructuras; después los imprima en orden inverso.

2. Programa similar que lea el nombre, apellidos, edad de 5 personas unsandopunteros.

3. Escribir un programa que lea un número determinado de enteros desde el teclado ylos imprima en el mismo orden y con la condición de que cada entero sólo seescribe una vez. Si el entero ya se ha impreso, no se debe imprimir de nuevo. Porejemplo si los números siguientes se leen desde el teclado: 55 78 -25 3 55 24 -37, el programa debe imprimir lo siguiente: 55 78 -25 3 24 -3 7.

4. Escribir una función que utilice punteros para copiar un array de elementos double

5. Escribir el código de la función siguiente que devuelve la suma de elementos floatapuntados por los n primeros punteros del array p:

flota suma(flota *p[], int n)

Page 55: C+1f

Programación II

Ingeniería Electrónica 55

UNIDAD V “ARCHIVOS”Objetivo educacional:El alumno utilizará los archivos para el procesamiento de información.

11.ARCHIVOS (FICHEROS)

El sistema de archivos de C está diseñado para secuencias que son independientes deldispositivo. Existen dos tipos se secuencias: de texto que es una ristra de caracteres organizados enlíneas terminadas por el carácter salto de línea. Secuencia binaria que es una ristra de bytes con unacorrespondencia uno a uno con los dispositivos. En esencia C trabaja con dos tipos de archivosecuenciales (texto) y binarios (registros).

Todas las operaciones de ficheros se realizan a través de llamadas a funciones que estándefinidas en en fichero de cabecera CONIO.H o IO.H. Esto permite una gran flexibilidad y facilidada la hora de trabajar con ficheros.

Mediante una operación de apertura se asocia una secuencia a un archivo especificado, estaoperación de apertura se realiza mediante un puntero de tipo FILE donde están definidas lascaracterísticas del fichero (nombre, estado, posición,…). Una vez abierto el fichero escribiremos ysacaremos información mediante las funciones implementadas y por último cerraremos los ficherosabiertos.

ABRIR FICHERO: La función fopen abre una secuencia para que pueda ser utilizada yvinculada con un archivo. Después devuelve el puntero al archivo asociado, si es NULL es que seha producido un error en la apertura. Se utiliza un puntero de tipo FILE para abrir ese fichero. Sirvepara los dos tipos de ficheros. Cabecera <stdio.h>.

FILE *nombre_puntero_fichero;fopen(char_nombre_archivo,char_modo_apertura);

MODOS DE APERTURA

VALOR DESCRIPCIÓN

r Abre un archivo de texto para lectura.

w Crea un archivo de texto para escritura.

a Abre un archivo de texto para añadir información.

rb Abre un archivo binario para lectura.

wb Crea un archivo binaro para escritura.

ab Abre un archivo binario para añadir información.

r+ Abre un archivo de texto para lectura / escritura.

w+ Crea un archivo de texto para lectura / escritura.

a+ Abre o Crea un archivo de texto para añadir información.

r+b Abre un archivo binario para lectura / escritura.

w+b Crea un archivo binaro para lectura / escritura.

a+b Abre o Crea un archivo binario para añadir información

Page 56: C+1f

Programación II

Ingeniería Electrónica 56

CIERRE FICHERO: Una vez terminadas las operaciones de escritura y lectura hay que cerrar lasecuencia (archivo). Se realiza mediante la llamada a la funciónfclose() que cierra un fichero determinado o fcloseall() quecierra todos los archivos abiertos. Estas funciones escribe la informaciónque todavía se encuentre en el buffer y cierra el archivo a nivel de MS-DOS. Ambas funciones devuelve CERO si no hay problemas. La cabeceraque utilizan es <stdio.h>.

int fclose(puntero_fichero);

int fcloseall();

PROGRAMA #5A

#include <stdio.h>#include <conio.h>

void main(void){

FILE *punt_fich;clrscr();

if((punt_fich=fopen("hola.txt","w"))==NULL){

printf("Error en la apertura");exit(0);

}printf( “Ya se creo el archivo hola.txt verificalo”);getch();fclose(punt_fich);

}

ESCRITURA DE CARACTERES Y CADENAS EN SECUENCIALES

FPUTC/PUTC: Escribe un carácter en el fichero abierto por el puntero que se pone comoparámetro. Si todo se produce correctamente la función devuelve el propiocarácter, si hay algún error devuelve EOF. La cabecera que utiliza es<stdio.h>.

int fputc(variable_char,puntero_fichero);

int fputc(‘carácter’,puntero_fichero);int putc(variable_char,puntero_fichero);

int putc(‘carácter’,puntero_fichero);

Page 57: C+1f

Programación II

Ingeniería Electrónica 57

FPUTS: Escribe el contenido de la cadena puesta como primer parámetro de la función.El carácter nulo no se escribe en el fichero. Si se produce algún error devuelveEOF y si todo va bien devuelve un valor no negativo. La cabecera <stdio.h>.

int fputs(variable_cadena,puntero_fichero);

int fputs(“texto”,puntero_fichero);

FPRINTF: Escribe en el fichero cualquier tipo de valor, cadenas, números y caracteres. Estafunción tiene el mismo formato que printf. Hay que indicarle el puntero, elidentificador de formato y nombre de la variables o variables a escribir.Cabecera <stdio.h>.

fprintf(puntero_fichero,“texto”);fprintf(puntero_fichero“identificador”,var);

fprintf(puntero_fich“ident(es)_formato”,variable(s));

PROGRAMA #5B

#include <stdio.h>#include <conio.h>#include <string.h>void letra(void);void frase(void);FILE *punt_fich;void main(void){

int opt;clrscr();if((punt_fich=fopen("hola.txt","w"))==NULL){

printf("Error en la apertura");exit(0);

}printf("1.INTRODUCIR LETRA A LETRA\n");printf("2.INTRODUCIR CADENA A CADENA\n\n");printf("Elegir opcion: ");scanf("%d",&opt);fflush(stdin);clrscr();switch(opt){

case 1:letra();break;

case 2:frase();break;

}fclose(punt_fich);

}

Page 58: C+1f

Programación II

Ingeniería Electrónica 58

void letra(void){

char t;for(;t!='$';)

{printf(":");t=getchar();fputc(t,punt_fich);fflush(stdin);

}}

void frase(void){

char *frase;do{

printf(":");gets(frase);fprintf(punt_fich,"%s\n",frase);// fputs(frase,punt_fich);fflush(stdin);

}while(strcmp(frase,"$"));}

LECTURA DE CARACTERES Y CADENAS EN SECUENCIALES

FGETC/FGET: Devuelve el carácter leído del fichero e incrementa el indicador de posicióndel archivo. Si se llega al final del fichero la función devuelve EOF. Todoslos valores que lee los transforma a carácter. Cabecera es <stdio.h>.

var_char=fgetc(puntero_fichero);

var_char=getc(puntero_fichero);

FGETS: Lee un determinado número de caracteres de un fichero y los pasa a unavariable de tipo cadena. Lee caracteres hasta que encuentra un salto delínea, un EOF o la longitud especificada en la función. Si se produce unerror devuelve un puntero NULL. La Cabecera es <stdio.h>.

fgets(variable_cadena,tamaño,puntero_fichero);

Page 59: C+1f

Programación II

Ingeniería Electrónica 59

PROGRAMA #5C

#include <stdio.h>#include <conio.h>void letra(void);void frase(void);FILE *punt_fich;

void main(void){

int opt;clrscr();if((punt_fich=fopen("hola.txt","r"))==NULL){

printf("Error en la apertura");exit(0);

}printf("1.LEER LETRA A LETRA\n");printf("2.LEER CADENAS\n\n");printf("Elegir opcion: ");scanf("%d",&opt);fflush(stdin);clrscr();switch(opt){case 1:

letra();break;

case 2:frase();break;

}getch();fclose(punt_fich);

}

void letra(void){

char t=0;for(;t!=EOF;){

t=getc(punt_fich);printf("%c",t);

}}

void frase(void){

char frase[31];fgets(frase,30,punt_fich);printf("%s",frase);

}

Page 60: C+1f

Programación II

Ingeniería Electrónica 60

POSICION EN FICHEROS SECUENCIALES Y BINARIOS

REWIND: Lleva el indicador de posición al principio del archivo. No devuelve ningún valor.La cabecera que utiliza es <stdio.h>.

rewind(puntero_fichero);

FGETPOS: Guarda el valor actual del indicador de posición del archivo. El segundo terminoes un objeto del tipo fpos_t que guarda la posición. El valor almacenado sólo esvalido para posteriores llamadas a fsetpos. Devuelve DISTINTO DE CERO sise produce algún error y CERO si todo va bien. Cabecera <stdio.h>.

int fgetpos(puntero_fichero,&objeto_fpos_t);

FSETPOS: Desplaza el indicador de posición del archivo al lugar especificado por el segundotermino que es un objeto fpos_t. Este valor tiene que haber sido obtenido por unallamada a fgetpos. Devuelve DISTINTO DE CERO si hay errores y CERO siva todo bien. Cabecera <stdio.h>.

int fsetpos(puntero_fichero,&objeto_fpos_t);

TELL: Devuelve el valor actual del indicador de posición del archivo. Este valor es elnúmero de bytes que hay entre el comienzo del archivo y el indicador. Devuelve –1 si se produce un error. Cabecera <io.h>.

var_long =tell(puntero_fichero);

FEOF: Determina el final de un fichero binario. Se utiliza siempre que se realizanconsultas, informes y listados, va asociado a un bucle que recorre todo el fichero.Cabecera <stdio.h>.

feof(puntero_fichero);

FSEEK: Sitúa el indicador del archivo en la posición indicada por la variable de tipo long(en segundo termino) desde el lugar que le indiquemos mediante el tercer terminode la función (mediante una constante). Devuelve –1 si hay error, si no hay errordevuelve la nueva posición. La Cabecera es <io.h>.

var_long=fseek(puntero_fichero,long_despl,int_origen);

CONSTANTE DESCRIPCIÓN

SEEK_SET Desde el principio del fichero

SEEK_CUR Desde la posición actual.

SEEK_END Desde el final del fichero

Page 61: C+1f

Programación II

Ingeniería Electrónica 61

PROGRAMA #5D

Descripción: Programa que demuestra el procedimiento “copia” el cual, copia una cadena en otra.

#include <stdio.h>#include <conio.h>#include <stdlib.h>void main(void){

FILE *punte;clrscr();

if((punte=fopen("hola.txt","r"))==NULL){

printf("Error de lectura");exit(0);

}fseek(punte,7,SEEK_SET);printf("%c",fgetc(punte));getch();fclose(punte);

}

ESCRITURA Y LECTURA EN BINARIOS

FWRITE: Escribe los datos de una estructura a un fichero binario e incrementa laposición del archivo en el número de caracteres escritos. Hay que tener encuenta que el modo de apertura del fichero debe ser binario Cabecera<stdio.h>.

fwrite(&eti_estru,tamaño_estru,nº_reg,punter_fichero);

FREAD: Lee registros de un fichero binario, cada uno del tamaño especificado en lafunción y los sitúa en la estructura indicada en primer termino de la función.Además de leer los registros incrementa la posición del fichero. Hay que teneren cuenta el modo de apertura del fichero. Cabecera <stdio.h>.

fread(&eti_estru,tamaño_estru,nº_reg,punter_fichero);

Page 62: C+1f

Programación II

Ingeniería Electrónica 62

PROGRAMA #5E

#include <stdio.h>#include <conio.h>#include <stdlib.h>#include <ctype.h>void altas(void);void muestra(void);FILE *fich;struct ficha{

int código;char nombre[25];char direcion[40];int edad;

}cliente;

void main(void){

char opcion;if((fich=fopen("gestion.dat","a+b"))==NULL)

{printf("Error al crear fichero");exit(0);

}do{

clrscr();printf("Altas\n");printf("Consulta\n");printf("Salir\n\n");printf("Elegir opcion: ");scanf("%c",&opcion);fflush(stdin);switch(toupper(opcion)){

case 'A':altas();break;

case 'C':muestra();break;

}}while(toupper(opcion)!='S');fclose(fich);

}void altas(void){

clrscr();printf("Código: ");scanf("%d",&cliente.codigo);fflush(stdin);printf("Nombre: ");gets(cliente.nombre);

Page 63: C+1f

Programación II

Ingeniería Electrónica 63

fflush(stdin);printf("Direccion: ");gets(cliente.direcion);fflush(stdin);printf("Edad: ");scanf("%d",&cliente.edad);fflush(stdin);fwrite(&cliente,sizeof(cliente),1,fich);

}

void muestra(void){

int cod_temp;clrscr();rewind(fich);printf("Código a mostrar:");scanf("%d",&cod_temp);while(!feof(fich)){

fread(&cliente,sizeof(cliente),1,fich);if(cod_temp==cliente.codigo){

printf("Código: %d\n",cliente.codigo);printf("Nombre: %s\n",cliente.nombre);printf("Direc: %s\n",cliente.direcion);printf("Edad: %d\n",cliente.edad);getch();break;

}}

}

Programas propuestos para la unidad 5

1. Abrir un archivo de texto, leerlo línea a línea en un array de caracteres y escribirlode nuevo en otro archivo.

2. Escribir un programa que lea un texto desde el teclado y almacene ese texto en unnuevo archivo de texto con el nombre de miarch.txt El nuevo archivo debe tener lamisma estructura de línea que el archivo de texto escrito desde el teclado. Además,todas las letras minusculas deben ser traducidas a lestras mayusculas.

3. Escribir un programa que permita crear un archivo inventario de los libros de unalibrería, así como calcular e imprimir el valor total del inventario. Los campos decada libro deben ser, como mínimo, título, autor, ISBN, precio, cantidad, editorial.

Page 64: C+1f

Programación II

Ingeniería Electrónica 64

UNIDAD VI “UTILIZACIÓN DE LIBRERIAS EXTERNAS”Objetivo educacional:El alumno utilizará y creará librerías de funciones.

12. FUNCIONES MATEMÁTICAS

El estándar C define 22 funciones matemáticas que entran en las siguientes categorías,trigonométricas, hiperbólicas, logarítmicas, exponenciales y otras. Todas la funciones requieren elarchivo de cabecera MATH.H. Si un argumento de una función matemática no se encuentra en elrango para el que esta definido, devolverá un valor definido EDOM.

ACOS: Devuelve un tipo double. Muestra el arcocoseno de la variable. La variable debe ser detipo double y debe estar en el rango –1 y 1, en otro caso se produce un error de dominio.Cabecera <math.h>.

double acos(variable_double);

ASIN: Devuelve un tipo double. Muestra el arcoseno de la variable. La variable debe ser de tipodouble y debe estar en el rango –1 y 1, en otro caso se produce un error de dominio.Cabecera <math.h>.

double asin(variable_double);

ATAN: Devuelve un tipo double. Muestra el arcotangente de la variable. La variable debe ser detipo double y debe estar en el rango –1 y 1, en otro caso se produce un error de dominio.Cabecera <math.h>.

double atan(variable_double);

COS: Devuelve un tipo double. Muestra el coseno de la variable. La variable debe ser de tipodouble y debe estar expresada en radianes. Cabecera <math.h>.

double cos(variable_double_radianes);

SIN: Devuelve un tipo double. Muestra el seno de la variable. La variable debe ser de tipodouble y debe estar expresada en radianes. Cabecera <math.h>.

double sin(variable_double_radianes);

TAN: Devuelve un tipo double. Muestra la tangente de la variable. La variable debe ser de tipodouble y debe estar expresada en radianes. Cabecera <math.h>.

double tan(variable_double_radianes);

COSH: Devuelve un tipo double. Muestra el coseno hiperbólico de la variable. La variable debeser de tipo double y debe estar en el rango –1 y 1, en otro caso se produce un error dedominio. Cabecera debe ser <math.h>.

double cosh(variable_double);

Page 65: C+1f

Programación II

Ingeniería Electrónica 65

SINH: Devuelve un tipo double. Muestra el seno hiperbólico de la variable. La variable debeser de tipo double y debe estar en el rango –1 y 1, en otro caso se produce un error dedominio. Cabecera debe ser <math.h>.

double sinh(variable_double);

TANH: Devuelve un tipo double. Muestra la tangente hiperbólico de la variable. La variabledebe ser de tipo double y debe estar en el rango –1 y 1, en otro caso se produce un errorde dominio. Cabecera debe ser <math.h>.

double tanh(variable_double);

PROGRAMA #6A

#include <stdio.h>#include <conio.h>#include <math.h>

void main(void){

double radianes;clrscr();

printf("Introducir radianes: ");scanf("%f",&radianes);

printf("Coseno= %f\n",cos(radianes));printf("Seno= %f\n",sin(radianes));printf("Tangente= %f",tan(radianes));getch();

}

CEIL: Devuelve un double que representa el menor entero sin ser menor de la variableredondeada. Por ejemplo, dado 1.02 devuelve 2.0. Si asignamos –1.02 devuelve –1. Enresumen redondea la variable a la alta. Cabecera <math.h>.

double ceil(variable_double);

FLOOR: Devuelve un double que representa el entero mayor que no sea mayor a la variableredondeada. Por ejemplo dado 1.02 devuelve 1.0. Si asignamos –1.2 devuelve –2. Enresumen redondea la variable a la baja. Cabecera <math.h>.

double floor(variable_double);

FABS: Devuelve un valor float o double. Devuelve el valor absoluto de una variable float. Seconsidera una función matemática, pero su cabecera es <stdlib.h>.

var_float fabs(variable_float);

Page 66: C+1f

Programación II

Ingeniería Electrónica 66

LABS: Devuelve un valor long. Devuelve el valor absoluto de una variable long. Se considerauna función matemática, pero su cabecera es <stdlib.h>.

var_long labs(variable_long);

ABS: Devuelve un valor entero. Devuelve el valor absoluto de una variable int. Se considerauna función matemática, pero su cabecera es <stdlib.h>.

var_float abs(variable_float);

MODF: Devuelve un double. Descompone la variable en su parte entera y fraccionaria. La partedecimal es el valor que devuelve la función, su parte entera la guarda en el segundotermino de la función. La variables tienen que ser obligatoriamente de tipo double.Cabecera <math.h>.

var_double_deimal=modf(variable,var_parte_entera);

POW: Devuelve un double. Realiza la potencia de un número base elevado a un exponente quenosotros le indicamos. Se produce un error si la base es cero o el exponente es menor oigual a cero. La cabecera es <math.h>.

var_double=pow(base_double,exponente_double);

SQRT: Devuelve un double. Realiza la raíz cuadrada de la variable. La variable no puede sernegativa, si lo es se produce un error de dominio. La cabecera <math.h>.

var_double=sqrt(variable_double);

PROGRAMA #6B

#include <stdio.h>#include <conio.h>#include <math.h>void main(void){

float num;double num_dec,num_ent;clrscr();printf("Introducir Numero: ");scanf("%f",&num);gotoxy(9,3);printf("ALTO: %.1f",ceil(num));gotoxy(1,4);printf("REDONDEO");gotoxy(9,5);printf("BAJO: %.1f",floor(num));num_dec=modf(num,&num_ent);gotoxy(12,8);printf("ENTERA: %.2f",num_ent);gotoxy(1,9);printf("DESCONPONGO");gotoxy(12,10);printf("DECIMAL: %.2f",num_dec);gotoxy(1,13);printf("VALOR ABSOLUTO: %.2f",fabs(num));gotoxy(1,16);printf("R.CUADRADA: %.2f",sqrt(fabs(num)));getch();

}

Page 67: C+1f

Programación II

Ingeniería Electrónica 67

LOG: Devuelve un double. Realiza el logaritmo natural (neperiano) de la variable. Se produceun error de dominio si la variable es negativa y un error de rango si es cero. Cabecera<math.h>.

double log(variable_double);

LOG10: Devuelve un valor double. Realiza el logaritmo decimal de la variable de tipo double. Seproduce un error de dominio si la variable es negativo y un error de rango si el valor escero. La cabecera que utiliza es <math.h>.

double log10(var_double);

RAMDOMIZE(): Inicializa la semilla para generar números aleatorios. Utiliza las funciones detiempo para crear esa semilla. Esta función esta relacionada con random.Cabecera <stdlib.h>.

void randomize();

RANDOM: Devuelve un entero. Genera un número entre 0 y la variable menos uno. Utilizael reloj del ordenador para ir generando esos valores. El programa debe llevarla función randomize para cambiar la semilla en cada ejecución. Cabecera<stdlib.h>.

int random(variable_int);

PROGRAMA #6C

Descripción: Genera seis números aleatorios entre 1 y 49. No se repite ninguno de ellos.

#include <stdio.h>#include <conio.h>#include <stdlib.h>void main(void){

int num=0,num1=0,repe,temp;int valores[6];clrscr();printf("Loteria primitiva: ");randomize();for(;;){

repe=1;if(num==6)

break;temp=random(49)+1;for(num1=0;num1<=num;num1++){

if(valores[num1]==temp){

valores[num1]=temp;num--;repe=0;break;

Page 68: C+1f

Programación II

Ingeniería Electrónica 68

}}if (repe==1)

valores[num]=temp;num++;

}for(num=0;num<6;num++)printf("%d ",valores[num]);getch();

}

13.FUNCIONES DE CONVERSIÓN

En el estándar de C se definen funciones para realizar conversiones entre valores numéricos ycadenas de caracteres. La cabecera de todas estas funciones es STDLIB.H. Se pueden dividir en dosgrupos, conversión de valores numéricos a cadena y conversión de cadena a valores numéricos.

ATOI: Devuelve un entero. Esta función convierte la cadena en un valor entero. La cadena debecontener un número entero válido, si no es así el valor devuelto queda indefinido. Lacadena puede terminar con espacios en blanco, signos de puntuación y otros que no seandígitos, la función los ignora. La cabecera es <stdlib.h>.

int atoi(variable_char);

ATOL: Devuelve un long. Esta función convierte la cadena en un valor long. La cadena debecontener un número long válido, si no es así el valor devuelto queda indefinido. La cadenapuede terminar con espacios en blanco, signos de puntuación y otros que no sean dígitos,la función los ignora. La cabecera es <stdlib.h>.

long atol(variable_char);

ATOF: Devuelve un double. Esta función convierte la cadena en un valor double. La cadena debecontener un número double válido, si no es así el valor devuelto queda indefinido. Lacadena puede terminar con espacios en blanco, signos de puntuación y otros que no seandígitos, la función los ignora. La cabecera es <stdlib.h>.

double atof(variable_char);

SPRINTF: Devuelve una cadena. Esta función convierte cualquier tipo numérico a cadena. Paraconvertir de número a cadena hay que indicar el tipo de variable numérica y tenerpresente que la longitud de la cadena debe poder guardar la totalidad del número.Admite también los formatos de salida, es decir, que se puede coger distintas partesdel número. La cabecera es <stdlib.h>.

sprintf(var_cadena,”identificador”,var_numerica);

ITOA: Devuelve una cadena. La función convierte un entero en su cadena equivalente y sitúa elresultado en la cadena definida en segundo termino de la función. Hay que asegurarse quela cadena se lo suficientemente grande para guardar el número. Cabecera <stdlib.h>.

itoa(var_entero,var_cadena,base);

Page 69: C+1f

Programación II

Ingeniería Electrónica 69

BASE DESCRIPCIÓN

2 Convierte el valor en binario.

8 Convierte el valor a Octal.

10 Convierte el valor a decimal.

16 Convierte el valor a hexadecimal.

LTOA: Devuelve una cadena. La función convierte un long en su cadena equivalente y sitúa elresultado en la cadena definida en segundo termino de la función. Hay que asegurarse quela cadena se lo suficientemente grande para guardar el número. Cabecera <stdlib.h>.

ltoa(var_long,var_cadena,base);

PROGRAMA #6D

#include<stdio.h>#include<conio.h>#include<stdlib.h>void main(void){

char texto[4];char ntext[10],ntext1[10];int num;float total;clrscr();printf("Numero de 3 digitos: ");scanf("%d",&num);fflush(stdin);printf("Cadena numerica: ");gets(ntext);fflush(stdin);printf("Cadena numerica: ");gets(ntext1);fflush(stdin);sprintf(texto,"%d",num);printf("%c %c %c\n",texto[0],texto[1],texto[2]);total=atof(ntext)+atof(ntext1);printf("%.3f",total);getch();

}

Page 70: C+1f

Programación II

Ingeniería Electrónica 70

1. FUNCIONES DE FECHA Y HORA

Estas funciones utilizan la información de hora y fecha del sistema operativo. Se definen variasfunciones para manejar la fecha y la hora del sistema, así como los tiempos transcurridos. Estasfunciones requieren el archivo de cabecera TIME.H. En este archivo de cabecera se definen cuatrotipos de estructuras para manejar las funciones de fecha y hora (size_t , clock_t , time_t , time).

TIME: Devuelve la hora actual del calendario del sistema. Si se produce un error devuelve –1.Utiliza la estructura time_t a la cual debemos asignar una etiqueta que nos servirá paratrabajar con la fecha y hora. Por si sola no hace nada, necesita otras funciones paramostrar los datos. Cabecera <time.h>.

time_t nombre_etiqueta;..nombre_etiqueta=time(NULL);

CTIME: Devuelve un puntero a una cadena con un formato día semana meshora:minutos:segundo año \n\0. La hora del sistema se obtiene mediante la funcióntime. Cabecera <time.h>.

puntero=ctime(&etiqueta_estructura_time_t);

PROGRAMA #6E

#include<stdio.h>#include<conio.h>#include<time.h>void main(void){

time_t fecha_hora;clrscr();fecha_hora=time(NULL);printf(ctime(&fecha_hora));getch();

}

GETTIME: Devuelve la hora del sistema. Utiliza la estructura dostime_t para guardar lainformación referente a la hora. Antes de hacer referencia a la función hay que crearuna etiqueta de la estructura. Cabecera <dos.h>.

_dos_gettime(&etiqueta_estructura_dostime_t);struct dostime_t{

unsigned hour;unsigned minute;unsigned second;unsigned hsecond;

}

Page 71: C+1f

Programación II

Ingeniería Electrónica 71

PROGRAMA #6F

#include<stdio.h>#include<conio.h>#include<dos.h>void main(void){struct dostime_t ho;clrscr();_dos_gettime(&ho);printf(" %d:%d:%d",ho.hour,ho.minute,ho.second);getch();}

GETDATE: Devuelve la fecha del sistema. Utiliza la estructura dosdate_t para guardar lainformación referente a la fecha. Antes de hacer referencia a la función hay que crearuna etiqueta de la estructura. Cabecera <dos.h>.

_dos_getdate(&etiqueta_estructura_dosdate_t);

struct dosdate_t{unsigned day;unsigned month;unsigned year;unsigned dayofweek;

}

PROGRAMA #6G

#include<stdio.h>#include<conio.h>#include<dos.h>void main(void){struct dosdate_t fec;clrscr();_dos_getdate(&fec);printf("%d/%d/%d\n",fec.day,fec.month,fec.year);getch();}

SETTIME: Permite cambiar la hora del sistema. Utiliza la estructura dostime_t para guardarla información referente a la hora. Antes de hacer referencia a la función hay quecrear una etiqueta de la estructura. Cabecera <dos.h>.

_dos_settime(&etiqueta_estructura_dostime_t);

SETDATE: Permite cambiar la fecha del sistema. Utiliza la estructura dosdate_t paraguardar la información referente a la fecha. Antes de hacer referencia a la funciónhay que crear una etiqueta de la estructura. Cabecera <dos.h>.

_dos_setdate(&etiqueta_estructura_dosdate_t);

Page 72: C+1f

Programación II

Ingeniería Electrónica 72

PROGRAMA #6H

#include<stdio.h>#include<conio.h>#include<dos.h>void main(void){struct dosdate_t fec;struct dostime_t ho;clrscr();printf("Introducir fecha: ");gotoxy(19,1);scanf("%u%*c%u%*c%u",&fec.day,&fec.month,&fec.year);printf("Introducir hora: ");gotoxy(18,2);scanf("%u%*c%u%*c%u",&ho.hour,&ho.minute,&ho.second);_dos_settime(&ho);_dos_setdate(&fec);}

DIFFTIME: Devuelve un double. La función devuelve la diferencia, en segundos, entre una horainicial y hora final. Se restara la hora final menos la hora inicial. Tenemos queobtener la hora al iniciar un proceso y al terminar el proceso volveremos a tomar lahora. Cabecera <time.h>.

double difftime(hora_final,hora_inicial);

PROGRAMA #6I

#include<stdio.h>#include<conio.h>#include<time.h>void main(void){

time_t inicio, final;double tiempo,cont;clrscr();inicio=time(NULL);for(cont=0;cont<50000;cont++)clrscr();

final=time(NULL);tiempo=difftime(final,inicio);printf("Tiempo: %.1f",tiempo);getch();

}

Page 73: C+1f

Programación II

Ingeniería Electrónica 73

2. FUNCIONES DE SISTEMA

Este tema trata sobre funciones que, de una u otra forma, están más próximas al sistemaoperativo que las demás funciones de la biblioteca estándar de C. Estas funciones permiteninteractuar directamente con el sistema operativo. Las funciones de este tema interactúan con elsistema operativo DOS. Este tipo de funciones atizan en unos casos el archivo de cabecera DOS.H yen otros DIR.H.

BIOS_EQUIPLIST: Esta función devuelve un valor que especifica el equipo existente en lacomputadora. Ese valor está codificado tal como se muestra a continuación.

BIT DESCRIPCIÓN EQUIPO

0 Tiene unidades de disco. --

1 Con microprocesador matemático. --

0 0: 16K

0 1: 32K

1 0: 48K2,3 Tamaño RAM en la placa base.

1 1: 64K

0 0: no utilizado

0 1: 40x25BN adap.color

1 0: 80x25BN adap.color4,5 Modo inicial de vídeo.

1 1: 80x25adap.monocromo

0 0: una

0 1: dos

1 0: tres6,7 Número de unidades de disquete.

1 1: cuatro

8 Chip DMA. 0

0 0 0: cero

0 0 1: uno

0 1 0: dos

0 1 1: tres

1 0 0: cuatro

9,10,11 Número de puertos serie.

1 0 1: cinco

Page 74: C+1f

Programación II

Ingeniería Electrónica 74

1 1 0: seis

1 1 1: siete

12 Con adaptador de juegos. 1

13 Con módem 1

0 0: cero

0 1: uno

1 0: dos14,15 Número de impresoras

1 1: tres

La cabecera que utiliza esta función es <bios.h>. El modo de trabajar esigualar la función a una variable sin signo, después el resultado se le desplazaa los bits que nos interesan para mostrar la información.

var_sinsigno=_bios_equiplist();

var_sinsigno >> nº_bit;

PROGRAMA #6J

#include<stdio.h>#include<conio.h>#include<bios.h>void main(void){

unsigned num_bit;clrscr();num_bit=_bios_equiplist();num_bit>>=6;printf("Nº de disqueteras: %d",(num_bit & 3)+1);getch();

}

GETDISKFREE: Devuelve la cantidad de espacio libre del disco especificado por la unidad(numeradas a partir de 1 que corresponde a la unidad A). Esta función utilizala estructura diskfree_t. El espacio lo devuelve indicando el número decilindros libres, para pasarlo a bytes hay que multiplicarlo por 512 y por 64.Cabecera <dos.h>.

_dos_getdiskfree(unidad,&etiq_struct_diskfree_t);

Page 75: C+1f

Programación II

Ingeniería Electrónica 75

VALOR UNIDAD

1 A:

2 B:

3 C:

PROGRAMA #6K

#include <stdio.h>#include <conio.h>#include <dos.h>void main(void){struct diskfree_t disco;float tam;clrscr();_dos_getdiskfree(3,&disco);tam= (float)(disco.avail_clusters)*(float)(disco.sectors_per_cluster)*(float)(disco.bytes_per_sector);printf("Tamaño Bytes: %.0f\n",tam);printf("Tamaño Sectores: %d",disco.avail_clusters);getch();}

GETDRIVE: Devuelve el número de la unidad de disco actual del sistema y deja el valor en lavariable int. Ese valor se puede discriminar por medio de un switch o como en elejemplo utilizar directamente un printf. La cabecera <dos.h>.

_dos_getdrive(&var_intera);

VALOR UNIDAD

1 A:

2 B:

3 C:

struct diskfree_t{unsigned total_clusters;unsigned avail_clusters;unsigned sectors_per_cluster;unsigned bytes_per_sector;

}

Page 76: C+1f

Programación II

Ingeniería Electrónica 76

PROGRAMA #6L

#include<stdio.h>#include<conio.h>#include<dos.h>void main(void){

int unidad;clrscr();_dos_getdrive(&unidad);printf("La unidad actual es: %c",unidad+'A'-1);getch();

}

SETDRIVE: La función cambia la unidad de disco actual a la especificada por la variable detipo entero. La función devuelve el número de unidades del sistema en el enteroapuntado por la segunda variable de la función. La cabecera <dos.h>.

_dos_setdrive(var_int_unidad,&var_int_unidades);

PROGRAMA #6M

#include<stdio.h>#include<conio.h>#include<dos.h>void main(void){

unsigned unit;clrscr();_dos_setdrive(3,&unit);printf("Nº unidades: %u",unit);getch();

}

GETCUDIR: Devuelve un entero. La función obtiene el directorio actual de la unidad que sele especifica mediante un entero. Esta función devuelve CERO si todo seproduce correctamente, en caso contrario devuelve uno. La cabecera es <dir.h>.

int getcurdir(int_unidad,cadena);

PROGRAMA #6N

#include<stdio.h>#include<conio.h>#include<dos.h>void main(void){

char *director;clrscr();getcurdir(3,director);printf("Directorio: %s",director);getch();

Page 77: C+1f

Programación II

Ingeniería Electrónica 77

}

FINDFIRST/FINDNEXT: La función findfirst busca el primer nombre de archivo quecoincida con el patrón de búsqueda. El patrón puede contener launidad como el camino donde buscar. Además el patrón puedeincluir los caracteres comodines * y ¿?. Si se encuentra alguno,rellena con información la estructura find_t.int _dos_findfirst(patron,atrib,&etique_find_t);

La función findnext continua la búsqueda que haya comenzadocon findfirst. Devuelve CERO en caso de éxito y un valorDISTINTO DE CERO si no tiene éxito la búsqueda. Cabecera<dos.h>.

int _dos_findnext(&etiqueta_find_t);

ATRIBUTO DESCRIPCIÓN

_A_NORMAL Archivo normal.

_A_RDONLY Archivo sólo lectura

_A_HIDDEN Archivo oculto.

_A_SYSTEM Archivo del sistema.

_A_VOLID Etiqueta de volumen.

_A_SUBDIR Subdirectorio.

_A_ARCH Bit de archivado activado.

PROGRAMA #6O

#include<stdio.h>#include<conio.h>#include<dos.h>void main(void){

struct find_t fiche;int fin;

fin=_dos_findfirst("*.c",_A_NORMAL,&fiche);while(!fin){printf("%s %ld\n",fiche.name,fiche.size);fin=_dos_findnext(&fiche);

}getch();

}

struct find_t{char reserved[21];char attrib;unsigned wr_time;unsigned wr_date;long size;char name[13];}

Page 78: C+1f

Programación II

Ingeniería Electrónica 78

REMOVE: La función elimina el archivo especificado en la variable. Devuelve CERO siconsigue eliminar el fichero, y MENOS UNO si se produce algún error. Lacabecera <stdio.h>.

int remove(variable_cadena);

RENAME: La función cambia el nombre del archivo especificado en primer termino por elnombre de la segunda variable cadena. El nuevo nombre no debe coincidir conninguno que exista en el directorio. Devuelve CERO si tiene éxito y DISTINTO DECERO si se produce algún error. Cabecera <stdio.h>.

int rename(var_nombre_antiguo,var_nombre_nuevo);

PROGRAMA #6P

#include<stdio.h>#include<conio.h>#include<stdlib.h>void main(int argc, char *argv[]){

clrscr();if (argc!=3){printf("Error en los argumentos");exit(0);

}if(remove(argv[1]))printf("El fichero no esta\n");

if(rename(argv[2],"nuevo.txt"))printf("No puedo cambiar nombre\n");

}

MKDIR: Esta función permite crear directorios. El directorio dependerá de aquel donde estemossituados a la hora de crearlo. Devuelve CERO si todo ha ido correctamente yDISTINTO de cero si hay algún error. Cabecera <dir.h>.

int mkdir(variable_cadena);CHDIR: Esta función permite cambiarse de directorio. Hay que indicarle la ruta completa para

poder cambiarse. Devuelve CERO si todo ha ido correctamente y DISTINTO de cerosi hay algún error. Cabecera <dir.h>.

int chdir(variable_cadena);

RMDIR: Esta función permite borrar el directorio que le indiquemos. Las condiciones paraborrar el directorio es que este vacío y estar en el directorio que le precede. DevuelveCERO si todo ha ido correctamente y DISTINTO de cero si hay algún error. Cabecera<dir.h>.

int rmdir(variable_cadena);

SYSTEM: La función pasa la cadena como una orden para el procesador de órdenes del sistemaoperativo. El valor devuelto por system normalmente es CERO si se realiza todo

Page 79: C+1f

Programación II

Ingeniería Electrónica 79

correctamente y DISTINTO de cero en cualquier otro caso. No es muy utilizada, alllamarla perdemos todo el control del programa y lo coge el sistema operativo. Paraprobar esta orden es necesario salir a MS-DOS. La cabecera utilizada es <stdlib.h>.

int system(variable_cadena);

SOUND/NOSOUND: La función sound hace que el altavoz del ordenador comience a pitar conuna frecuencia determinada por la variable. El altavoz seguirá pitando hastaque el programa lea una línea con la función nosound(). Cabecera<dos.h>.

sound(int_frecuencia);

nosound();

PROGRAMA #6Q

#include <stdio.h>#include <conio.h>#include <dir.h>#include <stdlib.h>#include <dos.h>void main(void){

char *directorio;clrscr();printf("Nombre del directorio: ");gets(directorio);if(!mkdir(directorio)) printf("Directorio creado\n");

else{ printf("No se pudo crear directorio\n"); delay(1000); exit(0);

}

getch();system(“dir/p”);getch();if(!rmdir(directorio)) printf("\nDirectorio borrado\n");

else{

printf("\nNo se pudo borrar\n"); delay(1000);

exit(0);}getch();

}

Page 80: C+1f

Programación II

Ingeniería Electrónica 80

3. FUNCIONES GRÁFICAS

Los prototipos de las funciones gráficas y de pantalla se encuentran en GRAPHICS.H. Loprimero que hay que tener en cuenta son los distintos modos de vídeo para el PC. Cuandoutilizamos funciones gráficas hay que iniciar el modo gráfico y esto supone un cambio en lascoordenadas en pantalla y el tamaño.

La parte más pequeña de la pantalla direccionable por el usuario en modo texto es un carácter .En modo gráfico es el pixel. Otro aspecto es que en modo gráfico la esquina superior izquierda en lacoordenada 1,1 y como esquina inferior derecha 24,80. En el modo gráfico la esquina superiorizquierda es 0,0 y la esquina inferior derecha depende del modo de vídeo. Se pude obtener mediantelas funciones getmaxx() y getmaxy().

Para compilar un fichero fuente con funciones gráficas tenemos primero que indicar alcompilador que se va a trabajar con ese tipo de funciones.

OPTIONS LINKER LIBRARIES

LISTA DE COLORES:TEXTO FONDO DEL TEXTO FONDO GRÁFICOVALOR COLOR VALOR COLOR VALOR COLOR0 Negro. 0 Negro. 0 Negro.1 Azul. 1 Azul. 1 Azul.2 Verde. 2 Verde. 2 Verde.3 Cían. 3 Cían. 3 Cían.4 Rojo. 4 Rojo. 4 Rojo.5 Magenta. 5 Magenta. 5 Magenta.6 Marrón. 6 Marrón. 6 Marrón.

7 Gris claro. 7 Gris claro.8 Gris oscuro. 8 Gris oscuro.9 Azul Claro. 9 Azul Claro.10 Verde claro. 10 Verde claro.11 Cían claro 11 Cían claro12 Rojo claro. 12 Rojo claro.13 Magenta claro 13 Magenta claro14 Amarillo. 14 Amarillo.15 Blanco. 15 Blanco.

nº+128 Parpadean.

TEXTCOLOR: Establece el color del texto. No es una función gráfica. La variable que tienecomo parámetro especifica el color, se puede poner una variable o directamenteel nº de color. Se mantiene ese color hasta el momento en que lee otro valor paratextcolor. Cabecera <conio.h>.

textcolor(int color);

Activar la opciónGraphics Library

Page 81: C+1f

Programación II

Ingeniería Electrónica 81

CPRINTF: Tiene la misma función y formato que printf pero mediante esta función el textose muestra con el color especificado en texcolor. Cabecera <conio.h>.

cprintf(“mensaje”);

cprintf(“identificador_formato”,variable);

TEXTBACKGROUND: Establece el color de fondo donde se va mostrando el texto, solo aparececuando hay texto escrito. Se puede utilizar una variable o el valornumérico. Se mantiene hasta que lee otro valor para textbackground.Cabecera <conio.h>.

texbackground(int color);SETCURSORTYPE: Esta función establece el tipo de cursor que se va a ver en pantalla. Se

mantiene hasta el momento en que lee otro valor para en la funciónsetcursortype. Admite tres constantes definidas en el compilador de C.Cabecera <conio.h>.

_setcursortype(constante_tipo_cursor);

CONSTANTES DE CURSOR

CONSTANTE DESCRIPCIÓN

_NOCURSOR No se ve el cursor.

_SOLIDCURSOR Cursor grande.

_NORMALCURSOR Cursor normal.

PROGRAMA #6R

#include <stdio.h>#include <conio.h>#include <dir.h>#include <stdlib.h>#include <dos.h>#include <graphic.h>

void main(void){

char cadena[20]="hola que tal";clrscr();_setcursortype(_NOCURSOR);textbackground(4);

Page 82: C+1f

Programación II

Ingeniería Electrónica 82

textcolor(1);cprintf("%s",cadena);getch();

}

INICIO GRAFICO: Antes de poder utilizar cualquiera de las funciones gráficas hay que iniciar elmodo gráfico. Al iniciar el modo gráfico hay que indicarle cual es el modo devídeo y el directorio donde están las funciones gráficas en C. Para indicar latarjeta y el modo se utilizan variables de tipo entero asignándoles unaconstante llamada DETECT. La cabecera <graphics.h>.

initgraph(&var_tarjeta,&var_modo,”dir_lib_graficas”);

GRAPHRESULT: Una vez iniciado el modo gráfico debemos comprobar que se ha iniciadocorrectamente el modo gráfico para poder utilizar las funciones gráficas sinningún problema. La función devuelve un entero que debemos comparar conla constante grOk, si son iguales el modo gráfico se ha iniciadocorrectamente.

variable_int=graphresult();

CERRAR GRAFICO: Una vez que se ha terminado de trabajar con las funciones gráficas se debecerrar siempre el modo gráfico. Si un programa termina sin cerrar el modográfico el sistema operativo mantendrá el modo gráfico. Cabecera<graphics.h>.

closegraph();

CLEARDEVICE: Esta función borra la pantalla una vez que se ha inicializado el modo gráfico.Si se utiliza la orden clrscr solo se limpiara una parte de la pantalla. Cabecera<graphics.h>.

cleardevice();

SETBKCOLOR: Establece el color de fondo en la pantalla. Hay que indicarle mediantevariable o valor numérico. Cuando se borra la pantalla este no desaparece.Cabecera <graphics.h>.

setbkcolor(int_color);

Nota: Si olvidamos cerrar el modo gráfico yestamos en MS-DOS podemos utilizar laorden mode co80 para restaurar el modotexto en el sistema operativo.

Page 83: C+1f

Programación II

Ingeniería Electrónica 83

PROGRAMA #6S

#include <stdio.h>#include <conio.h>#include <dir.h>#include <stdlib.h>#include <dos.h>#include <graphic.h>void main(void){ int tarjeta= DETECT,modo=DETECT;

int color; clrscr();

initgraph(&tarjeta, &modo, "c:\\tc\\bgi"); if(graphresult()!=grOk) {

printf("Error en el modo grafico");exit(0);

} cleardevice(); for(color=0;color<=15;color++) {

setbkcolor(color);delay(1000);

} closegraph();}

SETCOLOR: Establece el color del borde con el que van a mostrarse los objetos gráficosque se van pintando. Por defecto los objetos aparece con el borde de colorblanco. El valor que tiene la función es un entero. Cabecera <graphics.h>.

setcolor(int_color);

SETFILLSTYLE: Establece el estilo de relleno de los objetos. Hay que indicar el tipo y el color,teniendo en cuenta que el color debe ser igual al que establecemos ensetcolor. Esto simplemente establece el estilo. Cabecera <graphics.h>.

setfillstyle(int_estilo,int_color);

ESTILO DESCRIPCIÓN

1 Sólido 100%

2 Líneas horizontales gruesas.

3 Líneas diagonales finas ///

Page 84: C+1f

Programación II

Ingeniería Electrónica 84

4 Líneas diagonales gruesas ///

5 Líneas diagonales gruesas \\\

6 Líneas diagonales finas \\\

7 Líneas horizontales y verticales cruzadas.

8 Líneas diagonales cruzadas.

9 Líneas diagonales cruzadas muy juntas.

10 Puntos separados.

11 Puntos cercanos.

FLOODFILL: Rellena el objeto que ha sido pintado previamente. Hay que indicarle lasmismas coordenas que tiene el objeto y el color debe ser igual al borde y alestilo de relleno. La cabecera <graphics.h>.

floodfill(int_x,int_y,in_color);

CIRCULO: Dibuja un circulo en una posición indicada mediante las coordenadas x e y,también hay que indicarle un color. Cabecera <graphics.h>.

circle(int_x,int_y,int_color);

RECTANGULO: Dibuja un rectángulo o cuadrado. Se le indica la posición de la esquinasuperior izquierda mediante los valores x1,y1 y la esquina inferior derechamediante los valores de x2,y2. Cabecera <graphics.h>.

rectangle(int_x1,int_y1,int_x2,int_y2);

Page 85: C+1f

Programación II

Ingeniería Electrónica 85

PROGRAMA #6T

#include <stdio.h>#include <conio.h>#include <dir.h>#include <stdlib.h>#include <dos.h>#include <graphic.h>void main(void){int tarjeta= DETECT,modo=DETECT;int color;

initgraph(&tarjeta, &modo, "c:\\tc\\bgi");if(graphresult()!=grOk){

printf("Error en el modo gr fico");exit(0);

}cleardevice();setcolor(3);circle(200,200,90);setcolor(14);circle(500,200,90);setfillstyle(3,14);floodfill(500,200,14);rectangle(300,100,400,300);getch();closegraph();}

ESTILO LINEA: Sirve para establecer el tipo de línea con el que se van a pintar los objetos.Los tipos de línea establecen cinco valores definidos. También hay queespecificar el ancho y la separación. Cabecera <graphics.h>.

setlinestyle(inttipo,int_separacion,int_ancho);

VALOR LINEA DESCRIPCIÓN

0 Continua.

1 Guiones.

2 Guiones largos y cortos.

3 Guiones largos.

4 Puntos.

LINEAS: Dibuja una línea desde la posición donde nos encontramos. Primero debemosposicionarnos en la coordenada de inicio y después llamar a la función dando

Page 86: C+1f

Programación II

Ingeniería Electrónica 86

la coordenada final mediante 2 enteros. En la segunda función directamentese le da el comienzo y el final. Cabecera <graphics.h>.

moveto(x,y);lineto(x,y);

line(x1,y1,x2,y2);

PROGRAMA #6W

#include <stdio.h>#include <conio.h>#include <dir.h>#include <stdlib.h>#include <dos.h>#include <graphic.h>void main(void){int tarjeta= DETECT,modo=DETECT;int color,coord_y,tipo_linea=0;clrscr();

initgraph(&tarjeta, &modo, "c:\\tc\\bgi");if(graphresult()!=grOk){

printf("Error en el modo gráfico");exit(0);

}cleardevice();setcolor(14);moveto(350,150);lineto(350,250);for(coord_y=150;coord_y<=250;coord_y+=25){

setlinestyle(tipo_linea,1,1);line(300,coord_y,400,coord_y);tipo_linea++;

}getch();closegraph();}

ELIPSES: Dibuja una elipse o arco de elipse. Se le indica la posición mediante losvalores x, y. El ángulo inicial (que es cero si es una elipse) y el ángulo final(que es 360 si es una elipse). Hay que indicarle el radio para x y el radio paray. Cabecera <graphics.h>.

ellipse(x,y,ang_inicio,ang_fin,radio_x,radio_y);

ARCOS: Dibuja un arco. hay que indicarle la posición, el ángulo inicial y el final y elradio que tiene dicho arco. Todos sus valores son enteros. Cabecera<graphics.h>.

arc(x,y,ang_inicial,ang_final,radio);

Page 87: C+1f

Programación II

Ingeniería Electrónica 87

PUNTOS: Pintan un punto en una coordenada determinada con un color establecido.Hay que indicarle las coordenadas y el color mediante variables o valoresenteros. Se pude pintar puntos aleatoriamente. Cabecera <graphics.h>.

putpixel(int_x,int_y,int_color);

PROGRAMA #6X

#include <stdio.h>#include <conio.h>#include <dir.h>#include <stdlib.h>#include <dos.h>#include <graphic.h>void main(void){int tarjeta= DETECT,modo=DETECT;clrscr();initgraph(&tarjeta, &modo, "c:\\tc\\bgi");if(graphresult()!=grOk){

printf("Error en el modo gr fico");exit(0);

}cleardevice();setcolor(2);ellipse(400,200,0,360,90,40);setcolor(15);arc(310,200,0,45,90);setcolor(11);line(490,200,470,350);line(310,200,330,350);setcolor(14);ellipse(400,350,180,360,70,25);getch();closegraph();}

SETTEXTSTYLE: Establece el estilo de letra que se va a utilizar en modo gráfico. Hay queindicarle mediante valores enteros el tipo, la dirección y el tamaño que tienela letra. El color se establece con la función setcolor. Cabecera<graphics.h>.

settextstyle(int_tipo,const_direccion,int_tamaño);

Page 88: C+1f

Programación II

Ingeniería Electrónica 88

TIPO DE LETRAS DIRECCIÓN DEL TEXTO

VALOR DESCRIPCIÓN CONST. DESCRIPCIÓN

0 A B C HORIZ_DIR En Horizontal.

1 A B C VERT_DIR En Vertical.

2 A B C

3 A B C

4 ABC

5 A B C

6 A B C

7 A B C

8 A B C

9 A B C (tamaño grande).

10 A B C (tamaño grande)

11 ABC

ALINEAR TEXTO: La función settextjustify() alineara el texto con respecto a lascoordenadas donde se muestra el texto. Lo hace en horizontal y en vertical.Cabecera <graphics.h>.

settextjustify(const_horizontal,const_vertical);

HORIZONTAL VERTICAL

CONST. DESCRIPCIÓN CONST. DESCRIPCIÓN

LEFT_TEXT Alineación izquierda. TOP_TEXT Alineación superior.

CENTER_TEXT Alineación centrada. CENTER_TEXT Alineación centrada.

RIGHT_TEXT Alineación derecha. BOTTOM_TEXT Alineación inferior.

VER TEXTO: La función outtextxy(), muestra el texto de una cadena o el contenidode una variable utilizando el modo gráfico. Hay que indicarle la posiciónmediante dos valores enteros y a continuación la variable o cadena entrecomillas. Cabecera <graphics.h>.

outtextxy(x,y,variable_cadena);outtextxy(x,y,”textto);

Page 89: C+1f

Programación II

Ingeniería Electrónica 89

PROGRAMA #6Y

#include <stdio.h>#include <conio.h>#include <dir.h>#include <stdlib.h>#include <dos.h>#include <graphic.h>void main(void){int tarjeta= DETECT,modo=DETECT;int tipo=0;clrscr();initgraph(&tarjeta, &modo, "c:\\tc\\bgi");if(graphresult()!=grOk){

printf("Error en el modo gráfico");exit(0);

}cleardevice();for(tipo=0;tipo<=11;tipo++){

settextstyle(tipo,HORIZ_DIR,5);outtextxy(200,200,"ABC");delay(1000);cleardevice();

}closegraph();}

COPIAR IMAGEN: Existen tres funciones gráficas relacionadas entre si, que permiten copiar ymover objetos gráficos por la pantalla. Las tres tienen la cabecera <graphics.c>. Deben estarsiempre las tres para funcionar. El modo de trabajo es: copiar una zona de la pantalla a la memoria(utilizando un puntero), asignar la memoria necesaria y, mostrar la imagen.

GETIMAGE: Copia el contenido del rectángulo definido por las cuatro coordenadas (tipoint) y lo guarda en memoria mediante un puntero. Cabecera <graphics.h>.

getimage(x1,y1,x2,y2,puntero);

IMAGESIZE: Devuelve el tamaño en bytes necesarios para contener la región especificadaen el rectángulo de la orden getimage(). Cabecera <graphics.h>.

variable=imagesize(x1,y1,x2,y2);

PUTIMAGE: Muestra en pantalla una imagen obtenida por getimage(). El puntero es quiencontiene la imagen y la sitúa en la posición dada por x,y. El modo en que semuestra esta definido por 5 constantes. Cabecera <graphics.h>.

putimage(x,y,puntero,modo);

CONST. VALOR DESCRIPCIÓN

COPY_CUT 0 Copia la imagen.

Page 90: C+1f

Programación II

Ingeniería Electrónica 90

XOR_PUT 1 Borra la imagen anterior.

OR_PUT 2 Mezcla las imágenes.

AND_PUT 3 Muestra encima de la anterior.

NOT_PUT 4 Copia en color inverso.

PROGRAMA #6Z

#include <stdio.h>#include <conio.h>#include <dir.h>#include <stdlib.h>#include <dos.h>#include <graphic.h>void main(void){

int tarjeta=DETECT,modo=DETECT,fil,col;long tam;char *imagen;

initgraph(&tarjeta,&modo,"c:\\tc\\bgi");if(graphresult()!=grOk){printf("Error en modo grafico");exit(0);

}cleardevice();

circle(100,100,40);tam=imagesize(50,50,150,150);imagen=malloc(tam);getimage(50,50,150,150,imagen);cleardevice();while(!kbhit()){

delay(400);putimage(col,fil,imagen,XOR_PUT);

delay(400);putimage(col,fil,imagen,XOR_PUT);

col=random(getmaxx());fil=random(getmaxy());

}closegraph();

}

Page 91: C+1f

Programación II

Ingeniería Electrónica 91

4. PROYECTOS

Procedimiento con el que se compilan de forma independiente distintas partes de un programay luego se enlazan para formar el programa ejecutable final. Se utiliza con aplicaciones muygrandes. Los proyectos tienen la extensión PRJ. Solo se genera un ejecutable, los ficheros fuentegeneran ficheros OBJ.

Lo primero es crear el proyecto (que es el que va a contener los ficheros fuente). El proyecto vaa tener la extensión PRJ. El modo de crearlo es:

MENU PROJECT OPCION OPEN PROJECT Asignar un nombreal proyecto.

Lo siguiente es crear cada uno de los ficheros fuente que van a componer el proyecto. Lacreación de los ficheros es como siempre, no hay nada de particular. Cuando tengamos los ficheroshay que añadirlos al proyecto. El modo de hacerlo.

Seleccionar la ventana del proyecto (ventana inferior de color gris).

MENU PROJECT OPCION ADD ITEM

Cuando se tengan todos seleccionados se pulsa el botón DONE.

El siguiente paso es COMPILAR CADA UNO DE LOS FICHEROS FUENTE. Para hacerlohay que seleccionar primero el fichero y luego pulsar ALT+F9. Así con todos los ficheros.Posteriormente se tiene que linkar el proyecto.

MENU COMPILE OPCION LINK.Cuando se termine con el proyecto hay que cerrarlo.

MENU PROJECT OPCION CLOSE.

EJEMPLO: En este proyecto hay dos ficheros fuente. En el primero se muestra 2 valores yse hace la llamada a funciones del segundo programa.

Ir seleccionando cadauno de los ficheros queforman el proyecto

Page 92: C+1f

Programación II

Ingeniería Electrónica 92

Fichero: UNO.C Fichero:DOS.C

#include <stdio.h>#include <conio.h>

void mostrar();void sumar();

void main(void){int x,y;clrscr();x=10;y=20;printf("%d %d",x,y);getch();mostrar();sumar();getch();}

#include<stdio.h>#include<conio.h>

void sumar(){int x,y;printf("%d",x+y);getch();}

void mostrar(){int z,p;z=15;p=25;printf("%d %d",z,p);getch();}

Page 93: C+1f

Programación II

Ingeniería Electrónica 93

El puerto paralelo de la PC

PRECAUCION: Conectar dispositivos al puerto paralelo implica el riesgo de daños permanentes ala tarjeta madre de la PC, tenga siempre presente que aún los profesionales cometen errores, por lotanto no está de más recomendarle extremo cuidado al trabajar en el puerto paralelo..

Los puertos de comunicación de la PC son de particular interés para el estudioso de laelectrónica ya que le permiten utilizar una computadora personal para controlar todo tipo circuitoselectrónicos utilizados, principalmente, en actividades de automatización de procesos, adquicisiónde datos, tareas repetitivas y otras actividades que demandan precisión. Éste artículo es el primerode una serie que analizará diversos usos para el puerto paralelo de la PC.

Conceptos básicos

Existen dos métodos básicos para transmisión de datos en las computadoras modernas. En unesquema de transmisión de datos en serie un dispositivo envía datos a otro a razón de un bit a la veza través de un cable. Por otro lado, en un esquema de transmisión de datos en paralelo undispositivo envía datos a otro a una tasa de n número de bits a través de n número de cables a untiempo. Sería fácil pensar que un sistema en paralelo es n veces más rápido que un sistema en serie,sin embargo ésto no se cumple, básicamente el impedimiento principal es el tipo de cable que seutiliza para interconectar los equipos. Si bién un sistema de comunicación en paralelo puede utilizarcualquier número de cables para transmitir datos, la mayoría de los sistemas paralelos utilizan ocholíneas de datos para transmitir un byte a la vez, como en todo, existen excepciones, por ejemplo elestándar SCSI permite transferencia de datos en esquemas que van desde los ocho bits y hasta lostreinta y dos bits en paralelo. En éste artículo nos concentraremos en transferencias de ocho bits yaque ésta es la configuración del puerto paralelo de una PC.Un típico sistema de comunicación en paralelo puede ser de una dirección (unidireccional) o de dosdirecciones (bidireccional). El más simple mecanismo utilizado en un puerto paralelo de una PC esde tipo unidireccional y es el que analizaremos en primer lugar. Distinguimos dos elementos: laparte transmisora y la parte receptora. La parte transmisora coloca la información en las líneas dedatos e informa a la parte receptora que la información (los datos) están disponibles; entonces laparte receptora lee la información en las líneas de datos e informa a la parte transmisora que hatomado la información (los datos). Observe que ámbas partes sincronizan su respectivo acceso a laslíneas de datos, la parte receptora no leerá las líneas de datos hasta que la parte transmisora se loindique en tanto que la parte transmisora no colocará nueva información en las líneas de datos hastaque la parte receptora remueva la información y le indique a la parte transmisora que ya ha tomadolos datos, a ésta coordinación de operaciones se le llama acuerdo ó entendimiento. Bién, en éstosámbitos tecnológicos es recomendable utilizar ciertas palabras en inglés que nos permitenirónicamente un mejor entendimiento de los conceptos tratados. Repito: a la coordinación deoperaciones entre la parte transmisora y la parte receptora se le llama handshaking, que en españoles el acto con el cual dos partes manifiestan estar de acuerdo, es decir, se dan un apretón de manos.

Page 94: C+1f

Programación II

Ingeniería Electrónica 94

El handshakingPara implementar el handshaking se requieren dos líneas adicionales. La línea de estroboscopio

(en inglés strobe) es la que utiliza la parte transmisora para indicarle a la parte receptora ladisponibilidad de información. La línea de admisión (acknowledge) es la que utiliza la partereceptora para indicarle a la parte transmisora que ha tomado la información (los datos) y que estálista para recibir más datos. El puerto paralelo provee de una tercera línea de handshaking llamadaen inglés busy (ocupado), ésta la puede utilizar la parte receptora para indicarle a la partetransmisora que está ocupada y por lo tanto la parte transmisora no debe intentar colocar nuevainformación en las líneas de datos. Una típica sesión de transmisión de datos se parece a losiguiente:

Parte transmisora:

La parte transmisora checa la línea busy para ver si la parte receptora está ocupada. Si lalínea busy está activa, la parte transmisora espera en un bucle hasta que la línea busy estéinactiva.

La parte transmisora coloca la información en las líneas de datos. La parte transmisora activa la línea de strobe. La parte transmisora espera en un bucle hasta que la línea acknowledge está activa. La parte transmisora inactiva la línea de strobe. La parte transmisora espera en un bucle hasta que la línea acknowledge esté inactiva. La parte transmisora repite los pasos anteriores por cada byte a ser transmitido.

Parte receptora:

La parte receptora inactiva la línea busy (asumiendo que está lista para recibirinformación).

La parte receptora espera en un bucle hasta que la línea strobe esté activa. La parte receptora lee la información de las líneas de datos (y si es necesario, procesa los

datos). La parte receptora activa la línea acknowledge. La parte receptora espera en un bucle hasta que esté inactiva la línea de strobe. La parte receptora inactiva la línea acknowledge. La parte receptora repite los pasos anteriores por cada byte que debe recibir.

Se debe ser muy cuidadoso al seguir éstos pasos, tanto la parte transmisora como la receptoracoordinan sus acciones de tal manera que la parte transmisora no intentará colocar varios bytes enlas líneas de datos, en tanto que la parte receptora no debe leer más datos que los que le envíe laparte transmisora, un byte a la vez.

El hardware del puerto paraleloEl puerto paralelo de una típica PC utiliza un conector hembra de tipo D de 25 patitas (DB-25 S),

éste es el caso más común, sin embargo es conveniente mencionar los tres tipos de conectoresdefinidos por el estándar IEEE 1284, el primero, llamado 1284 tipo A es un conector hembra de 25

Page 95: C+1f

Programación II

Ingeniería Electrónica 95

patitas de tipo D, es decir, el que mencionamos al principio. El orden de las patitas del conector eséste:

El segundo conector se llama 1284 tipo B que es un conector de 36 patitas de tipo centronics y loencontramos en la mayoría de las impresoras; el tercero se denomina 1284 tipo C, se trata de unconector similar al 1284 tipo B pero más pequeño, además se dice que tiene mejores propiedadeseléctricas y mecánicas, éste conector es el recomendado para nuevos diseños. La siguiente tabladescribe la función de cada patita del conector 1284 tipo A:

Patita E/S Polaridad activa Descripción

1 Salida 0 Strobe

2 ~ 9 Salida -Líneas de datos

(bit 0/patita 2, bit 7/patita 9)

10 Entrada 0Línea acknowledge

(activa cuando el sistema remoto toma datos)

11 Entrada 0Línea busy

(si está activa, el sistema remoto no acepta datos)

12 Entrada 1Línea Falta de papel

(si está activa, falta papel en la impresora)

13 Entrada 1Línea Select

(si está activa, la impresora se ha seleccionado)

14 Salida 0Línea Autofeed

(si está activa, la impresora inserta una nuevalínea por cada retorno de carro)

15 Entrada 0Línea Error

(si está activa, hay un error en la impresora)

16 Salida 0

Línea Init(Si se mantiene activa por al menos 50

micro-segundos, ésta señalautoinicializa la impresora)

17 Salida 0Línea Select input

(Cuando está inactiva, obliga a laimpresora a salir de línea)

18 ~ 25 - - Tierra eléctrica

Tabla 1: Configuración del puerto paralelo estándar

Page 96: C+1f

Programación II

Ingeniería Electrónica 96

Observe que el puerto paralelo tiene 12 líneas de salida (8 líneas de datos, strobe, autofeed, init,y select input) y 5 de entrada (acknowledge, busy, falta de papel, select y error). El estándar IEEE1284 define cinco modos de operación:

1. Modo compatible2. Modo nibble3. Modo byte4. Modo EPP, puerto paralelo ampliado5. Modo ECP, puerto de capacidad extendida

El objetivo del estándar es diseñar nuevos dispositivos que sean totalmente compatibles con elpuerto paralelo estándar (SPP) definido originalmente por la IBM (en éste artículo trataré solamenteel modo compatible). Hay tres direcciones de E/S asociadas con un puerto paralelo de la PC, éstasdirecciones pertenecen al registro de datos, el registro de estado y el registro de control. El registrode datos es un puerto de lectura-escritura de ocho bits. Leer el registro de datos (en la modalidadunidireccional) retorna el último valor escrito en el registro de datos. Los registros de control yestado proveen la interface a las otras líneas de E/S. La distribución de las diferentes señales paracada uno de los tres registros de un puerto paralelo esta dada en las siguientes tablas:

Dirección Nombre Lectura/Escritura Bit # Propiedades

Bit 7 Dato 7

Bit 6 Dato 6

Bit 5 Dato 5

Bit 4 Dato 4

Bit 3 Dato 3

Bit 2 Dato 2

Bit 1 Dato 1

Base + 0 Puerto de datos Escritura

Bit 0 Dato 0

Tabla 2: Registro de datos

Dirección Nombre Lectura/Escritura Bit # Propiedades

Bit 7 Busy

Bit 6 Acknowledge

Bit 5 Falta de papel

Bit 4 Select In

Bit 3 Error

Bit 2 IRQ (Not)

Bit 1 Reservado

Base + 1 Puerto de estado Sólo Lectura

Bit 0 Reservado

Tabla 3: Registro de estado

Page 97: C+1f

Programación II

Ingeniería Electrónica 97

Dirección Nombre Lectura/Escritura Bit # Propiedades

Bit 7 No usado

Bit 6 No usado

Bit 5Permite puertobidireccional

Bit 4

Permite IRQ através de la

líneaacknowledge

Bit 3Seleccionaimpresora

Bit 2Inicializaimpresora

Bit 1Nueva líneaautomática

Base + 2 Puerto de control Lectura/Escritura

Bit 0 Strobe

Tabla 4: Registro de control

Una PC soporta hasta tres puertos paralelo separados, por tanto puede haber hasta tres juegos deregistros en un sistema en un momento dado. Existen tres direcciones base para el puerto paraleloasociadas con tres posibles puertos paralelo: 0x3BCh, 0x378h y 0x278h, nos referimos a éstas comolas direcciones base para el puerto LPT1, LPT2 y LPT3, respectivamente. El registro de datos selocaliza siempre en la dirección base de un puerto paralelo, el registro de estado aparece en ladirección base + 1, y el registro de control aparece en la dirección base + 2. Por ejemplo, para unpuerto LPT2 localizado en 0x378h, ésta es la dirección del registro de datos, al registro de estado lecorresponde la dirección 0x379h y su respectivo registro de control está en la dirección 0x37Ah.Cuando la PC se enciende el BIOS ejecuta una rutina para determinar el número de puertospresentes en el sistema asignando la etiqueta LPT1 al primer puerto localizado, si existen máspuertos entonces se asignarán consecutivamente las etiquetas LPT2 y LPT3 de acuerdo a lasiguiente tabla:

Dirección inicial Función

0000:0408 Dirección base para LPT1

0000:040A Dirección base para LPT2

0000:040C Dirección base para LPT3

0000:040E Dirección base para LPT4

Tabla 5: Direcciones base en el BIOS

Para trabajar con el puerto paralelo necesitamos en primer lugar conocer la dirección baseasignada por el BIOS (estamos hablando de una PC compatible con IBM), podemos utilizar unprograma llamado Debug.exe que nos indique la(s) dirección(es) asignada(s): en la plataformaWindows vamos al menú inicio, seleccionamos programas y luego MS-DOS para abrir una ventanade Símbolo de MS-DOS y aquí podemos introducir los comandos indicados más abajo. Si se trabaja

Page 98: C+1f

Programación II

Ingeniería Electrónica 98

en ambiente DOS basta con teclear en la línea de comandos la palabra debug, el programa respondecolocando un signo de menos - en donde tecleamos sin dejar espacios en blanco d040:08L8 ypresionamos la tecla entrar, entonces el programa debug.exe nos indica en una serie de númerosla(s) dirección(es) para el (los) puerto(s) paralelo(s) disponibles en nuestro sistema, la siguienteimagen muestra el resultado obtenido como ejemplo:

Se puede observar una serie de números de dos dígitos (ocho en total), se trata del volcado dememoria que empieza en la dirección 40:0008h. Los primeros seis pares de números representn lasdirecciones base para los puertos paralelo instalados, en la imagen de arriba se aprecia que el únicopuerto paralelo de mi máquina está en la dirección 0x378h (78 03). Los números están invertidosporque Intel almacena tal información en un formato de "byte de bajo orden - byte de alto orden".Una vez que obtenemos la información deseada cerramos el programa Debug.exe simplementetecleando la letra q y presionando la tecla entrar. Para cerrar la ventana de Símbolo de MS-DOStecleamos la palabra exit y presionamos la tecla entrar.

Por supuesto, también podemos conocer la dirección asignada al puerto paralelo utilizando unprograma, faltaba más, el código es el siguiente:

Page 99: C+1f

Programación II

Ingeniería Electrónica 99

PROGRAMA #7A

Descripción: Determina la direccion del puerto paralelo

#include <stdio.h>#include <dos.h>

int main(){ unsigned int __far *puntero_a_direccion; int i;

puntero_a_direccion=(unsigned int __far *)0x00000408;

for (i=0; i<3; i++) { if (*puntero_a_direccion == 0) printf("No se encontro puerto asignado a LPT%d \n", i+1); else printf("La direccion asignada a LPT%d es 0x%Xh\n", i+1, *puntero_a_direccion); puntero_a_direccion++; }

return 0;}

El programa es muy sencillo, necesitamos un puntero que señale a la ubicación de memoria quealmacena la información para las diferentes direcciones asignadas al puerto paralelo, lo llamamospuntero_a_direccion, éste puntero debe ser de al menos dos bytes, por ésta razón se declara como detipo unsigned int __far. Es importante que Usted verifique en la documentación de su compilador lamanera precisa para utilizar la palabra clave far, ésta puede ser simplemente la palabra como tal óbién puede llevar uno (_far) o dos guiones bajos (__far), asegúrese de utilizar la forma correcta ó elprograma no funcionará. Creo que con lo explicado arriba el funcionamiento del programapuerto1.c no presenta problema alguno.

Interfaz para el puerto paraleloActualmente, la mayoría de los puertos instalados en las computadoras son de tipo multimodal

configurables a través del BIOS de la máquina, en éste artículo me refiero expresamente al modoNormal (SPP), además de éste están las opciones Bidireccional, EPP versión 1.7, EPP versión 1.9 yECP principalmente. El modo de operación Normal es el más elemental y solamente permite laescritura en las líneas de datos, patitas 2 a la 9 del conector DB-25 del puerto paralelo de la PC.

Eléctricamente, el puerto paralelo entrega señales TTL y como tal, teoricamente, se le puedeconectar cualquier dispositivo que cumpla con los niveles de voltaje específicos de la lógica TTL,sin embargo el hardware del puerto paralelo está muy limitado en cuanto a su capacidad de manejode corriente, por ésta razón se debe ser muy cuidadoso con el manejo de las señales del puerto, uncorto circuito puede dañar permanentemente la tarjeta madre de la PC. Para disminuir lo másposible el riesgo de daños al puerto utilizamos un circuito integrado 74LS244 como etapaseparadora y al mismo tiempo mejoramos la capacidad de manejo de corriente, de esta forma

Page 100: C+1f

Programación II

Ingeniería Electrónica 100

podemos conectar una serie de diodos emisores de luz (LED) que nos indiquen la actividad en laslíneas de datos del puerto paralelo. El circuito se detalla en el siguiente diagrama:

Por cada línea de entrada que tomamos directamente del puerto paralelo existe una etapaamplificadora-separadora dentro del circuito integrado 74LS244 que nos permite trabajar con unatasa de entrega de corriente suficiente para desplegar en los diodos emisores de luz la informaciónescrita en las líneas de datos del puerto. Además es posible habilitar ó deshabilitar el despliegue delnibble de orden inferior ó superior del byte escrito en el puerto. Colocando en un nivel lógico alto lapatita 1 del CI 74LS244 inhabilitamos el despliegue del nibble de orden bajo, un nivel lógico alto enla patita 19 evita el despliegue del nibble de orden alto. Para comodidad, conecto las patitas 1 y 19permanentemente a tierra de tal manera que sea posible visualizar la actividad en los diodosemisores de luz (LED). En el diagrama se especifican con números las correspondientes patitas delconector DB-25. Obviamente se requiere de una fuente regulada de 5 Voltios para operar éstecircuito, además los siguientes materiales:

1. Circuito Integrado TTL 74LS244. 8. Diodos Emisores de Luz. 8. Resistencias de 220 Ohms, 1/2 Watt. 1. Cable y conector para el puerto paralelo.

Naturalmente lo más recomendable es probar el correcto funcionamiento del circuito antes deconectarlo al puerto paralelo de la PC. Ensamble el circuito, preferentemente en un circuitoimpreso, y conéctelo a una fuente regulada de 5 Voltios, conecte temporalmente un extremo de una

Page 101: C+1f

Programación II

Ingeniería Electrónica 101

resistencia de 10,000 Ohms a una línea de entrada, el resto de las líneas de entrada conéctelas atierra. El otro extremo de la resistencia conéctelo directamente al borne positivo de la fuente dealimentación para inducir una señal TTL alta, el respectivo LED debe encender. Con un trozo dealambre conectado a Tierra, toque temporalemente el extremo de la resistencia que está conectado ala línea de entrada para inducir una señal TTL de lógica baja, el LED se debe apagar. Repita éstaoperación para cada una de las ocho líneas de entrada. Una vez que ha verificado el correctofuncionamiento del circuito está listo para conectarlo al puerto paralelo de la PC.

En primer lugar apague la computadora y el circuito. Conecte el cable al puerto paraleloasegurándose que el conector esté firme en su sitio. Encienda el circuito y por último encienda lacomputadora, por regla general, el circuito de restablecimiento de la computadora colocainicialmente en las líneas de datos del puerto paralelo un valor igual a 0x0h, por lo tanto todos losdiodos deben estar apagados una vez que la computadora ha terminado su proceso de arranque, sinembargo, si algún diodo permanece encendido ésto no indica una condición de falla, esresponsabilidad del software que Usted escriba para controlar el puerto inicializarlo con un valoradecuado antes de realizar cualquier otra operación.

Escribiendo datos al puerto paraleloCon ocho bits podemos escribir en el puerto un total de 256 valores diferentes, cada uno de éstos

representa un byte de información y cada byte puede representar una acción concreta que nosotrospodemos definir de acuerdo a nuestras necesidades. En éste artículo el objetivo es entender cómotrabajar con el puerto paralelo, por lo tanto hagamos un programa que nos permita escribir unnúmero cualquiera entre 0 y 255 de tal manera que sea posible visualizar el valor en formatobinario. En primer lugar consulte la documentación de su compilador para verificar la correctasintáxis de la función que nos sirve para escribir en el puerto, en el caso específico de SymantecC++, dicha función es outp( ). Ésta función requiere dos parámetros, el primero de tipo unsigned intque especifica la dirección del puerto paralelo, y el segundo de tipo char que especifica el valor aescribir en las líneas de datos de puerto. Una típica llamada a la función outp( ) se parece a ésto:

outp(0x378, 65);

Se aprecia la facilidad de manejo de la función, aunque diferentes compiladores dan a susrespectivas funciones nombres diferentes, la mecánica es la misma, se requieren dos parámetros, ladirección del puerto y el valor a escribir en el puerto. Estudie el siguiente código:

PROGRAMA #7B

Descripción: Escribe datos al puerto paralelo de la PC

#include <stdio.h>#include <dos.h>

int puerto(int direcc);int seleccion;

int main(){

Page 102: C+1f

Programación II

Ingeniería Electrónica 102

unsigned int __far *puntero_a_direccion; int i, direccion[3]={0,0,0}, disponible[3]={0,0,0};

puntero_a_direccion = (unsigned int __far *)0x00000408;

printf("Seleccione el puerto:\n"); /* ¿Cuantos puertos existen? */ for (i=0; i<3; i++) { if (*puntero_a_direccion == 0) printf("Puerto LPT%d...............no disponible\n", i+1); else { disponible[i] = 1; direccion[i] = *puntero_a_direccion; printf("Puerto LPT%d...............%d\n", i+1, i+1); }

puntero_a_direccion++; } printf("Salir del programa........0\n"); scanf("%d", &seleccion);

do { switch(seleccion) { case 0:/* Salir del programa */ printf("Adios!!!\n"); return 0;

break;

case 1:/* Puerto LPT1 */ if(disponible[0]==1) puerto(direccion[0]); else { printf("ERROR: PUERTO NO DISPONIBLE\n"); return 0; }

break;

case 2:/* Puerto LPT2 */ if(disponible[1]==1) puerto(direccion[1]); else { printf("ERROR: PUERTO NO DISPONIBLE\n"); return 0; }

break;

case 3:/* Puerto LPT3 */ if(disponible[2]==1) puerto(direccion[2]); else {

Page 103: C+1f

Programación II

Ingeniería Electrónica 103

printf("ERROR: PUERTO NO DISPONIBLE\n"); return 0; } break;

default: printf("ERROR: OPCION INCORRECTA!\n"); break; } if(seleccion!=0) { printf("Seleccione otra opcion\n"); scanf("%d", &seleccion); } } while(seleccion!=0);

return 0;}

int puerto(int direcc){ unsigned char valor; /* Solo valores entre 0 y 255 */

printf("Ahora puede escribir cualquier valor\n"); printf("entre 1 y 255, 0 para terminar el programa\n"); do { printf("Valor al puerto?\n"); scanf("%d", &valor); outp(direcc, valor); printf("Se ha escrito %d al puerto\n", valor); } while(valor!=0);

return seleccion=0;}

El programa determina el número de puertos paralelo, instalados en la computadora y almacenasus respectivas direcciones en el arreglo llamado direccion[i], en caso de encontrarse una direcciónválida además se establece en 1 el valor del arreglo llamado disponible[i] simplemente como unamedida de seguridad adicional. Como resultado de éstas acciones el programa despliega un menúbasado en los puertos encontrados, en este punto Usted puede seleccionar, en caso de que dispongade más de un puerto, el puerto en donde está conectado el circuito mostrado en el diagrama dearriba.

Una vez seleccionado el puerto Usted puede escribir un valor cualquiera comprendido entre 0 y255. Independientemente del puerto seleccionado toda la funcionalidad del programa estáencapsulada en la función de tipo int llamada puerto( ) a la cual se le pasa un único parámetro quees la dirección del puerto seleccionado. La función está codificada de tal forma que al escribir un 0el programa termina, de ésta manera al cerrar el programa las líneas de datos del puerto paraleloestán todas en un nivel lógico bajo. Éste programa y el circuito asociado son útiles para entender deforma visual la forma de representar valores en formato binario, además establece las bases detrabajo para otros proyectos de control basados en computadora.

Page 104: C+1f

Programación II

Ingeniería Electrónica 104

PROGRAMA #7C

Descripción: Mediante las flechas se puede hacer una cuenta desde 0 hasta 255

#include <dos.h>#include <stdio.h>#include <conio.h>int b,lum;int c;int a;main(){clrscr();outport(888,0);gotoxy(2,3), printf("PRESIONE FLECHA ARRIBA - FLECHA ABAJO PARAcontar hacia Arriba o hacia Abajo");gotoxy(30,5), printf("PRESIONE ESC PARA SALIR");ret:b= getch ();if(b=='\x0') { b= getch (); if(b==72) { a++; } if(b==80) { a--; } if(a==-1) { a=255; } if(a==256)

{ a=0; } gotoxy(35,15), printf("VALOR DEL PUERTO %i ",a); outport(888,a); lum=(a*100)/255; gotoxy(30,12),printf("INTENSIDAD: %i% ", lum);

goto ret; }if(b==27) { outport(888,0);

return 0; }getch();}

* Nota: El circuito se conecta desde la patita 2 hasta la patita 9 a tierra con unos led´s

Page 105: C+1f

Programación II

Ingeniería Electrónica 105

Uniendo - 16 Carácter x 2 Línea LCDEsta interfase es un ejemplo de otra forma de usar el puerto paralelo. Empezaremos con

algo simple. Este ejemplo no usa el rasgo Bidireccional encontrado en los más nuevos puertos, asídebe funcionar con la mayoría, si ningún Puerto todo Paralelo. No muestra el uso del Puerto deEstado sin embargo como una entrada. ¿Así que qué nosotros estamos uniendo? Un Carácter 16 x 2Línea el Módulo de LCD al Puerto Paralelo. Estos Módulos de LCD son muy comúnes estos días, yes bastante simple trabajar con ellos.

Circuito

Descripción del circuito El tablero de LCD Habilite y Registre Seleccione se conecta al Puerto del Mando. El Puerto delMando es un colector abierto / el rendimiento del desagüe abierto. Mientras la mayoría de losPuertos Paralelos tienen las resistencias pull-up interiores, hay unos qué no hace. Por consiguienteincorporando dos resistencias de 10K, el circuito es más portátil para un rango más ancho decomputadoras algunos de los cuales no pueden tener ningún problema en las resistencias.

Nosotros no hacemos ningún esfuerzo para poner los Datos vaya en el bus de datos en la direccióninversa. Por consiguiente los R/W linean del tablero de LCD, en escriba el modo. Esto causará queningún bus de datos choca en las líneas de los datos. Como resultado nosotros no podemos leer laBandera Ocupada interior del LCD que nos dice atrás si el LCD ha aceptado y el proceso acabado laúltima instrucción. Este problema se supera insertando los retrasos conocidos en nuestro programa.

Page 106: C+1f

Programación II

Ingeniería Electrónica 106

El potenciometro de 10k controla el contraste del tablero de LCD. Nada imagina aquí. Como contodos los ejemplos, yo he omitido el suministro de poder. Usted puede usar una alimentación de 5vo puede usar un onboard +5 regulador. Recuerde unos condensadores de de-coupling, sobre todo siusted tiene el problema con el circuito que trabaja propiamente.

La 2 línea x 16 carácter los módulos de LCD están disponibles de una gama amplia de fabricantesy si todos deben ser compatibles con el HD44780.

Programando - el Código de la Fuente

PROGRAMA #7D

#include <stdio.h>#include <conio.h>#include <dos.h>#include <string.h>

#define PORTADDRESS 0x378 /* Enter Your Port Address Here */

#define DATA PORTADDRESS+0#define STATUS PORTADDRESS+1#define CONTROL PORTADDRESS+2

void main(void){ char string[] = {"Testing 1,2,3""It'Works!"};

char init[10]; int count; int len; init[0] = 0x0F; /* Init Display */ init[1] = 0x01; /* Clear Display */ init[2] = 0x38; /* Dual Line / 8 Bits */

outportb(CONTROL, inportb(CONTROL) & 0xDF); /* Reset Control Port - Makesure Forward Direction */

outportb(CONTROL, inportb(CONTROL) | 0x08); /* Set Select Printer(Register Select) */

for (count = 0; count <= 2; count++) { outportb(DATA, init[count]); outportb(CONTROL,inportb(CONTROL) | 0x01); /* Set Strobe (Enable)*/ delay(20); /* Larger Delay for INIT */ outportb(CONTROL,inportb(CONTROL) & 0xFE); /* Reset Strobe (Enable)*/ delay(20); /* Larger Delay for INIT */ }

outportb(CONTROL, inportb(CONTROL) & 0xF7); /* Reset Select Printer(Register Select) */

Page 107: C+1f

Programación II

Ingeniería Electrónica 107

len = strlen(string);

for (count = 0; count < len; count++) { outportb(DATA, string[count]); outportb(CONTROL,inportb(CONTROL) | 0x01); /* Set Strobe */ delay(2); outportb(CONTROL,inportb(CONTROL) & 0xFE); /* Reset Strobe */

delay(2); }}

Anteriormente es el código de la fuente para conseguir este funcionamiento del ejemplo. Se esescrito para el C de Borland, para que si usted está usando a un recopilador de Microsoft, entoncesusted tendrá que cambiar el outportb () la función al outp () e inportb () al inp ().

El tablero de LCD exige a unas instrucciones ser enviado, pedir encender el despliegue einicializarlo. Esto es lo que la primera para la vuelta hace. Estas instrucciones deben enviarse alRegistro de la Instrucción del LCD que se controla por el Registro Seleccione (Pin 4). Cuando fija 4es bajo el registro de la instrucción se selecciona, así cuando alto el registro de los datos debeseleccionarse. Nosotros conectamos esto a la impresa Selecta del Puerto Paralelo linea qué pasapara ser hardware invertido. Por consiguiente si nosotros escribimos un 1' a pedazo 3 del Registrodel Mando la línea de la impresión Selecta va baja.

Nosotros queremos enviar las instrucciones primero al módulo de LCD. Por consiguiente elRegistro la línea Selecta debe ser baja. Como él hardware invertido es, nosotros querremos ponerpedazo 3 del Registro del Mando a 1'. Sin embargo nosotros no queremos perturbar cualquier otromomento en el Puerto del Mando. Nosotros logramos esto leyendo el Puerto del Mando y 0x80 deOR'ing a él. por ejemplo el outportb(CONTROL, inportb(CONTROL) | el 0x08); Esto pondrá sólopedazo 3.

Después de que nosotros ponemos un byte del datos en los datos linea, nosotros debemos señalarentonces al módulo de LCD para leer los datos. Esto que usa se hace el Habilite la línea. El datos secronometra en el módulo de LCD adelante el alto para mugir la transición. El Estroboscopio eshardware invertido, así poniendo pedazo 0 del Registro del Mando nosotros conseguimos un altopara mugir la transición en la línea Estroboscópica. Nosotros esperamos entonces por un retraso, ydevuelve la línea a un estado alto listo para el próximo byte.

Después de que nosotros inicializamos el Módulo de LCD, nosotros queremos enviar el texto a él.Se envían los carácteres al Puerto de los Datos del LCD, así nosotros queremos aclarar pedazo 3.una vez más nosotros debemos cambiar sólo el uno mordió, así nosotros usamos eloutportb(CONTROL, inportb(CONTROL) & el 0xF7);. Entonces nosotros preparamos otro para lavuelta leer un byte del cordón y enviarlo al tablero de LCD. Esto se repite para la longitud delcordón.

Los retrasos deben ser convenientes para la mayoría de las máquinas. Si el tablero de LCD no estáinicializando propiamente, usted puede probar aumentando los retrasos. Igualmente si el tablero estásaltando los carácteres, por ejemplo Tst ,2. por otro lado, Si el módulo de LCD es los carácteresrepetidor por ejemplo TTTeessttiinngg entonces usted puede tener un faulting Habilitar la conexión.Verifique su Habilite a la conexión Estroboscópica.