Vous êtes sur la page 1sur 81

APUNTES

PRINCIPIOS DE PROGRAMACIN EN LA SOLUCIN


DE PROBLEMAS

NDICE
1
2

INTRODUCCIN.....................................................................................................5
INTRODUCCIN A LA PROGRAMACIN..........................................................6
1.1
RESOLUCIN DE PROBLEMAS A TRAVS DE LA COMPUTADORA.. .6
1.1.1
Definicin del Problema..............................................................................6
1.1.2
Anlisis del Problema..................................................................................6
1.1.3
Prueba y Depuracin...................................................................................6
1.1.4
Mantenimiento.............................................................................................7
1.2
ALGORITMOS.................................................................................................8
1.2.1
DEFINICIN Y CARACTERSTICAS DE LOS ALGORITMOS...........8
1.2.2
REGLAS PARA LA CONSTRUCCIN DE ALGORITMOS...................9
1.2.2.1
TIPOS DE ALGORITMOS.................................................................9
1.2.3
DIAGRAMAS DE FLUJO LINEALES....................................................11
1.2.3.1
Tipos de Datos....................................................................................11
1.2.3.1.1 Datos Numricos............................................................................11
1.2.3.1.2 Cadenas..........................................................................................12
1.2.3.1.3 Lgicos...........................................................................................13
1.2.3.1.4 Tipos Compuestos..........................................................................13
1.2.3.2
Constantes y variables........................................................................14
1.2.3.3
Operadores.........................................................................................15
1.2.3.3.1 Operadores Aritmticos.................................................................15
1.2.3.3.2 Operadores Div y Mod..................................................................16
1.2.3.3.3 Operadores Relacionales................................................................16
1.2.3.3.4 Prioridad De Operadores Aritmticos y Relacionales...................17
1.2.3.3.5 Operadores Lgicos.......................................................................19
1.2.3.3.6 Prioridad De Los Operadores Lgicos...........................................20
1.2.3.4
Asignacin..........................................................................................20
1.2.3.4.1 Asignacin Aritmtica...................................................................21
1.2.3.4.2 Asignacin Lgica.........................................................................21
1.2.3.4.3 Asignacin de caracteres...............................................................22
1.2.3.5
Entrada y Salida de Informacin........................................................22
1.2.4
ESTRUCTURAS ALGORTMICAS........................................................23
1.2.4.1
Estructura Secuencial.........................................................................23
1.2.4.2
Estructuras condicionales...................................................................25
1.2.4.3
IF, IF...ELSE.......................................................................................25
ALTERNATIVA SIMPLE (SI-ENTONCES/IF-THEN).................................25
1.2.4.3.1 Alternativas Mltiples (segn_sea, caso de / case)........................26
1.2.4.4
Estructuras Repetitivas.....................................................................28
1.2.4.4.1 Estructura Mientras (while)...........................................................28
1.2.4.4.2 Estructura Repetir (repeat).....................................................30
1.2.4.4.3 Estructura Desde/Para (for)....................................................30
2 LENGUAJE DE PROGRAMACIN C.................................................................32
2.1
HISTORIA DE C.............................................................................................32
2.2
Caractersticas clave de C................................................................................33
2.3
Compiladores de C..........................................................................................34
Pag.2

2.4
Palabras reservadas de C (ANSI-C)................................................................35
2.5
Primer programa en C.....................................................................................36
2.6
Identificadores.................................................................................................37
2.7
Constantes y Variables.....................................................................................37
2.7.1
Variables....................................................................................................37
2.7.1.1
Reglas para nombres de variables......................................................37
2.7.1.2
Tipos de Datos numricos..................................................................38
2.7.1.3
Declaracin de Variables....................................................................38
2.7.1.4
Inicializacin de Variables.................................................................38
2.7.2
Constantes..................................................................................................38
2.7.2.1
Constantes Literales...........................................................................39
2.7.2.2
Constantes simblicas........................................................................39
2.7.2.3
Declaracin de Constantes.................................................................39
2.7.2.3.1 La directiva #Define.....................................................................39
2.7.2.3.2 Const..............................................................................................39
2.8
Enunciados, expresiones y operadores............................................................40
2.8.1
Enunciados................................................................................................40
2.8.2
Expresiones................................................................................................40
2.8.3
Operadores.................................................................................................40
2.8.3.1
Operador de asignacin......................................................................40
2.8.3.2
Operadores matemticos....................................................................40
2.8.3.2.1 Operadores Unuarios:....................................................................40
2.8.3.2.2 Operadores Binarios......................................................................41
2.8.3.3
Operadores de Relacin.....................................................................42
2.8.3.4
Operadores lgicos.............................................................................42
2.9
ENTRADA Y SALIDA DE DATOS...............................................................43
2.9.1
Funcin puts()............................................................................................43
2.9.2
Funcin Printf().........................................................................................43
2.9.3
Funcin Scanf().........................................................................................43
2.9.4
Funcin Gets()...........................................................................................44
2.10 Estructuras de Control.....................................................................................44
2.10.1 Estructuras condicionales..........................................................................44
2.10.1.1 El Enunciado IF..................................................................................44
2.10.1.2 El enunciado IF.Then..Else........................................................45
2.10.1.3 EL enunciado Switch.........................................................................45
2.10.2 Estructuras ciclicas....................................................................................47
2.10.2.1 El enunciado For................................................................................47
2.11 FUNCIONES...................................................................................................47
2.11.1 Prototipo de Funcin.................................................................................48
2.11.2 Definicin de Funcin...............................................................................48
2.11.3 Estructura de una funcin..........................................................................48
2.11.4 Llamado de funciones................................................................................48
2.11.5 Paso de Argumentos..................................................................................48
2.12 Arreglos...........................................................................................................49
2.12.1 Arreglos Unidimensionales (Vectores)......................................................49
2.12.1.1 Inicializar un arreglo..........................................................................50
2.12.1.2 Asignacin de un arreglo:..................................................................50
2.12.2 Arreglos Bidimensionales (MATRICES)..................................................51
2.12.2.1 Definicin...........................................................................................51
2.13 REGISTROS...................................................................................................54
Pag.3

2.13.1 CONCEPTOS GENERALES...................................................................54


2.13.1.1 CONCEPTO DE CAMPO.................................................................54
2.13.1.2 CONCEPTO DE REGISTRO............................................................54
2.13.2 DEFINICION............................................................................................54
2.13.2.1 DEFINICION DE CAMPOS.............................................................54
2.13.2.2 DEFINICION DE REGISTROS........................................................54
2.13.3 Enumeraciones..........................................................................................56
2.13.4 Uniones......................................................................................................57
2.13.5 Definicin de nuevos nombres para tipos de datos...................................59
2.13.6 Convirtiendo tipos de datos (cast).............................................................60
2.13.7 Ejercicios...................................................................................................62
2.14 ARCHIVOS.....................................................................................................63
2.14.1 CONCEPTOS GENERALES...................................................................63
2.14.2 Clasificacin de Archivos..........................................................................64
2.14.3 Creacin de un archivo de datos................................................................66
2.14.4 Archivos de Acceso Aleatorio...................................................................68
2.14.5 Calcular la longitud de un fichero.............................................................69
2.14.6 Borrar registros..........................................................................................69
2.14.7 Ejemplo:....................................................................................................70
2.15 APUNTADORES............................................................................................73
2.15.1 Declaracin de punteros............................................................................74
2.15.2 Obtener punteros a variables.....................................................................74
2.15.3 Diferencia entre punteros y variables........................................................75
2.15.4 Correspondencia entre arrays y punteros..................................................75
2.15.5 Operaciones con punteros..........................................................................76
2.15.6 Asignacin.................................................................................................77
2.15.7 Operaciones aritmticas.............................................................................77
3
BIBLIOGRAFA.....................................................................................................80

Pag.4

1 INTRODUCCIN

Pag.5

2 INTRODUCCIN A LA PROGRAMACIN
1.1

RESOLUCIN DE PROBLEMAS A TRAVS DE LA


COMPUTADORA.
El proceso de resolucin de problemas con computadoras conduce a la escritura de un
programa y su ejecucin en la misma. Aunque el proceso de disear programas es
esencialmente un proceso creativo, se puede considerar una serie de fases o pasos
comunes que generalmente deben seguir los programadores. Estas fases son las
siguientes:

1.1.1 Definicin del Problema


Esta fase est dada por el enunciado del problema, el cual requiere una definicin
clara y precisa. Es importante que se conozca lo que se desea que realice la
computadora; mientras esto no se conozca del todo no tiene mucho caso continuar
con la siguiente etapa.

1.1.2 Anlisis del Problema


Una vez que se ha comprendido lo que se desea de la computadora, es necesario
definir:
1. Los datos de entrada.
2. Cul es la informacin que se desea producir (salida).
3. Los mtodos y frmulas que se necesitan para procesar los datos.
Una recomendacin muy prctica es el que nos pongamos en el lugar de la
computadora y analicemos que es lo que necesitamos que nos ordenen y en que
secuencia para producir los resultados esperados.

Codificacin: La codificacin es la operacin de escribir la solucin del problema


(de acuerdo a la lgica del diagrama de flujo o pseudocdigo), en una serie de
instrucciones detalladas, en un cdigo reconocible por la computadora, la serie de
instrucciones detalladas se le conoce como cdigo fuente, el cual se escribe en un
lenguaje de programacin o lenguaje de alto nivel.

1.1.3 Prueba y Depuracin


Los errores humanos dentro de la programacin de computadoras son muchos y
aumentan considerablemente con la complejidad del problema. El proceso de
identificar y eliminar errores, para dar paso a una solucin sin errores se le llama
depuracin. La depuracin o prueba resulta una tarea tan creativa como el mismo
desarrollo de la solucin, por ello se debe considerar con el mismo inters y
entusiasmo.

Documentacin

Pag.6

Es la gua o comunicacin escrita es sus variadas formas, ya sea en enunciados,


procedimientos, dibujos o diagramas. A menudo un programa escrito por una persona,
es usado por otra. Por ello la documentacin sirve para ayudar a comprender o usar
un programa o para facilitar futuras modificaciones.
La documentacin se divide en tres partes:
1. Documentacin Interna: son los comentarios o mensajes que se aaden al
cdigo fuente para hacer ms claro el entendimiento de un proceso.
2. Documentacin Externa: se define en un documento escrito los siguientes
puntos:

Descripcin del Problema.


Nombre del Autor.
Algoritmo (diagrama de flujo o pseudocdigo).
Diccionario de Datos.
Cdigo Fuente (programa).

1. Manual del Usuario: describe paso a paso la manera cmo funciona el


programa, con el fin de que el usuario obtenga el resultado deseado.

1.1.4 Mantenimiento
Se lleva a cabo despus de terminado el programa, cuando se detecta que es
necesario hacer algn cambio, ajuste o complementar al programa para que siga
trabajando de manera correcta. Para poder realizar este trabajo se requiere que el
programa este correctamente documentado.

Pag.7

1.2 ALGORITMOS
1.2.1 DEFINICIN Y CARACTERSTICAS DE LOS ALGORITMOS.
Un algoritmo es una secuencia de pasos lgicos necesarios para llevar a cabo
una tarea especfica, como la solucin de un problema. Los algoritmos son
independientes tanto del lenguaje de programacin en que se expresan como de la
computadora que los ejecuta. En cada problema el algoritmo se puede expresar en un
lenguaje diferente de programacin y ejecutarse en una computadora distinta; sin
embargo el algoritmo ser siempre el mismo.
A primera vista, se puede pensar que el conocimiento de estos algoritmos y
estructuras de datos no tienen una aplicacin prctica inmediata. Sin embargo, su
conocimiento y correcta aplicacin sirven para producir programas mejores, en el
sentido de que aprovechan mejor la memoria del sistema, son ms rpidos, eficientes,
robustos y tolerantes a fallos.
Las aplicaciones de estos algoritmos en algunos casos son inmediatas; por
ejemplo, hallar el trayecto ms corto entre dos estaciones es algo que interesa a
muchos viajeros del metro y se pueden obtener aproximaciones bastante buenas del
mundo real utilizando algunos de los algoritmos que obtienen distancias mnimas.
Otros algoritmos sirven para procesar cadenas, lo cual sirve de base para
analizadores lxicos o algoritmos criptogrficos, por ejemplo.
Adems, tener conocimientos adecuados de algoritmia y estructuras de datos
facilita el poder pasar de un lenguaje de programacin a otro con mucha mayor
facilidad: puesto que ya se tiene la base, slo hace falta superar las dificultades
tcnicas particulares de cada lenguaje.
Las caractersticas fundamentales que debe cumplir todo algoritmo son:

Un algoritmo debe ser preciso e indicar el orden de realizacin de cada paso.


Un algoritmo debe estar definido. Si se sigue un algoritmo dos veces, se debe
obtener el mismo resultado cada vez.
Un algoritmo debe ser finito. Si se sigue un algoritmo, se debe terminar en
algn momento; o sea debe de tener un nmero finito de pasos.

La definicin de un algoritmo debe describir tres partes: Entrada, Proceso y Salida.

Pag.8

1.2.2 REGLAS PARA LA CONSTRUCCIN DE ALGORITMOS


1.2.2.1

TIPOS DE ALGORITMOS.

* Algoritmo determinista: en cada paso del algoritmo se determina de forma nica el


siguiente
paso.
* Algoritmo no determinista: deben decidir en cada paso de la ejecucin entre varias
alternativas y agotarlas todas antes de encontrar la solucin.
Todo algoritmo tiene una serie de caractersticas, entre otras que requiere una serie de
recursos, algo que es fundamental considerar a la hora de implementarlos en una
mquina.
Estos
recursos
son
principalmente:
El tiempo: perodo transcurrido entre el inicio y la finalizacin del algoritmo.
La memoria: la cantidad (la medida vara segn la mquina) que necesita el
algoritmo
para
su
ejecucin.
Obviamente, la capacidad y el diseo de la mquina pueden afectar al diseo del
algoritmo.
En general, la mayora de los problemas tienen un parmetro de entrada que es el
nmero de datos que hay que tratar, esto es, N. La cantidad de recursos del algoritmo
es tratada como una funcin de N. De esta manera puede establecerse un tiempo de
ejecucin del algoritmo que suele ser proporcional a una de las siguientes funciones:

1: Tiempo de ejecucin constante. Significa que la mayora de las instrucciones


se ejecutan una vez o muy pocas.

logN: Tiempo de ejecucin logartmico. Se puede considerar como una gran


constante. La base del logaritmo (en informtica la ms comn es la base 2)
cambia la constante, pero no demasiado. El programa es ms lento cuanto
ms crezca N, pero es inapreciable, pues logN no se duplica hasta que N
llegue a N2.

N: Tiempo de ejecucin lineal. Un caso en el que N valga 40, tardar el doble


que otro en que N valga 20. Un ejemplo sera un algoritmo que lee N nmeros
enteros y devuelve la media aritmtica.

Nylon: El tiempo de ejecucin es Nylon. Es comn encontrarlo en algoritmos


como Quick Sort y otros del estilo divide y vencers. Si N se duplica, el tiempo
de ejecucin es ligeramente mayor del doble.

N2: Tiempo de ejecucin cuadrtico. Suele ser habitual cuando se tratan pares
de elementos de datos, como por ejemplo un bucle anidado doble. Si N se
duplica, el tiempo de ejecucin aumenta cuatro veces. El peor caso de entrada
del algoritmo Quick Sort se ejecuta en este tiempo.

N3: Tiempo de ejecucin cbico. Como ejemplo se puede dar el de un bucle


anidado triple. Si N se duplica, el tiempo de ejecucin se multiplica por ocho.

Pag.9

2N: Tiempo de ejecucin exponencial. No suelen ser muy tiles en la prctica


por el elevadsimo tiempo de ejecucin. El problema de la mochila resuelto por
un algoritmo de fuerza bruta -simple vuelta atrs- es un ejemplo. Si N se
duplica, el tiempo de ejecucin se eleva al cuadrado.

* Algoritmos polinomiales: aquellos que son proporcionales a N k. Son en general


factibles.
* Algoritmos exponenciales: aquellos que son proporcionales a kN. En general son
infactibles salvo un tamao de entrada muy reducido.
- Notacin O-grande
En general, el tiempo de ejecucin es proporcional, esto es, multiplica por una
constante a alguno de los tiempos de ejecucin anteriormente propuestos, adems de
la suma de algunos trminos ms pequeos. As, un algoritmo cuyo tiempo de
ejecucin sea T = 3N2 + 6N se puede considerar proporcional a N2. En este caso se
dira que el algoritmo es del orden de N 2, y se escribe O (N2)
Los grafos definidos por matriz de adyacencia ocupan un espacio O (N 2), siendo N el
nmero de vrtices de ste.
La notacin O-grande ignora los factores constantes, es decir, ignora si se hace una
mejor o peor implementacin del algoritmo, adems de ser independiente de los datos
de entrada del algoritmo. Es decir, la utilidad de aplicar esta notacin a un algoritmo es
encontrar un lmite superior del tiempo de ejecucin, es decir, el peor caso.
A veces ocurre que no hay que prestar demasiada atencin a esto. Conviene
diferenciar entre el peor caso y el esperado. Por ejemplo, el tiempo de ejecucin del
algoritmo Quick Sort es de O (N2). Sin embargo, en la prctica este caso no se da casi
nunca y la mayora de los casos son proporcionales a NlogN. Es por ello que se utiliza
esta ltima expresin para este mtodo de ordenacin.
Una
definicin
rigurosa
de
esta
notacin
es
la
siguiente:
Una funcin g(N) pertenece a O(f(N)) si y slo si existen las constantes c0 y N0 tales
que:
|g(N)| <= |c0f(N)| , para todo N >= N0.

Pag.10

1.2.3 DIAGRAMAS DE FLUJO LINEALES


1.2.3.1

Tipos de Datos

Un dato se define como la expresin general que describe los objetos con los
cuales opera una computadora. Los datos de entrada se transforman por el programa,
despus de las etapas intermedias, en datos de salida.

Los datos se clasifican en diversas categoras, segn el tipo de mquina o del


lenguaje en uso. Generalmente podemos encontrar las siguientes categoras :

Numricos

Lgicos

Cadenas

1.2.3.1.1 Datos Numricos


Son aqullos que representan una cantidad o valor determinado. Su
representacin se lleva a cabo en los formatos ya conocidos (enteros, punto y
fracciones decimales si estas existen).
Estos pueden representarse en dos formas distintas :

Tipo Numrico Entero (integer).

Tipo Numrico Real (real).

Enteros
Es un conjunto finito de los nmeros enteros. Los enteros son nmeros
completos, no tienen componentes fraccionarios o decimales y pueden ser negativos y
positivos.
Algunos ejemplos son :
Pag.11

37

-10 9

15.25

50

Reales
Consiste en un subconjunto de los nmeros reales. Estos nmeros siempre tienen
un punto decimal y pueden ser positivos o negativos. Un nmero real consiste de un
nmero entero y una parte decimal. Algunos ejemplos son :

0.52 664.32

6.579 8.0

-9.3 -47.23

1.2.3.1.2 Cadenas
Son los datos que representan informacin textual (palabras, frases, smbolos,
etc). No representan valor alguno para efectos numricos. Pueden distinguirse porque
son delimitados por apstrofes o comillas.
Se clasifica en dos categoras :

Datos tipo carcter (char)


Datos tipo Cadena (string)

Datos Tipo Carcter


Es un conjunto finito y ordenado de caracteres que la computadora reconoce.
Un dato de este tipo contiene solo un carcter.

Reconoce los siguientes caracteres :

Caracteres Alfabticos (A,B,C,Z,a,b,cz)

Caracteres Numricos (0,1,2,9)

Pag.12

Caracteres Especiales (+, -, *, /, ^, . , ;, <, >, $, .)

Datos Tipo Cadena (string)


Es una sucesin de caracteres que se encuentran delimitados por una comilla
(apstrofe) o dobles comillas, segn el tipo de lenguaje de programacin. La longitud
de una cadena de caracteres es el nmero de ellos comprendidos entre los
separadores o delimitadores.
Ejemplos :

Hola Mortimer

12 de octubre de 1496

Enunciado cualquiera

Nota: Los smbolos disponibles para la formulacin de caracteres y de


cadenas son aqullos que se encuentran en el cdigo ASCII.

ASCII (American Standard Code for Information Interchange).

1.2.3.1.3 Lgicos
Tambin se le denomina Booleano, es aqul dato que solo puede tomar uno de
dos valores : Falso y verdadero.
Se utiliza para representar las alternativas (si/no) a determinadas condiciones.
Por ejemplo, cuando se pide si un valor entero sea primo, la respuesta ser verdadera
o falsa, segn sea.
Las categoras y tipos que se mencionaron anteriormente se conocen como Tipos
Simples, puesto que no poseen una estructura compleja.
En forma adicional, cada lenguaje puede proporcionar la utilizacin de Tipos
Compuestos, siendo estos, datos que tienen una estructura predeterminada.

1.2.3.1.4 Tipos Compuestos


Entre los principales tipos compuestos se encuentran los siguientes:

Pag.13

a.- SUB-RANGO:
Son aqullos en los que se especifica con precisin el intervalo
de valores vlidos para un dato.
Ejemplos:
0..100

(son enumerativos de tipo entero)

'A'..'Z'

(son enumerativos de tipo cadena)

Los Reales no son vlidos para crear enumerativos, ya que su intervalo no est
definido.

b.- ENUMERATIVOS :
valores para un dato.

Son aqullos en los que se definen individualmente los

Ejemplos:
(0,25,40,52)

Siempre deben ponerse netre parntesis.

c.- DEFINIDOS POR EL USUARIO :


Son aqullos que el programador crea para
satisfacer las necesidades del programa en diseo.

1.2.3.2

Constantes y variables

Una Constante es aqulla que no cambia de valor durante la ejecucin de un


programa (o comprobacin de un algoritmo en este caso). Se representa en la forma
descrita para cada categora.
Las Variables son aqullas que pueden modificar su valor durante la ejecucin
de un programa (idem).
Su representacin se da a travs de letras y smbolos generalmente numricos a
los que se les asigna un valor.
Ejemplos:

Numricos

Pag.14

Constantes
36

Variables
A

450.35

Nom

0.58

Edad

'A'
Cadena

'Juan'

Ciudad

'La Paz'

Estatura

Falso
Lgicos
Verdadero

Operadores y Operandos

1.2.3.3

Operadores

Un operador es el smbolo que determina el tipo de operacin o relacin que


habr de establecerse entre los operandos para alcanzar un resultado.

Los operadores se clasifican en tres grupos:

Aritmticos.

Relacionales.

Lgicos.

1.2.3.3.1 Operadores Aritmticos


Son aqullos que permiten la realizacin de clculos aritmticos. Utilizan
operandos numricos y proporcionan resultados numricos.

Operador
Pag.15

Operacin

Suma

Resta

Multiplicacin

Divisin real

Div

Divisin entera

Mod

Residuo

Exponenciacin

Ejemplos:
7+3 = 10 10 Div 4 = 2
7-3 = 4 20 Mod 3 = 2
7*3 = 21 5 Mod 7 = 5
10/4= 2.5 4 ^ 2 = 16
En la expresin 7+3, los valores 7 y 3 se denominan operandos. El valor de la
expresin 7+3 se conoce como resultado de la expresin.

Todos los operadores aritmticos no existen en todos los lenguajes de


programacin, por ejemplo, en Fortran no existen Div y mod.

1.2.3.3.2 Operadores Div y Mod


El smbolo / se utiliza para la divisin real, y el operador Div representa la divisin
entera.
Expresin

Resultado

Expresin

Resultado

10.5/3.0

3.5

10 Div 3

1/4

0.25

18 Div 2

2.0/4.0

0.5

30 Div 30

30/30

1.0

10 Mod 3

6/8

0.75

10 Mod 2

1.2.3.3.3 Operadores Relacionales


Pag.16

Permiten realizar comparaciones de valores de tipo numrico o carcter. Estos


operadores sirven para expresar las condiciones en los algoritmos. Proporcionan
resultados lgicos.

Operador

Significado

<

Menor que

>

Mayor que

Igual que

<=

Menor o igual que

>=

Mayor o igual que

<>

Diferente de

El formato general para las comparaciones es:


expresin1 operador de relacin expresin2

El resultado de la operacin ser Verdadero o Falso. As por ejemplo, si A=4 y B=3,


entonces:
A>B Es Verdadero
(A-2) < (B-4) Es Falso

Los operadores de relacin se pueden aplicar a cualquiera de los cuatro tipos de


datos estndar: enteros, real, lgico y carcter.
A < K = Verdadero
A > a = Falso
MARIA < JUAN = Falso (se considera la primera letra)
JAIME > JORGE = Falso
Pag.17

Nota: La comparacin de cadenas se rige por el cdigo ASCII.

1.2.3.3.4 Prioridad De Operadores Aritmticos y


Relacionales
Determina el orden en que habrn de realizarse las operaciones en una
expresin determinada. Para obtener la prioridad se deben conocer las siguientes
reglas:

Las operaciones que estn encerradas entre parntesis se evalan primero.


Si existen diferentes parntesis anidados (interiores unos a otros), las
expresiones ms internas se evalan primero.

Las operaciones aritmticas dentro de una expresin suelen seguir el


siguiente orden de prioridad.

Operador

Prioridad

Alta

*, /, Div
+, -, Mod
Relacionales

Baja

En caso de coincidir varios operadores de igual prioridad en una expresin o


subexpresin encerrada entre parntesis, el orden de prioridad en este caso es de
izquierda a derecha.

Cuando se desea realizar una operacin con baja prioridad por adelantado, debe
agruparse a los operandos involucrados.
4 + 12 /2 = 10 (sin agrupar)
(4 + 12) /2 = 8 (con agrupador)
Pag.18

Ejemplo:
Obtener los resultados de las expresiones:
-4 * 7 + 2 ^ 3 / 4 - 5

Solucin:
-4 *7 + 2 ^

Resulta:
-4 * 7+ 8/4 -5
-28 + 8/4 -5
-28 + 2 - 5
-26 - 5
-31

Los parntesis tienen prioridad sobre el resto de las operaciones.


A * (B+3)
La constante 3 se suma primero al valor de B, despus este
resultado se multiplica
por el valor de A.

(A*B) +3 A y B

A + (B/C) + D

Se multiplican primero y a continuacin se suma 3.

Esta expresin equivale a A+ B/C + D

1.2.3.3.5 Operadores Lgicos


Son aqullos que permiten la combinacin de condiciones para formar una sola
expresin lgica. Utilizan operandos lgicos y proporcionan resultados lgicos
tambin.
Pag.19

Operador

Relacin

not

Negacin (No)

and

Conjuncin (Y)

or

Disyuncin (O)

xor

Disyuncin Exclusiva
(O/SOLO)

Se obtiene Verdadero si:


NOT

El operando es falso

AND

Ambos operandos son


verdaderos
Al menos un operando es
verdadero

OR

Solo uno de los operandos son


verdadero

XOR

NOT(X)

NOT(Y)

X AND Y

X OR Y

X XOR Y

1.2.3.3.6 Prioridad De Los Operadores Lgicos


Los operadores aritmticos seguan un orden especfico o de prioridad cuando
exista ms de un operador en las expresiones. De modo similar los operadores lgicos
y relacionales tienen un orden de prioridad.
Ejemplos:

Pag.20

Not 4 > 6
a 4.

Produce un error, ya que el operador not se aplica

Not (4 > 14)

Produce un valor verdadero.

(1.0<x) And (x<z +7.0)

Si x vale 7 y z vale 4, se obtiene un valor falso.

1.2.3.4

Asignacin

La operacin de asignacin es el modo de darle valores a una variable. La


operacin de asignacin se representa por el smbolo u operador . La operacin de
asignacin se conoce como instruccin o sentencia de asignacin cuando se refiere a
un lenguaje de programacin.
A fin de manejar datos por medio de variables, estos pueden recibir valores
determinados. El tipo de los valores que pueden recibir dependen de la declaracin
previa de tales variables.
En una asignacin se resuelve, primeramente la expresin (al lado derecho del
smbolo de asignacin) y se asigna el resultado en la variable.
El formato general de asignacin es:
Nom_variable Expresin
Donde Expresin puede ser una variable o constante, operacin, funcin.
Ejemplo:
A 9
Significa que la variable A se le ha asignado el valor 9. La accin de asignar es
destructiva, ya que el valor que tuviera la variable antes de la asignacin se pierde y
se reemplaza por el nuevo valor. As en la secuencia de operaciones:
A 30
A 189
A9
Cuando se ejecutan, el ltimo valor que toma A ser 9, ya que los valores anteriores
a este han desaparecido.
Las acciones de asignacin se
Aritmticas, Lgicas y de Caracteres.

Pag.21

clasifican segn sea el tipo de expresiones :

1.2.3.4.1

Asignacin Aritmtica

Las expresiones en las operaciones de asignacin son aritmticas:


Suma 5+10+2
es decir, 17

1.2.3.4.2

Se evala la expresin 5+10+2 y se asigna a la variable Suma,


ser el valor que toma Suma.

Asignacin Lgica

La expresin que se evala en la operacin de asignacin es lgica. Supngase que


M, N, y P son variables de tipo lgico.
M8<5
N M o (7 <= 12)
P7>6
Tras ejecutar las operaciones anteriores, las variables M,N,P toman los valores,
falso, verdadero, verdadero respectivamente.

1.2.3.4.3

Asignacin de caracteres

La operacin que se evala es de tipo carcter.


x '3 de Mayo de 1999'
La accin de asignacin anterior asigna la cadena de caracteres '3 de Mayo de 1999' a
la variable de tipo carcter x.

1.2.3.5

Entrada y Salida de Informacin

Los clculos que realizan las computadoras requieren para ser tiles la Entrada
de los datos necesarios para ejecutar las operaciones que posteriormente se
convertirn en resultados, es decir, Salida.
Las operaciones de entrada permiten leer determinados valores y asignarlos a
determinadas variables. Esta entrada se conoce como operacin de Lectura (read).
Los datos de entrada se introducen al procesador mediante dispositivos de entrada
(teclado, unidades de disco, etc). La salida puede aparecer en un dispositivo de salida
(pantalla, impresora, etc). La operacin de salida se denomina escritura (write).

Pag.22

En la escritura de algoritmos las acciones de lectura y escritura se representan


por los formatos siguientes
leer ( Nom_variable )
escribir (lista de variables de salida)

Las expresiones son combinaciones de constantes, variables, smbolos de


operadores, parntesis y nombres de funciones especiales. Las mismas ideas son
utilizadas en notacin matemtica tradicional ; por ejemplo :
a + b ( b+2)

Aqu los parntesis indican el orden de clculo.

Cada expresin toma un valor que se determina tomando los valores de las
variables y constantes implicadas y la ejecucin de las operaciones indicadas.

1.2.4 ESTRUCTURAS ALGORTMICAS


`
1.2.4.1

Estructura Secuencial.

Es aqulla en la que una accin (instruccin) sigue a otra en secuencia. Las


tareas se suceden de tal modo que la salida de una es la entrada de la siguiente y as
sucesivamente hasta el fin del proceso. La estructura secuencial tiene una entrada y
una salida. Su representacin grfica es la siguiente:

Estructura Secuencial

....
Pag.23

Pseudocdigo de una estructura secuencial


Inicio
:
:
acciones
:
:
fin

Pag.24

Ejemplo:
Calcular el salario neto de un trabajador en funcin del nmero de horas
trabajadas, precio de la hora de trabajo y considerando unos descuentos fijos al
sueldo bruto en concepto de impuestos (20 por 100).
Pseudocdigo
Inicio
{clculo salario neto}
leer nombre, horas, precio_hora
salario_bruto
horas * precio
impuestos
0.20 * salario_bruto
salario_neto
salario_bruto_impuestos
escribir nombre, salario_bruto, salario_neto_bruto, salario_neto
Fin
Diagrama de flujo

Pag.25

1.2.4.2

Estructuras condicionales

1.2.4.3

IF, IF...ELSE

La especificacin formal de algoritmos tiene realmente utilidad cuando el


algoritmo requiere una descripcin ms complicada que una lista sencilla de
instrucciones. Este es el caso cuando existen un nmero de posibles alternativas
resultantes de la evaluacin de una determinada condicin.
Las estructuras selectivas se utilizan para tomar decisiones lgicas; de ah que
se suelan denominar tambin estructuras de decisin o alternativas.
En las estructuras selectivas se evala una condicin y en funcin del resultado
la misma se realiza una opcin u otra. Las condiciones se especifican usando
expresiones lgicas. La representacin de una estructura selectiva se hace con
palabras en pseudocdigo (if, then, else o bien en espaol si, entonces, sino), con una
figura geomtrica en forma de rombo o bien con un tringulo en el interior de una caja
rectangular.

ALTERNATIVA SIMPLE (SI-ENTONCES/IF-THEN).


La estructura alternativa simple si-entonces (en ingls if-then o bien IF-THEN)
ejecuta una determinada accin cuando se cumple una determinada condicin. La
seleccin si-entonces evala la condicin y
Si la condicin es verdadera, entonces ejecuta la accin S1 (o acciones en
caso de ser S1 una accin compuesta y constar de varias acciones).
Si la condicin es falsa, entonces no hacer nada.
A continuacin se muestra la grfica de la estructura condicional simple.

Pseudocdigo en espaol
Si <condicin> entonces
<accin S1>
Fin_si
Pag.26

Pseudocdigo en ingls
If <condicin> then
<accin S1>
end_if

1.2.4.3.1 Alternativas Mltiples (segn_sea, caso de /


case)
Cuando existen ms de dos elecciones (alternativas) posibles, es cuando se
presenta el caso de alternativas mltiples. Si el nmero de alternativas es grande
puede plantear serios problemas de escritura del algoritmo y naturalmente de
legibilidad.
La estructura de decisin mltiple evaluar una expresin que podr tomar n
valores distintos 1, 2, 3, 4, .., n . Segn que elija uno de estos valores en la condicin,
se realizar una de las n acciones, o lo que es igual, el flujo del algoritmo seguir un
determinado camino entre los n posibles.
La representacin grfica se muestra a continuacin:

Diagrama de Flujo

Pseudocdigo.
En ingls la estructura de decisin mltiple se representa
Case expresin of
[e1]: accin S1
[e2]: accin S2
:
[en]: accin Sn
else
accin Sx
end_case

Pag.27

Ejemplo:
Se desea disear un algoritmo que escriba los nombres de los das de la
semana en funcin del valor de una variable DIA introducida por teclado.
Los das de la semana son 7; por consiguiente, el rango de valores de DIA
ser 1..7, y caso de que DIA tome un valor fuera de este rango se deber
producir un mensaje de error advirtiendo la situacin anmala.
Inicio
Leer DIA
Segn_sea DIA hacer
1: escribir('Lunes')
2: escribir('Martes')
3: escribir('Mircoles')
4: escribir('Jueves')
5: escribir('Viernes')
6: escribir('Sabado')
7: escribir('Domingo')
else
escribir('Error')
fin_segn
fin

Pag.28

1.2.4.4

Estructuras Repetitivas.

Las estructuras que repiten una secuencia de instrucciones un nmero


determinado de veces se denominan Bucles y se denomina Iteracin al hecho
de repetir la ejecucin de una secuencia de acciones. Entre las estructuras
repetitivas se encuentran:

Mientras (while)
Repetir (repeat)
Desde (for)

1.2.4.4.1 Estructura Mientras (while)


La estructura repetitiva while, es aqulla en que el cuerpo del bucle se repite
mientras se cumple una determinada condicin, su representacin grfica es:

Pseudocdigo en espaol
Mientras condicin hacer
Accin S1
Accin S2
:
accin Sn
Fin_mientras

Pseudocdigo en ingls
while condicin do
<Acciones>
:
End_while

Ejemplo:
Contar los nmeros enteros positivos introducidos por teclado. Se
consideran dos variables enteras NUMERO y CONTADOR (contar el nmero
de enteros positivos). Se supone que se leen nmeros positivos y se detiene el
bucle cuando se lee un nmero negativo o cero.
Pag.29

Pseudocdigo
Inicio
contador
0
Leer (numero)
Mientras numero > 0 hacer
contador
contador+1
Leer (numero)
Fin_Mientras
Escribir('El nmero de enteros positivos es : ', contador)
Fin

Diagrama de Flujo

Pag.30

1.2.4.4.2 Estructura Repetir (repeat)


Esta estructura se ejecuta hasta que se cumpla una condicin
determinada que se comprueba hasta el final del bucle. Se ejecuta al menos
una vez. El bucle repetir-Hasta_que se repite mientras el valor de la expresin
booleana de la condicin sea falsa, justo la opuesta de la sentencia mientras.
Pseudocdigo en Espaol
Repetir
<acciones>
:
Hasta que <condicin>

Pseudocdigo en Ingls
Repeat
<acciones>
:
Until <condicin>

Diagrama de Flujo de Repetir

1.2.4.4.3 Estructura Desde/Para (for)


En muchas ocasiones se conoce de antemano el nmero de veces que
se desean ejecutar las acciones de un bucle. En estos casos en el que el
nmero de iteraciones es fija, se debe usar la estructura desde o para.
La estructura Desde ejecuta las acciones del cuerpo del bucle un
nmero especfico de veces y de modo automtico controla el nmero de
iteraciones o pasos a travs del cuerpo del bucle.
Pseudocdigo en Espaol
Ingls
Desde variable(v)= vi Hasta vf hacer
Do
<acciones>
:
Fin_desde
Pag.31

Pseudocdigo en
For variable (v)= vi To vf
<acciones>

Donde:
v: Variable ndice
vi, vf: Valores inicial y final de la variable
Diagrama de Flujo de la estructura Desde/Para

Pag.32

LENGUAJE DE PROGRAMACIN C

2.1 HISTORIA DE C
En 1970 Ken Thompson de los laboratorios Bell se haba propuesto desarrollar un
compilador para el lenguaje Fortran que corra en la primera versin del sistema
operativo UNIX tomando como referencia el lenguaje BCPL; el resultado fue el
lenguaje B (orientado a palabras) que resulto adecuado para la programacin de
software de sistemas. Este lenguaje tuvo la desventaja de producir programas
relativamente lentos.
En 1971 Dennis Ritchie, con base en el lenguaje B desarroll NB que luego cambio su
nombre por C; en un principio sirvi para mejorar el sistema UNIX por lo que se le
considera su lenguaje nativo. Su diseo incluye una sintaxis simplificada, la aritmtica
de direcciones de memoria (permite al programador manipular bits, bytes y direcciones
de memoria) y el concepto de apuntador; adems, al ser diseado para mejorar el
software de sistemas, se busco que generase cdigos eficientes y uno portabilidad
total, es decir el que pudiese correr en cualquier mquina. Logrados los objetivos
anteriores, C se convirti en el lenguaje preferido de los programadores profesionales.
En 1980 Bjarne Stroustrup de los laboratorios Bell de Murray Hill, New Jersey,
inspirado en el lenguaje Simula67 adiciono las caractersticas de la programacin
orientada a objetos (incluyendo la ventaja de una biblioteca de funciones orientada a
objetos) y lo denomino C con clases. Para 1983 dicha denominacin cambio a la de
C++. Con este nuevo enfoque surge la nueva metodologa que aumenta las
posibilidades de la programacin bajo nuevos conceptos.

Pag.33

2.2 Caractersticas clave de C

Pag.34

2.3 Compiladores de C

Pag.35

2.4 Palabras reservadas de C (ANSI-C)


Las palabras reservadas son identificadores predefinidos que tienen un significado
especial para el compilador C. Un identificador definido por el usuario, no puede tener
el mismo nombre que una palabra reservada.
auto
continue
else
for
long
sizeof
typedef
wile
break
default
num
goto
register
static
union
main
case
do
extern
if
return
struct
unsigned
char
double
float
int
short
switch
void
signed
Algunas versiones de compiladores pueden tener palabras adicionales, asm, ada,
fortran, pascal, etc. Cabe hacer mencin que el lenguaje que analizaremos es el ANSI
C, y ste debe de compilarse en cualquier compilador y cualquier plataforma, que
soporte el ANSI C (LINUX, UNIX, MS-DOS, etc.).

Pag.36

2.5 Primer programa en C


/* Mi primer programa en C */
#include <stdio.h>
int main (int argc, char *argv)
{
printf (Hola);
return O;
}
La primera lnea, entre / * y * /, es un comentario (algo que no forma parte del cdigo
del programa en s pero que se incluye como aclaracin para facilitar su lectura).
La lnea #include <stdio.h> le indica al preprocesador de C que incluya en el
programa el contenido del fichero de cabecera stdio.h, donde estn las declaraciones
de las funciones estndar de entrada/salida en C.
La lnea int main (...) define la cabecera de la funcin main, el punto donde comienza
la ejecucin de un programa en C.
Las llaves { } sirven para delimitar la secuencia de instrucciones que forman parte de
la funcin main.
La llamada a la funcin printf (Hola ); le indica al ordenador que muestre por
pantalla el mensaje que se le indica entre comillas.
La sentencia return indica el valor que
main (por convencin, O indica que todo fue bien).

Pag.37

devuelve

la

funcin

2.6 Identificadores
Los identificadores son nombres dados a constantes, variables, tipos, funciones y
etiquetas de un programa.

2.7 Constantes y Variables


2.7.1 Variables
Una variable es un identificador que tiene asociado un valor que puede cambiar a lo
largo de la ejecucin del programa
.

2.7.1.1

Reglas para nombres de variables

1.- El nombre puede contener letras, dgitos y el carcter de subrayado (__).


2.- EL primer carcter del nombre debe ser una letra. El carcter de subrayado
tambin puede ser un carcter inicial aceptado, pero no se recomienda su uso.
3.- Las maysculas y minsculas se consideran diferentes.
Ejemplo: SUMA, suma. Son variables diferentes
4.- Los identificadores no pueden coincidir con las palabras reservadas de C.
Ejemplo. For, Void, goto etc.
5.- EL identificador de variable puede ser hasta de 31 caracteres de largo.
Ejemplos de Variables Validos
Porcentaje /* Valido */.
Y2x5_fg7h /* Valido */
_ordenar /* Valido pero no recomendable*/
Cuenta#basico /* Ilegal */
Doubl /* Ilegal */
3contante /* Ilegal */
mi variable /* Ilegal */
caada /* Ilegal */
nombre.largo /* Ilegal */
camin /* Ilegal */

Pag.38

2.7.1.2

Tipos de Datos numricos

Tipo de Variable
Carcter
Nmeros Enteros
Entero corto
Entero largo

Palabra clave
Char
Int
Short
Long

Bytes Requeridos
1
2
1
4

Nmeros en Punto
flotante

float

Punto flotante doble

double

1.7X10 -308 a
1.7X10 +308

Doble largo

long double

3.4 X10-4932 a
1.1X10+4932

2.7.1.3

Rango
0 a 255
-32767 a 32767
-128 a 127
-2,147,483,648 a
-2,147,483,647
6 dgitos de precisin
3.4X10-38 a
3.4X10+38

Declaracin de Variables

Antes de ser utilizada una variable en C, esta debe ser declarada. Una declaracin de
variable le informa al compilador el nombre y tipo de la variable y opcionalmente inicia
la variable a un valor especifico.
Tipo Nombre de variable ,Nombre de Variable,:
Ejemplo.
Int contador;
Int numero, suma, inicio;
double porcentaje;

2.7.1.4

Inicializacin de Variables.

Una variable puede ser inicializada en el momento de su declaracin ej.


Int contador = 19;

2.7.2 Constantes
Recordemos que el valor de una constante no puede ser cambiado durante la
ejecucin del programa. El C tiene dos tipos de constantes.

Pag.39

2.7.2.1

Constantes Literales.

Una constante literal es un valor que es tecleado directamente en el cdigo fuente


cada vez que se necesita.
IVA = subtotal*.15;

2.7.2.2

Constantes simblicas

Una constante simblica es una constante que est representada por un nombre
(identificador). Cada vez que se necesite el valor de la constante en el programa se
usa su nombre.

2.7.2.3

Declaracin de Constantes

Las constante se pueden definir de dos maneras, por medio de la directiva #define o
la palabra clave const. Por conveniencia los nombres de las constantes se escriben en
mayscula.

2.7.2.3.1 La directiva #Define


La accin precisa de esta directiva es dar instrucciones al compilador para que en el
cdigo fuente reemplace a NOMBRE DE CONSTANTE con el valor. Cuando se
declara una constante con esta directiva no lleva punto y coma al final.
#define NOMBREDECONSTANTE literal
Ejemplo
#define PI 3.1416
#IVA .15

2.7.2.3.2 Const
La palabra clave const es otra manera de definer una constante, con la diferencia que
esta si reserva espacio en memoria para almacenar su valor. Su sintaxis es la
siguiente.
Const tipo de variable nombre de variable;
Const Int contador =100;
Const Float PI=3.1416;
Const long deuda =120000,

Pag.40

float tasa_impuesto = 0.21;

2.8 Enunciados, expresiones y operadores.


2.8.1 Enunciados
Un enunciado es una indicacin completa que le da instrucciones a la computadora,
los enunciados son escritos por lo general, uno en cada lnea aunque algunos pueden
extenderse a varias lneas. Los enunciados en C siempre terminan en punto y coma y
Los espacios en blanco son ignorados por el compilador.
Ejemplo X=2+3;
Es igual a
X
2
+

=
3;

2.8.2 Expresiones
Las expresiones son variables y constantes conectadas por operadores por ejemplo:
3+5
Var * 3

2.8.3 Operadores
Un operador es un smbolo que le da instrucciones al C para que ejecute alguna
operacin o accin, en uno o ms operandos. Los operadores en C se agrupan en
varias categoras.

2.8.3.1

Operador de asignacin

EL operador de asignacin es el signo de igual (=). En programacin es usado en


forma ligeramente diferente a las matemticas normales. Si se escribe
X=y;
En un programa C no significa x es igual a y. En cambio, significa Asigna el valor de
y a x. Esto es del lado derecho debe ser una expresin y del izquierdo una variable.
Variable = expresin;

2.8.3.2

Operadores matemticos.

2.8.3.2.1 Operadores Unuarios:


Los operadores unarios toman un solo operando.
Operador
Incremento

Smbolo
++

Decremento

--

++X;
Pag.41

Accin
Incrementa al operando en
1
Decrementa el operando en
1

Ejemplo
++x, x++
--x,x--

--Y;
Son equivalentes a
x=x+1
y=y-1;
Cuando se usan en modo prefijo, los operadores de incremento y decremento
modifican a su operando antes de que sea usado y en modo prefijo modifican a su
operando despus de que sea usado.
Ejemplo.
X=10;
Y=x++;
Despus de que estos enunciados se ejecutan x tiene el valor de 11 y y tiene el valor
de 10: el valor de x fue asignado a y y luego fue incrementado. Por el contrario, los
enunciados
X=10;
Y=++x;
Da como resultado que tanto y como x tienen el valor de 11: x fue incrementado y
luego fue asignado a y.

2.8.3.2.2 Operadores Binarios


Operadores Matemticos
Operador
Suma

Smbolo
+

Accin
Suma sus dos operadores

Ejemplo
X+y

Resta

Resta el segundo operando del


primero

X-Y

Multiplicacin

Multiplica sus dos operandos

X*y

Divisin

Divide el primer operando entre el x/y


segundo

Modulo

Da el residuo cuando el primer X%y


operando es dividido entre el
segundo

Precedencia de los operadores matemticos del COperadores


++-*/%
+-

Precedencia relativa
1
2
3

Si una expresin contiene ms de un operador con el mismo nivel de precedencia, los


operadores se ejecutan en orden de izquierda a derecha.
Pag.42

Ejemplo 12%5*2

2.8.3.3

Operadores de Relacin

Operador
Igual

Smbolo
==

Mayor que

>

Menor que

<

Mayor que o igual a

>=

Menor o igual a

<=

Diferente

!=

2.8.3.4

Pregunta
Es el Primer
operando igual que el
segundo?
Es el operando
mayor que el
segundo?
Es el operando
menor que el
segundo?
Es el operando
mayor que o igual al
segundo?
Es el operando
Menor que o igual al
segundo?
Es el operando
mayor que el
segundo?

Ejemplo
X==y
X>y
X<y
X>=y
X<=y
X!=y

Operadores lgicos

Operador

Smbolo

Ejemplo

&&

Exp1 && exp2

||

Exp1 || Exp2

No

!exp1

Precedencia de los operadores lgicos.


Operador

Precedencia

No

&&

||

2.9 ENTRADA Y SALIDA DE DATOS


Pag.43

En la mayora de los programas se necesita desplegar informacin en la pantalla o


leer informacin del teclado., en el lenguaje C las funciones mas comunes de salida es
Printf y Puts() y de entrada es Scanf() y gets( ),

2.9.1 Funcin puts()


La funcin puts() se usa para desplegar mensajes de texto y aade automticamente
una lnea nueva al final; Esta funcin no puede desplegar variables numricas.
Ejemplo.
Puts(Hola);

2.9.2 Funcin Printf()


En la funcin printf( ) solo se necesita pasarle el mensaje entre comillas dobles ej.
Printf( Mensaje de Prueba);
Si deseamos desplegar el valor de una variable junto al texto, la funcin se utilizara
de la siguiente manera Ej.
Printf( EL valor de x es

%d, x);

El formato debe contener un especificador de conversin que en el ejemplo es %d, ya


que el valor a imprimir es un valor int o long.
La funcin puede imprimir ms de una variable ejemplo.
Printf(Tasa= %f, cantidad = %d, tasa, cantidad);
Los especificadores de conversin mas comnmente usados son:
Especificador

Significado

%c

Un solo carcter

%d

Entero decimal

%f

Float, double

%s

Cadena de caracteres

%u

Entero decimal sin signo

2.9.3 Funcin Scanf()


La funcin scanf( ) lee datos numricos del teclado de acuerdo con un formato
especificado, y asigna los datos de entrada a una o mas variables del programa. El
formato utiliza los mismo especificadores de conversin que la funcin printf(). Ejemplo
Scanf(d%, x);
Lee un entero decimal del teclado y lo asigna a la variable entera X.

Pag.44

2.9.4 Funcin Gets()


La funcin gets() lee todos los caracteres del teclado hasta que se encuentra el primer
carcter de nueva lnea (Enter).
Char cadena(50);
Puts(Escribe una cadena);
Gets(cadena);
Printf(la cadena que escribiste es: %S, cadena);

2.10 Estructuras de Control


Los enunciados en un programa en C normalmente se ejecutan de arriba hacia abajo,
las estructuras de control como son el IF, Switch, for y do_While, modifican la ruta que
seguir el programa.

2.10.1

Estructuras condicionales
2.10.1.1

El Enunciado IF

En su forma bsica, el enunciado If evala una expresin y nos permite elegir si se


ejecuta o no una instruccin o un bloque de instrucciones. Cuando solo es una
sentencia la que se ejecuta despus de una evaluacin la forma es la siguiente:
If( expresin)
Sentencia;
Cuando es un grupo de dos o ms sentencias se encierran entre llaves de la siguiente
manera.
If (expresin){
Sentencia1;
Sentencia2;
Sentencia3;
}
Nota: La sentencia IF no debe llevar punto y coma.
Ejemplo: Disea un programa que lea un numero, si es positivo que lo multiplique por
2 y lo muestre.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
Int num;
Main()
{
Prinft(Escribe un numero);
Scanf(%d, &num);
IF(num>0)
{
Pag.45

Num=num*2;
Printf (El numero es

2.10.1.2

%d, num);

El enunciado IF.Then..Else

Un enunciado if puede incluir una clausula else de la siguiente manera


If (expresin)
Sentencia1;
Else
Sentencia2;
Si la expresin es cierta, se ejecuta la sentencia1. Si es falsa, se ejecuta la sentencia
2.
If(condicion) {
Bloque1
} Else {
Bloque2
}
Ejemplo:

IF anidados.
If(expresin)
Sentencia1;
Else if (expresin)
Sentencia 2;
Else
Sentencia3;
Ejemplo: Disea un programa en C que lea la edad de una persona, si la edad es
menor que 18, entonces que imprima menor de edad, de lo contrario si es menor que
65 entonces que imprima Adulto, si pasa los 65 entonces que imprima Anciano.
If(edad<18)
Printf(Menor de edad);
Else if(edad<65)
Printf(Adulto);
Else
Printf(Anciano);

2.10.1.3

EL enunciado Switch

Permite seleccionar entre varias alternativas posibles, su sintaxis es la siguiente:


switch (expresin) {
case expr_cte1:
Pag.46

sentencia1;
case expr_cte2:
sentencia2;
case expr_cte3:
sentencia3;
default:
sentencia;
}
Se selecciona a partir de la evaluacin de una nica expresin.

La expresin del switch debe ser de tipo entero.


Los valores de cada caso del switch han de ser constantes.
La etiqueta default marca el bloque de cdigo que se ejecuta
por defecto (cuando al evaluar la expresin se obtiene un valor
no especificado por los casos del switch).
En C, se ejecutan todas las sentencias incluidas a partir del
caso correspondiente, salvo que explcitamente usemos break:

void main()
{
int nota;
printf(Calificacin: );
scanf(%d, &nota);
switch (nota) {
case 0:
case 1:
case 2:
case 3:
case 4:
printf(Suspenso);
break;
case 5:
case 6:
printf(Aprobado);
break;
case 7:
case 8:
printf(Notable);
break;
case 9:
printf(Sobresaliente);
break;
case 10:
printf(Matrcula);
break;
default:
printf(Error);
}
}

Pag.47

2.10.2

Estructuras ciclicas
2.10.2.1

El enunciado For

EL enunciado for, permite ejecutar una instruccin o un bloque de instrucciones


durante una cantidad de veces; En esta sentencia se debe conocer el nmero de
veces
EL enunciado For tiene la siguiente estructura:
For(inicial; condicin; incremento){
Enunciado
}
Ejemplo :
for (i=1; i<=n; i++) {
factorial *= i;
Realiza un programa que C que lea 20 calificaciones e imprima su promedio.
WHILE
EL enunciado WHILE, permite ejecutar una instruccin o un bloque de instrucciones
mientras se cumple una condicin.
En el cuerpo del bucle debe existir algo que haga variar el valor asociado a la
condicin que gobierna la ejecucin del bucle.
While (condicin){
Bloque
}
Programa en C que permite introducir nmeros mientras sean positivos y al terminar
calcula e imprime el promedio
Main ()
{
Int num, suma, resp;
Float promedio;
Printf (Desea introducir un valor 1.-Si
Scanf(
resp;
While (resp=1)
Printf (Escribe un numero);
Scanf(%d,&num);
Suma=suma+num;
Printf (Desea introducir un valor 1.-Si
Scanf(
resp;
}

2.11 FUNCIONES
Pag.48

2.-No)

2.-No)

Una funcin es una seccin de cdigo de C que tiene un nombre independiente, que
ejecuta una tarea especfica y opcionalmente regresa un valor al programa que la
llama.

2.11.1

Prototipo de Funcin

Proporciona al compilador la descripcin de una funcin que ser definida mas


adelante en el programa. Un prototipo de funcin contiene el nombre de la funcin,
una lista de variables que se les debe pasar, el tipo de variable que regresa, en caso
de haberla y el punto y coma al final
ejemplo
Float suma (float, float);

2.11.2

Definicin de Funcin

La definicin contiene el cdigo que ser ejecutado. La primera lnea de la definicin


de funcin, llamada el encabezado de la funcin, debe ser idntica al prototipo de la
funcin, a excepcin del punto y coma. A continuacin del encabezado se encuentra el
cuerpo de la funcin. El cuerpo debe comenzar con una llave izquierda y terminar con
una llave derecha. Si el tipo de retorno de la funcin es otro diferente a void, se debe
incluir un enunciado return que regrese un valor.
Float suma (float a, float b)
{
Float resultado;
resultado=a+b;
return(resultado);
Sentencia return para
}
regreso de resultado

2.11.3

Estructura de una funcin

Type nombre_de_funcion (param1,param2,.)


Type= Tipo de retorno
Nombre de funcin= Nombre de la funcin
param1, param2= parmetros

2.11.4

Llamado de funciones

Cualquier funcin puede ser llamada simplemente con su nombre y lista de


argumentos en un enunciado.
resultado=suma(x,y);

2.11.5

Paso de Argumentos

Para pasar argumentos de una funcin se enlista entre parntesis a continuacin del
nombre. LA cantidad de argumentos y el tipo de cada uno de ellos deben coincidir con
los parmetros del encabezado y prototipo de funcin
#include <stdio.h>
Float suma (float, float);
Pag.49

Prototipo de Funcion

Void()
{
Float x,y,resultado ;
Printf (Escribe el primer valor);
Scanf(%f,&x);
Printf (Escribe el segundo valor);
Scanf(%f,&y);
resultado=suma(x,y);
Llamada a Funcion y
printf(El resultado de la suma es %f, resultado);
paso de argumentos
}
Float suma (float a, float b)
Encabezado de
{
funcion
Float resultado;
resultado=a+b;
return(resultado);
Sentencia return para
}
regreso de resultado

Escriba un encabezado de funcin llamada hazlo ( ), que tome tres argumentos de tipo
char y regrese un tipo float al programa que la llama.
Escriba una funcin que reciba dos nmeros como argumentos y regrese el valor de
su producto
Escriba una funcin que reciba dos nmeros como argumentos, La funcin debe dividir
el primer nmero entre el segundo. No divida cuando el segundo nmero es cero.
Escribe un programa que use una funcin para encontrar el promedio de cinco valores
tipo float tecleados por el usuario.

2.12 Arreglos
Un arreglo es una coleccin ordenada de elementos de un mismo tipo. Ordenada
significa que cada elemento tiene una ubicacin determinada dentro del arreglo y
debemos conocerla para accederlo.
Un arreglo puede tener una o varias dimensiones. A los arreglos unidimensionales se
les conocen como vectores y a los bidimensionales como matrices.

2.12.1

Arreglos Unidimensionales (Vectores)

Un vector es un arreglo de una sola dimensin, para indicar a qu elemento nos


referimos, se necesita especificar un slo nmero o ndice, que corresponde a la
posicin relativa de dicho elemento dentro del arreglo.
Definicin de un arreglo:
<tipo> nombre_variable[longitud];

Pag.50

tipo puede ser cualquier tipo de dato (int, float, char, etc.).

nombre_de_variable es el nombre del arreglo.

Longitud: corresponde al nmero de posiciones del arreglo

2.12.1.1

Inicializar un arreglo

Si se desea la inicializar arreglos, es decir asignar valores al arreglo en el momento de


ser declarados debe hacerse con el siguiente formato:
tipo nombre_arr[ tam1= {valor1,valor2.valor n};
Ejemplo:
int i[10] = {1,2,3,4,5,6,7,8,9,10};

Posiciones 0 1 2 3 4 5 6
Contenido

F u l a n o \0

2.12.1.2

Asignacin de un arreglo:

nombre_variable[ndice] = valor
Esta instruccin asigna el valor a la posicin ndice del arreglo. El ndice debe ser una
expresin del tipo entero en el rango [0, longitud-1].
Acceso al contenido de un arreglo:
nombre_variable[ndice] es valor del tipo <tipo> que puede ser asignado a una
variable, o pasado como parmetro, imprimirlo, etc. Aqu tambin vale la aclaracin de
que el ndice debe estar dentro del rango de definicin del arreglo, C++ no chequear
que esto sea cierto y devolver lo contenido en la posicin de memoria
correspondiente a un arreglo de mayor longitud, el dato obtenido de esta manera es
basura.
EJEMPLO:
El siguiente programa realiza la lectura de 10 datos y calcula la suma de los mismos:
#include <stdio.h>
main()
Pag.51

{
int i;
int sum;
int x[10];
sum=0;
for (i=0; i<10; i++)
{
printf (INTRODUCE EL DATO % d ,

i);

scanf (%d, &x[i]);


sum = sum + x[i];
}
printf (EL VECTOR ORIGINAL ES :);
for (i = 0; i<10; i ++]);
printf (%d , x[i]);
printf (/n LA SUMA DEL VECTOR ES : % d, sum);
}

2.12.2

Arreglos Bidimensionales (MATRICES)

Una matriz es un arreglo de dos dimensiones, y para especificar cualquier elemento,


debemos hacer referencia a dos ndices (que representan la posicin como rengln y
columna). Aunque no se justificar aqu, es conveniente mencionar que la
representacin matricial es puramente conceptual y con el nico fin de facilitar al
programador el manejo de los elementos, ya que la computadora almacena los datos
en una forma totalmente diferente.

2.12.2.1

Definicin

tipo nombre_de_variable [rango1][rango2];


donde:

Pag.52

tipo puede ser cualquier tipo de dato (int, float, char, etc.).

nombre_de_variable es el nombre del arreglo.

rango 1 corresponde al nmero de renglones que conforman el arreglo.

rango 2 corresponde al nmero de columnas.

El siguiente programa realiza la lectura de una matriz de 7 renglones y 15 columnas


(de una matriz de orden [7x15]) rengln por rengln).
#include <stdio.h>
#define ren 7
#define col 15
main ()
{
int i, j;
int x [ren][col];
for (i=0; i<ren; i++)
for(j=0; j<col ; j ++)
{
printf (INTRODUCE EL ELEMENTO A (%d, %d) , I, j);
scanf (%d, &x [i] [j]);
}
}
Ejercicios:
1. Hacer un programa que lea diez valores enteros en un arreglo desde el teclado y
calcule y muestre: la suma, el valor medio, el mayor y el menor.
2. Hacer un programa que lea diez valores enteros en un arreglo y los muestre en
pantalla. Despus que los ordene de menor a mayor y los vuelva a mostrar. Y
finalmente que los ordene de mayor a menor y los muestre por tercera vez. Para
ordenar
la
lista
usar
el
mtodo
de
la
burbuja.
Pag.53

3. Hacer un programa que lea 25 valores enteros en una tabla de 5 por 5, y que
despus muestre la tabla y las sumas de cada fila y de cada columna. Procura que la
salida
sea
clara.
4. Escribir un programa que lea un arreglo de cualquier tipo (entero, flotante, char), y
revise el arreglo para encontrar un valor en particular digitado por el usuario, la salida
es
la
posicin
del
arreglo
en
que
se
encuentra.
5. Leer un texto, un carcter a la vez desde la entrada estndar (que es el teclado), e
imprimirlo en forma invertida. Leer hasta que se encuentre un final-de-datos (teclear
CONTROL-Z
para
generarlo).
6. Escribir un programa para leer un texto hasta el fin-de-datos, y mostrar informacin
del texto , es decir nmero de palabras, longitud de las palabras, etc.

Pag.54

2.13 REGISTROS
2.13.1

CONCEPTOS GENERALES
2.13.1.1

CONCEPTO DE CAMPO

En informtica un campo es un espacio de almacenamiento para un dato


particular. En las bases de datos, un campo es la mnima unidad de informacin a la
que se puede acceder. En las hojas de clculo los campos son llamados celdas. La
mayora de los campos tienen atributos asociados a ellos. Por ejemplo, algunos
campos son numricos mientras otros almacenan texto, tambin vara el tamao de
estos. Adicionalmente, cada campo tiene un nombre.

2.13.1.2

CONCEPTO DE REGISTRO

En informtica, y concretamente en el contexto de una base de datos


relacional, un registro (tambin llamado fila o tupla) representa un tem nico de
datos implcitamente estructurados en una tabla. En trminos simples, una tabla de
una base de datos puede imaginarse formada de filas y columnas o campos. Cada fila
de una tabla representa un conjunto de datos relacionados, y todas las filas de la
misma tabla tienen la misma estructura.
La estructura implcita de un registro y el significado de los valores de sus
campos exige que dicho registro sea entendido como una sucesin de datos, uno en
cada columna de la tabla. La fila se interpreta entonces como una variable relacional
compuesta por un conjunto de tuplas, cada una de las cuales consta de dos tems: el
nombre de la columna relevante y el valor que esta fila provee para dicha columna.
REGISTRO: Es una estructura de datos homogneos o no a los cuales se les
llama campos tales que se accede a ellos mediante su propio nombre. Tienen un
nmero ilimitado de elementos y no tienen porque guardar un orden natural en
memoria.

2.13.2

Pag.55

DEFINICION

2.13.2.1
2.13.2.2

DEFINICION DE CAMPOS
DEFINICION DE REGISTROS

Una ESTRUCTURA es una coleccin de datos elementales (bsicos) de


diferentes tipos, lgicamente relacionados. A una estructura se le da tambin el
nombre de REGISTRO. Crear una estructura es definir un nuevo tipo de datos. En la
definicin de la estructura se especifican los elementos que la componen as como sus
tipos. Cada elemento de una estructura se denomina miembro (CAMPO). Declaracin
de una estructura:
struct nombre_estructura
{
tipo nombre_variable;
tipo nombre_variable;
tipo nombre_variable;
...
} variables_estructura;

Ejemplo:
struct Registro {
int a;
float b;
unsigned int c;
unsigned int d;
};

Esto permite agrupar un conjunto de variables en una nica estructura. Para crear
una variable de este tipo, bastar con hacer referencia a esta estructura. Las variables
o campos de esta estructura se referencian utilizando un punto.

MANIPULACION
MANIPULACION DE CAMPOS
MANIPULACION DE REGISTROS

Por ejemplo, podra utilizarse la estructura anterior en la siguiente forma:


void main (void)
{
struct Registro Reg;
Reg.a
Reg.b
Reg.c
Reg.d
}

Pag.56

=
=
=
=

-10;
20.3;
15;
Registro.c * 2;

Es posible cargar una estructura con un valor inicial. Por ejemplo, en el caso anterior
podra escribirse:
void main (void)
{
struct Registro Reg = {-10, 20.3, 15, 15*2};
struct Registro Reg2;
Reg2 = Reg;
variable */
}

/* Es posible copiar registros como cualquier otra

No existe ninguna funcin que imprima el contenido de un registro. Para ello debe
definirse una funcin que lo haga.

2.13.3

Enumeraciones

El tipo de dato enumeracin consiste en un conjunto de constantes numricas,


llamadas enumeradores ('enumerators' en ingls). Dichas constantes pueden tomar
cualquier valor arbitrario (entero). Si no se lo especifica, se entiende cero para el
primer valor, y uno ms que el anterior para los restantes. Por ejemplo:
enum DiasSemana
{
DOMINGO,
LUNES,
MARTES,
MIERCOLES,
JUEVES,
VIERNES,
SABADO
};

Para definir una variable de este tipo deber utilizarse:


enum DiasSemana Dia;
/* En C++ est permitido omitir la palabra enum al
definir una variable, en C no */
Dia = LUNES;

En este caso, DOMINGO tendr el valor 0, LUNES el 1 y as sucesivamente.


Es posible asignar un valor especfico a cada elemento, incluso valores repetidos:
enum DiasSemana
{
DOMINGO = 10,
LUNES,
/* Se utilizar el valor del elemento de arriba + 1 */
MARTES,
MIERCOLES = 15,

Pag.57

JUEVES,
VIERNES,
SABADO = 10 /* Repito un valor ya utilizado */
};

En este caso, tanto SABADO como DOMINGO tendrn el valor 10, LUNES tendr el
11, MARTES el 12, MIERCOLES el 15, JUEVES el 16 y VIERNES 17.
Si bien una variable de tipo enum almacenar un entero no est permitido asignarle
directamente valores de este tipo. Por ejemplo, el cdigo:
Dia = 15;

sera incorrecto, an cuando MIERCOLES tenga el valor 15.


S es posible realizar esta operacin utilizando algo llamado cast, que se ver ms
adelante, en este mismo captulo. Por ahora simplemente diremos que es posible
realizar esta operacin de la siguiente forma.
Dia = (enum DiasSemana) 15;

Tambin es sintcticamente posible asignar un valor invlido, como en el siguiente


ejemplo:
Dia = (enum DiasSemana) 4257;

pero en este caso los resultados no estn definidos.

2.13.4

Uniones

Una unin es una agrupacin de variables bajo una nica denominacin, pero en la
cual todas ellas comparten una misma zona de memoria. Segn como se la acceda,
dicha zona de memoria ser utilizada para almacenar un tipo de dato diferente.
Veamos un ejemplo:

Ejemplo : Uniones
union MiUnion{
char c;
int n;
float f;
double d;
};
void main(void)
{
MiUnion u;
u.d = 10.0 / 3.0;
printf ("u como double = %f\n", u.d);
printf ("u como float = %f\n", u.f);

Pag.58

printf ("u como int = %d\n", u.n);


printf ("u como char = %d\n", u.c);

Este ejemplo es correcto. Sin embargo no debe leerse nunca una variable de una
forma diferente a como fue escrita, por ejemplo, si u se escribe como int no debe
leerse nunca como double. Las uniones son utilizadas principalmente para almacenar
datos particulares de un tipo de dato ms general. En C++ este problema se resuelve
de una forma diferente, con el concepto de herencia que se ver ms adelante, razn
por la cual las uniones son rara vez utilizadas.
Para terminar con el tema, veamos un par de ejemplos, el los que se utilicen
estructuras, enumeraciones y uniones:

Ejemplo : Estructuras complejas (1)


/* estructura para almacenar informacin sobre una figura,
a dibujar en pantalla */
enum TipoFigura {CUADRADO, RECTANGULO,CIRCULO};
struct TPosicion
{
double x0, y0;
};
struct TFigura{
enum TipoFigura;
unsigned Color;
TPosicion Pos;
union Datos
{
double Lado;
struct Lados
{
double Ancho;
double Alto;
}
double Radio;
};
};

Ejemplo : Estructuras complejas (2)


enum TipoMisil {TIERRATIERRA, TIERRAAIRE, AIRETIERRA, AIREAIRE};
enum TipoDureza {DEBIL, MEDIA, FUERTE}
/* Estructura para almacenar los datos de un misil */
struct TMisil
{
double x,y,z;
/* Posicin del misil */
double vx, vy, vz; /* Velocidad */
enum TipoMisil;
union Blanco
{
struct Avion
{

Pag.59

double x,y,z;
double vx,vy,vz;

};

};
struct Edificio
{
double x,y;
TipoDureza Dureza;
}

};

Esta estructura permite almacenar la informacin de un misil. En este caso, el blanco u


objetivo del misil nunca ser un avin y un edificio al mismo tiempo. Por ello se utiliza
una unin para almacenar los datos del objetivo. Ambas estructuras utilizarn la misma
rea de memoria, y el programador deber saber cmo tratarla.

2.13.5

Definicin de nuevos nombres para tipos de datos

Pueden definirse tipos de datos o nuevos nombres para los ya existentes usando la
palabra reservada typedef. Esta se utiliza de la siguiente forma:
typedef definicin_del_tipo nuevo_nombre_del_tipo;

Por ejemplo, si se quisiese llamar byte al tipo de dato unsigned char, debera escribir:
typedef unsigned char byte;

Tambin podra utilizar typedef para abreviar el nombre de una estructura. Por
ejemplo, en ejemplo de la seccin anterior, donde se defina el tipo de dato struct
Registro, podra abreviar estas dos palabras en una sla escribiendo:
struct Registro {
int a;
float b;
unsigned int c;
unsigned int d;
};
typedef struct Registro TRegistro;

Estas lneas pueden escribirse en forma ms resumida como sigue:


typedef struct Registro {
int a;
float b;
unsigned int c;
unsigned int d;
} TRegistro;

con lo cual, para crear este tipo de dato podra escribir:


TRegistro Reg;

Pag.60

2.13.6

Convirtiendo tipos de datos (cast)

En C est permitido realizar conversiones de un tipo de dato a otro, sin mayor


inconveniente. Por ejemplo, podra escribirse:
Ejemplo : Conversin de tipos (cast) (1)
void main(void)
{
int a;
unsigned int b;
a = 10;
b = a;
}

Qu valor tomar b? La respuesta es simple, 10. Pero que ocurrira en el caso


siguiente?:
void main (void)
{
int a;
unsigned int b;

a = -1;
b = a;

Para responder esta pregunta es necesario analizar la representacin de -1 en binario.


Un valor entero -1 tiene la siguiente representacin binaria, en un sistema de 16 bits:
11111111 11111111. Si tratamos de leer este valor en decimal, considerndolo un
nmero positivo obtendremos en valor 65535, es decir que b recibir este valor.
Para evitar problemas de este tipo, el compilador suele advertir con un warning
cuando se realizan conversiones de datos no especificadas.
Pueden realizarse tambin operaciones entre nmeros enteros y de punto flotante. En
este caso el compilador se encarga de la conversin. Por ejemplo:
{
float a;
int b;

a = 20 / 3;
b = a;

Pag.61

En este caso a recibir en valor 6.66666, y b este valor, pero con la parte decimal
truncada a 0, es decir, 6.
La mayora de los compiladores emiten mensajes de advertencia cuando se realizan
operaciones entre datos de distinto tipo, y lo correcto es no hacer esto. Para realizar
operaciones entre datos de distinto tipo, debe realizarse una conversin de tipo. Esto
se hace encerrando entre parntesis el tipo de dato al que se quiere convertir. Esto se
conoce con el nombre de cast, y la operacin de realizar esta conversin con el
nombre de casting. Por ejemplo, en los casos anteriores se tendra:
{

int a;
unsigned int b;
float c;
a = -1;
b = (unsigned int) a;
c = (float) a;

Ejemplo 5.5: Casting


typedef unsigned char byte;
byte prom (byte a, byte b, byte c)
{
byte result;
result = (byte)(((unsigned)a + (unsigned)b + (unsigned)c) / 3);
}

return retult;

La conversin de tipos puede realizarse an sin que se cambie el tipo de variable.


Supongamos que se requiera calcular el promedio de 3 nmeros enteros de 8 bits, sin
signo, llamados a, b y c.
Desde ya que la funcin promedio retornar un entero de 8 bits, ya que el resultado
estar acotado a los valores recibidos. Vimos anteriormente que este clculo no lo
podemos realizar en la forma: a/3+b/3+c/3, ya que al realizarse la divisin se trunca la
parte decimal. Por ejemplo, el promedio de 2, 2, 2 sera 0.
La segunda alternativa consiste en realizar la suma primero, y luego la divisin
(a+b+c)/3.
Pero qu ocurrira si la suma superase el nmero 255, que es el mximo entero
representable con 8 bits?
Rta: El resultado de la suma se trucara quedndose nicamente con los 8 bits menos
significativos, y el resultado sera incorrecto.
Cmo solucionar este problema? La respuesta consiste en realizar este clculo con
nmeros de mayor precisin. Veamos el ejemplo:
Pag.62

typedef unsigned char byte;


byte prom (byte a, byte b, byte c)
{
byte result;
result = (byte) (((unsigned)a + (unsigned)b + (unsigned)c) / 3);
}

return retult;

Notar la forma en que se realiz la operacin. En primer lugar se convirti cada una de
las tres variables a un entero de mayor precisin, luego se efectu la suma de las tres
y la divisin por 3. Finalmente se convirti el resultado en un entero de 8 bits y se lo
copi en la variable result.

2.13.7

Ejercicios

1 - Defina un tipo de dato complejo, que almacene dos enteros llamados Real e Imag.
2 - Defina dos funciones que tomen un par de datos de tipo complejo y devuelvan su
suma y diferencia, respectivamente.
3 - Escriba una funcin que devuelva la parte real de un nmero complejo, convertida a
punto flotante.

Pag.63

2.14 ARCHIVOS
2.14.1

CONCEPTOS GENERALES

CAMPO
REGISTRO
ARCHIVO

Muy a menudo necesitamos almacenar cierta cantidad de datos de forma ms


o menos permanente. La memoria del ordenador es voltil, y lo que es peor, escaso y
caro. De modo que cuando tenemos que guardar nuestros datos durante cierto tiempo
tenemos que recurrir a sistemas de almacenamiento ms econmicos, aunque sea a
costa de que sean ms lentos.
Durante la historia de los ordenadores se han usado varios mtodos distintos
para el almacenamiento de datos. Al principio se recurri a cintas de papel perforadas,
despus a tarjetas perforadas. A continuacin se pas al soporte magntico,
empezando por grandes rollos de cintas magnticas abiertas.
Hasta aqu, todos los sistemas de almacenamiento externo eran secuenciales,
es decir, no permitan acceder al punto exacto donde se guardaba la informacin sin
antes haber partido desde el principio y sin haber ledo toda la informacin, hasta el
punto donde se encontraba la que estbamos buscando.
Con las cintas magnticas empez lo que con el tiempo sera el acceso
aleatorio a los datos. Se poda reservar parte de la cinta para guardar cierta
informacin sobre la situacin de los datos, y aadir ciertas marcas que hicieran ms
sencillo localizarla.
Pero no fue hasta la aparicin de los discos magnticos cuando sta tcnica
lleg a su sentido ms amplio. En los discos es ms sencillo acceder a cualquier punto
de la superficie en poco tiempo, ya que se accede al punto de lectura y escritura
usando dos coordenadas fsicas. Por una parte la cabeza de lectura/escritura se
puede mover en el sentido del radio del disco, y por otra el disco gira
permanentemente, con lo que cualquier punto del disco pasa por la cabeza en un
tiempo relativamente corto. Esto no pasa con las cintas, donde slo hay una
coordenada fsica.
Con la invencin y proliferacin de los discos se desarrollaron los ficheros de
acceso aleatorio, que permiten acceder a cualquier dato almacenado en un fichero en
relativamente poco tiempo.
Actualmente, los discos duros tienen una enorme capacidad y son muy rpidos,
aunque an siguen siendo lentos, en comparacin con las memorias RAM. El caso de
los CD es algo intermedio. En realidad son secuenciales en cuanto al modo de guardar
los datos, cada disco slo tiene una pista de datos grabada en espiral. Sin embargo,
Pag.64

este sistema, combinado con algo de memoria RAM, proporciona un acceso muy
prximo al de los discos duros.

2.14.2

Clasificacin de Archivos

En cuanto al tipo de acceso, en C y C++ podemos clasificar los archivos segn varias
categoras:
Dependiendo de la direccin del flujo de datos:
De entrada: los datos se leen por el programa desde el archivo.
De salida: los datos se escriben por el programa hacia el archivo.
De entrada/salida: los datos pueden se escritos o ledos.
Dependiendo del tipo de valores permitidos a cada byte:
De texto: slo estn permitidos ciertos rangos de valores para cada byte.
Algunos bytes tienen un significado especial, por ejemplo, el valor hexadecimal
0x1A marca el fin de fichero. Si abrimos un archivo en modo texto, no ser
posible leer ms all de un byte con ese valor, aunque el fichero sea ms largo.
Binarios: estn permitidos todos lo valores para cada byte. En estos archivos
el final del fichero se detecta de otro modo, dependiendo del soporte y del
sistema operativo. La mayora de las veces se hace guardando la longitud del
fichero. Cuando queramos almacenar valores enteros, o en coma flotante, o
imgenes, etc, deberemos usar este tipo de archivos.
Segn el tipo de acceso:
Archivos secuenciales: imitan el modo de acceso de los antiguos ficheros
secuenciales almacenados en cintas magnticas y
Archivos de acceso aleatorio: permiten acceder a cualquier punto de ellos
para realizar lecturas y/o escrituras.
Segn la longitud de registro:
Longitud variable: en realidad, en este tipo de archivos no tiene sentido
hablar de longitud de registro, podemos considerar cada byte como un registro.
Tambin puede suceder que nuestra aplicacin conozca el tipo y longitud de
cada dato almacenado en el archivo, y lea o escriba los bytes necesarios en
cada ocasin. Otro caso es cuando se usa una marca para el final de registro,
por ejemplo, en ficheros de texto se usa el carcter de retorno de lnea para
eso. En estos casos cada registro es de longitud diferente.
Longitud constante: en estos archivos los datos se almacenan en forma de
registro de tamao constante. En C usaremos estructuras para definir los
registros. C dispone de funciones de librera adecuadas para manejar este tipo
de ficheros.
Mixtos: en ocasiones pueden crearse archivos que combinen los dos tipos de
registros, por ejemplo, dBASE usa registros de longitud constante, pero aade
un registro especial de cabecera al principio para definir, entre otras cosas, el
tamao y el tipo de los registros.
Pag.65

Es posible crear archivos combinando cada una de estas categoras, por


ejemplo: archivos secuenciales de texto de longitud de registro variable, que son los
tpicos archivos de texto. Archivos de acceso aleatorio binarios de longitud de registro
constante, normalmente usados en bases de datos. Y tambin cualquier combinacin
menos corriente, como archivos secuenciales binarios de longitud de registro
constante, etc.

Modo de apertura de un archivo


Archivo para slo lectura. El fichero debe existir.

r
w
a
rb
wb
ab
r+
w+
a+
rb+
wb+
ab+

Se abre para escritura, se crea un fichero nuevo o se sobrescribe si ya


existe.
Aadir, se abre para escritura, el cursor se sita al final del fichero. Si
el fichero no existe, se crea.
Abre un archivo binario para slo lectura
Crea un archivo binario para escritura
Aade informacin a un archivo binario
Lectura y escritura. El fichero debe existir.
Lectura y escritura, se crea un fichero nuevo o se sobrescribe si ya
existe.
Aadir, lectura y escritura, el cursor se sita al final del fichero. Si el
fichero no existe, se crea.
Abre un archivo binario para operaciones de lectura/escritura
Crea archivo binario para operaciones de lectura/escritura
Aade informacin a un archivo binario para operaciones de
lectura/escritura

Cuando un archivo es abierto, se espera que exista, de no ser as se intentara crearlo.


En el modo w cualquier informacin previa en el archivo es borrada. Como se puede
apreciar, si no se especifica ninguna otra cosa, el archivo abierto es de tipo texto.
La funcin que realiza la apertura de un archivo es fopen() y tiene la siguiente
funcin prototipo:

FILE *fopen(const char *nombre_archivo, const char


*modo)
Donde:
FILE

nombre_archiv
o
modo

Pag.66

Es un tipo especificado en el archivo de cabecera stdio.h. Cuando


la operacin es exitosa se entrega un puntero al archivo, cuando la
operacin falla se entrega un NULL
Es el nombre del archivo que se debe abrir
Es alguno de los modos descritos anteriormente.

Ejemplo:
Para abrir un nuevo archivo llamado alumnos en el cual slo se realizara
escritura de texto, se deben escribir las siguientes sentencias:

FILE *pfArch;
pfArch = fopen(alumnos, w);
Para realizar una apertura en la cual se desee leer el contenido se tendr:

pfArch = fopen(alumnos, r);


Y para continuar aadiendo informacin se tendr:

pfArch = fopen(alumnos, r);


Si la apertura del archivo no es exitosa por cualquier razn, la funcin
fopen() entrega un valor NULL. Una operacin de apertura por escritura puede
fallar, por ejemplo si el medio est protegido para escritura, si el archivo tiene la
propiedad de solo lectura o porque el medio esta daado. Una operacin de apertura
para lectura puede fallar porque el archivo no existe, o la ruta especificada es errnea.
Cuando un archivo ya no sea necesitado por un programa, es recomendable
que sea cerrado, es decir, se elimine la conexin entre el programa y el archivo. La
funcin fclose() cumple con dicha tarea. Su funcin prototipo es la siguiente:

int fclose(FILE *puntero_archivo);


Donde:
puntero_archiv
o

Es el puntero al archivo que se desea cerrar.

Por ejemplo, para cerrar el archivo del ejemplo anterior basta con escribir:

fclose(pfArch);

2.14.3

Creacin de un archivo de datos.

Existen diversas funciones que nos permiten escribir o leer un archivo que ha
sido abierto con anterioridad. Las funciones putc() y fputc() son equivalentes, con
ellas se puede escribir un carcter en un archivo. Su funcin prototipo es:

Int fputc(int carcter, FILE *puntero_archivo)


Ejemplo de programa utilizando fopen, fputc, fclose.
/* Archivo: Leecadar.c
Uso de archivos */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

Pag.67

#include <conio.h>
#ifndef SALIDA
#define SALIDA'@'
#endif
void main(void)
{
FILE *pfArchivo;
char szLinea[80];
char szArchivo[12];
register int iContador;
/* Pide el nombre del szArchivo a crear */
printf("\n Digite el nombre del szArchivo: ");
gets(szArchivo);
if (strlen(szArchivo) == 0)
{
printf("\n Se omitio nombre del Archivo");
}
else
{
/* Creacion del szArchivo */
pfArchivo=fopen(szArchivo,"w");
if ( pfArchivo != NULL )
{
/* Si la creacion fue exitosa captura una szLinea de texto a la vez */
/*clrscr();*/
szLinea[0]='\0';
printf("\n @ Termina captura\n Capturando...\n");
/* Mientras no se de caracter de salida */
while (szLinea[0] != SALIDA)
{
gets(szLinea);
iContador=0;
while (szLinea[iContador] != '\0'&& szLinea[0] != SALIDA)
{
/* Guarda un caracter a la vez */
fputc(szLinea[iContador],pfArchivo);
iContador++;
}
fputc('\n',pfArchivo);
}
/* Cierra el szArchivo */
fclose(pfArchivo);
}
else
{
printf("\n No fue posible realizar la apertura");
}
}
}

Pag.68

2.14.4

Archivos de Acceso Aleatorio

Los archivos de acceso aleatorio son ms verstiles, permiten acceder a


cualquier parte del fichero en cualquier momento, como si fueran arrays en memoria.
Las operaciones de lectura y/o escritura pueden hacerse en cualquier punto del
archivo.
En general se suelen establecer ciertas normas para la creacin, aunque no todas
son obligatorias:
1. Abrir el archivo en un modo que te permita leer y escribir. Esto no es
imprescindible, es posible usar archivos de acceso aleatorio slo de lectura o
de escritura.
2. Abrirlo en modo binario, ya que algunos o todos los campos de la estructura
pueden no ser caracteres.
3. Usar funciones como fread y fwrite, que permiten leer y escribir registros de
longitud constante desde y hacia un fichero.
4. Usar la funcin fseek para situar el puntero de lectura/escritura en el lugar
apropiado de tu archivo.
Por ejemplo, supongamos que nuestros registros tienen la siguiente estructura:
struct stRegistro {
char Nombre[34];
int dato;
int matriz[23];
}reg;

Teniendo en cuenta que los registros empiezan a contarse desde el cero, para hacer
una lectura del registro nmero 6 usaremos:
fseek(fichero, 5*sizeof(stRegistro), SEEK_SET);
fread(&reg, sizeof(stRegistro), 1, fichero);

Anlogamente, para hacer una operacin de escritura, usaremos:


fseek(fichero, 5*sizeof(stRegistro), SEEK_SET);
fwrite(&reg, sizeof(stRegistro), 1, fichero);

Despus de cada operacin de lectura o


escritura, el cursor del fichero se actualiza
Informacin automticamente a la siguiente posicin, as que
es buena idea hacer siempre un fseek antes de
un fread o un fwrite.

Pag.69

2.14.5

Calcular la longitud de un fichero

Para calcular el tamao de un fichero, ya sea en bytes o en registros se suele


usar el siguiente procedimiento:
long nRegistros;
long nBytes;
fseek(fichero, 0, SEEK_END); // Colocar el cursor al final
nBytes = ftell(fichero); // Tamao en bytes
nRegistros = ftell(fich)/sizeof(stRegistro); // Tamao

2.14.6

del fichero
en registros

Borrar registros

Borrar registros puede ser complicado, ya que no hay ninguna funcin de


librera estndar que lo haga.
Es su lugar se suele usar uno de estos dos mtodos:
1. Marcar el registro como borrado o no vlido, para ello hay que aadir un campo
extra en la estructura del registro:
struct stRegistro {
char Valido; // Campo que indica si el registro es vlido
char Nombre[34];
int dato;
int matriz[23];
};

Si el campo Valido tiene un valor prefijado, por ejemplo 'S' o ' ', el registro es
vlido. Si tiene un valor prefijado, por ejemplo 'N' o '*', el registro ser invlido o se
considerar borrado.
De este modo, para borrar un registro slo tienes que cambiar el valor de ese
campo.
Pero hay que tener en cuenta que ser el programa el encargado de tratar los
registros del modo adecuado dependiendo del valor del campo Valido, el hecho de
marcar un registro no lo borra fsicamente.
Si se quiere elaborar ms, se puede mantener un fichero auxiliar con la lista de
los registros borrados. Esto tiene un doble propsito:
o
o

Que se pueda disear una funcin para sustituir a fseek() de modo que
se tengan en cuenta los registros marcados.
Que al insertar nuevos registros, se puedan sobrescribir los
anteriormente marcados como borrados, si existe alguno.

2. Hacer una copia del fichero en otro fichero, pero sin copiar el registro que se
quiere borrar. Este sistema es ms tedioso y lento, y requiere cerrar el fichero y
Pag.70

borrarlo o renombrarlo, antes de poder usar de nuevo la versin con el registro


eliminado.

Lo normal es hacer una combinacin de ambos, durante la ejecucin normal del


programa se borran registros con el mtodo de marcarlos, y cuando se cierra la
aplicacin, o se detecta que el porcentaje de registros borrados es alto o el usuario as
lo decide, se "empaqueta" el fichero usando el segundo mtodo.

2.14.7

Ejemplo:

A continuacin se incluye un ejemplo de un programa que trabaja con registros de


acceso aleatorio, es un poco largo, pero bastante completo:
// aleatory.cpp: Ejemplo de ficheros de acceso aleatorio.
#include <stdio.h>
#include <stdlib.h>
struct stRegistro {
char valido; //Campo que indica si el registro es vlido S>Vlido, N->Invlido
char nombre[34];
int dato[4];
};
int Menu();
void Leer(struct stRegistro *reg);
void Mostrar(struct stRegistro *reg);
void Listar(long n, struct stRegistro *reg);
long LeeNumero();
void Empaquetar(FILE **fa);
int main()
{
struct stRegistro reg;
FILE *fa;
int opcion;
long numero;
fa = fopen("alea.dat", "r+b");
// Este modo permite leer y
escribir
if(!fa) fa = fopen("alea.dat", "w+b"); // si el fichero no existe,
lo crea.
do {
opcion = Menu();
switch(opcion) {
case '1': // Aadir registro
Leer(&reg);
// Insertar al final:
fseek(fa, 0, SEEK_END);
fwrite(&reg, sizeof(struct stRegistro), 1, fa);
break;
case '2': // Mostrar registro
system("cls");
printf("Mostrar registro: ");
numero = LeeNumero();
fseek(fa, numero*sizeof(struct stRegistro), SEEK_SET);
fread(&reg, sizeof(struct stRegistro), 1, fa);

Pag.71

Mostrar(&reg);
break;
case '3': // Eliminar registro
system("cls");
printf("Eliminar registro: ");
numero = LeeNumero();
fseek(fa, numero*sizeof(struct stRegistro), SEEK_SET);
fread(&reg, sizeof(struct stRegistro), 1, fa);
reg.valido = 'N';
fseek(fa, numero*sizeof(struct stRegistro), SEEK_SET);
fwrite(&reg, sizeof(struct stRegistro), 1, fa);
break;
case '4': // Mostrar todo
rewind(fa);
numero = 0;
system("cls");
printf("Nombre
Datos\n");
while(fread(&reg, sizeof(struct stRegistro), 1, fa))
Listar(numero++, &reg);
system("PAUSE");
break;
case '5': // Eliminar marcados
Empaquetar(&fa);
break;

}
} while(opcion != '0');
fclose(fa);
return 0;

// Muestra un men con las opciones disponibles y captura una opcin


del usuario
int Menu()
{
char resp[20];
do {
system("cls");
printf("MENU PRINCIPAL\n");
printf("--------------\n\n");
printf("1- Insertar registro\n");
printf("2- Mostrar registro\n");
printf("3- Eliminar registro\n");
printf("4- Mostrar todo\n");
printf("5- Eliminar registros marcados\n");
printf("0- Salir\n");
fgets(resp, 20, stdin);
} while(resp[0] < '0' && resp[0] > '5');
return resp[0];
}
// Permite que el usuario introduzca un registro por pantalla
void Leer(struct stRegistro *reg)
{
int i;
char numero[6];
system("cls");
printf("Leer registro:\n\n");
reg->valido = 'S';
printf("Nombre: ");
fgets(reg->nombre, 34, stdin);

Pag.72

// la funcin fgets captura el retorno de lnea, hay que


eliminarlo:
for(i = strlen(reg->nombre)-1; i && reg->nombre[i] < ' '; i--)
reg->nombre[i] = 0;
for(i = 0; i < 4; i++) {
printf("Dato[%1d]: ", i);
fgets(numero, 6, stdin);
reg->dato[i] = atoi(numero);
}
}
// Muestra un registro en pantalla, si no est marcado como borrado
void Mostrar(struct stRegistro *reg)
{
int i;
system("cls");
if(reg->valido == 'S') {
printf("Nombre: %s\n", reg->nombre);
for(i = 0; i < 4; i++) printf("Dato[%1d]: %d\n", i, reg>dato[i]);
}
system("PAUSE");
}
// Muestra un registro por pantalla en forma de listado,
// si no est marcado como borrado
void Listar(long n, struct stRegistro *reg)
{
int i;
if(reg->valido == 'S') {
printf("[%6ld] %-34s", n, reg->nombre);
for(i = 0; i < 4; i++) printf(", %4d", reg->dato[i]);
printf("\n");
}
}
// Lee un nmero suministrado por el usuario
long LeeNumero()
{
char numero[6];
fgets(numero, 6, stdin);
return atoi(numero);
}
// Elimina los registros marcados como borrados
void Empaquetar(FILE **fa)
{
FILE *ftemp;
struct stRegistro reg;
ftemp = fopen("alea.tmp", "wb");
rewind(*fa);
while(fread(&reg, sizeof(struct stRegistro), 1, *fa))
if(reg.valido == 'S')
fwrite(&reg, sizeof(struct stRegistro), 1, ftemp);
fclose(ftemp);
fclose(*fa);
remove("alea.bak");
rename("alea.dat", "alea.bak");
rename("alea.tmp", "alea.dat");
*fa = fopen("alea.dat", "r+b");
}

Pag.73

2.15 APUNTADORES
Los punteros proporcionan la mayor parte de la potencia al C y C++, y marcan
la principal diferencia con otros lenguajes de programacin. Una buena comprensin y
un buen dominio de los punteros pondr en tus manos una herramienta de gran
potencia. Un conocimiento mediocre o incompleto te impedir desarrollar programas
eficaces.
La memoria RAM de un ordenador est compuesta por unidades bsicas
llamadas bits. Cada bit slo puede tomar dos valores, normalmente denominados alto
y bajo, 1 y 0. Pero trabajar con bits no es prctico, y por eso se agrupan. Cada grupo
de 8 bits forma un byte u octeto. En realidad el microprocesador, y por lo tanto nuestro
programa, slo puede manejar directamente bytes o grupos de dos o cuatro bytes.
Para acceder a los bits hay que acceder antes a los bytes. Y aqu llegamos al quid,
cada byte tiene una direccin, llamada normalmente direccin de memoria.
La unidad de informacin bsica es la palabra, dependiendo del tipo de
microprocesador una palabra puede estar compuesta por dos, cuatro, ocho o diecisis
bytes. Hablaremos en estos casos de plataformas de 16, 32, 64 128 bits. Se habla
indistintamente de direcciones de memoria, aunque las palabras sean de distinta
longitud. Cada direccin de memoria contiene siempre un byte. Lo que suceder
cuando las palabras sean de 32 bits es que accederemos a posiciones de memoria
que sern mltiplos de 4.
Un puntero es un tipo especial de variable que contiene, ni ms ni menos
que, una direccin de memoria.
Por supuesto, a partir de esa direccin de memoria puede haber cualquier tipo
de objeto: un char, un int, un float, un array, una estructura, una funcin u otro puntero.
Intentemos ver con mayor claridad el funcionamiento de los punteros. Podemos
considerar la memoria del ordenador como un gran array, de modo que podemos
acceder a cada celda de memoria a travs de un ndice. Podemos considerar que la
primera posicin del array es la 0 celda[0].
Si usamos una variable para almacenar el ndice, por ejemplo, ndice=0,
entonces celda[0] == celda[ndice]. Prescindiendo de la notacin de los arrays, el
ndice se comporta exactamente igual que un puntero.
El puntero ndice podra tener por ejemplo, el valor 3, en ese caso, *ndice
tendra el valor 'valor3'.
Las celdas de memoria existirn independientemente del valor de ndice, o
incluso de la existencia de ndice, por lo tanto, la existencia del puntero no implica
nada ms que eso, pero no que el valor de la direccin que contiene sea un valor
vlido de memoria.
Dentro del array de celdas de memoria existirn zonas que contendrn
programas y datos, tanto del usuario como del propio sistema operativo o de otros
programas, el sistema operativo se encarga de gestionar esa memoria, prohibiendo o
protegiendo determinadas zonas.
Pag.74

El propio puntero, como variable que es, ocupar ciertas direcciones de


memoria.
En principio, debemos asignar a un puntero, o bien la direccin de un objeto
existente, o bien la de uno creado explcitamente durante la ejecucin del programa. El
sistema operativo suele controlar la memoria, y no tiene por costumbre permitir el
acceso al resto de la memoria.

2.15.1

Declaracin de punteros.

Una variable puntero se declara como todas las variables. Debe ser del mismo
tipo que la variable apuntada. Su identificador va precedido de un asterisco (*):
int *punt;
*punt es una variable puntero que apunta a otra variable que contiene un dato de tipo
entero.
char *car:
Es un puntero a variable de tipo carcter.
Como pasa con todas las variables en C++, cuando se declaran slo se
reserva espacio para almacenarlas, pero no se asigna ningn valor inicial, el contenido
de la variable permanecer sin cambios, de modo que el valor inicial del puntero ser
aleatorio e indeterminado. Debemos suponer que contiene una direccin no vlida.
Si "punt" apunta a una variable de tipo "int", "*punt" ser el contenido de esa
variable, pero no olvides que "*punt" es un operador aplicado a una variable de tipo
"puntero a int", es decir "*punt" es una expresin, no una variable.

2.15.2

Obtener punteros a variables.

Para averiguar la direccin de memoria de cualquier variable usaremos el


operador de direccin (&), que leeremos como "direccin de".
Por supuesto, los tipos tienen que ser "compatibles", no podemos almacenar la
direccin de una variable de tipo "char" en un puntero de tipo "int".
Por ejemplo:
int A;
int *pA;
pA = &A;
Segn este ejemplo, pA es un puntero a int que apunta a la direccin donde se
almacena el valor del entero A.

Pag.75

2.15.3

Diferencia entre punteros y variables.

Declarar un puntero no crear un objeto. Por ejemplo: int *entero; no crea un


objeto de tipo "int" en memoria, slo crea una variable que puede contener una
direccin de memoria. Se puede decir que existe fsicamente la variable "entero", y
tambin que esta variable puede contener la direccin de un objeto de tipo "int". Lo
veremos mejor con otro ejemplo:
int A, B;
int *entero;
...
B = 213; /* B vale 213 */
entero = &A;
/* entero apunta a la direccin de la variable A
*/
*entero = 103; /* equivale a la lnea A = 103; */
B = *entero;
/* equivale a B = A; */
...
En este ejemplo vemos que "entero" puede apuntar a cualquier variable de tipo
"int", y que podemos hacer referencia al contenido de dichas variables usando el
operador de indireccin (*).
Como todas las variables, los punteros tambin contienen "basura" cuando son
declaradas. Es costumbre dar valores iniciales nulos a los punteros que no apuntan a
ningn sitio concreto:
entero = NULL;
caracter = NULL;
NULL es una constante, que est definida como cero en varios ficheros de cabecera,
como "stdio" o "iostream", y normalmente vale 0L.

2.15.4

Correspondencia entre arrays y punteros

Existe una equivalencia casi total entre arrays y punteros. Cuando declaramos
un array estamos haciendo varias cosas a la vez:

Declaramos un puntero del mismo tipo que los elementos del array, y que
apunta al primer elemento del array.
Reservamos memoria para todos los elementos del array. Los elementos de un
array se almacenan internamente en el ordenador en posiciones consecutivas
de la memoria.

La principal diferencia entre un array y un puntero es que el nombre de un array


es un puntero constante, no podemos hacer que apunte a otra direccin de memoria.
Adems, el compilador asocia una zona de memoria para los elementos del array,
cosa que no hace para los elementos apuntados por un puntero autntico.

Pag.76

Ejemplo:
int vector[10];
int *puntero;
puntero = vector; /* Equivale a puntero = &vector[0];
*puntero++; /* Equivale a vector[0]++; */
puntero++; /* puntero equivale a &vector[1] */

Qu hace cada una de estas instrucciones?:


La primera incrementa el contenido de la memoria apuntada por "puntero", que
es vector[0].
La segunda incrementa el puntero, esto significa que apuntar a la posicin de
memoria del siguiente "int", pero no a la siguiente posicin de memoria. El puntero no
se incrementar en una unidad, como tal vez sera lgico esperar, sino en la longitud
de un "int".
Anlogamente la operacin:
puntero = puntero + 7;

No incrementar la direccin de memoria almacenada en "puntero" en siete


posiciones, sino en 7*sizeof(int).
Otro ejemplo:
struct stComplejo {
float real, imaginario;
} Complejo[10];
stComplejo *p;
p = Complejo; /* Equivale a p = &Complejo[0]; */
p++; /* p == &Complejo[1] */

En este caso, al incrementar p avanzaremos las posiciones de memoria


necesarias para apuntar al siguiente complejo del array "Complejo". Es decir
avanzaremos sizeof(stComplejo) bytes.

2.15.5

Operaciones con punteros.

Aunque no son muchas las operaciones que se pueden hacer con los punteros, cada
una tiene sus peculiaridades.

Pag.77

2.15.6

Asignacin.

Ya hemos visto cmo asignar a un puntero la direccin de una variable. Tambin


podemos asignar un puntero a otro, esto har que los dos apunten a la misma
posicin:
int *q, *p;
int a;
q = &a; /* q apunta al contenido de a */
p = q; /* p apunta al mismo sitio, es decir, al contenido de a */

2.15.7

Operaciones aritmticas.

Tambin hemos visto como afectan a los punteros las operaciones de suma
con enteros. Las restas con enteros operan de modo anlogo. Pero, qu significan
las operaciones de suma y resta entre punteros?, por ejemplo:
int vector[10];
int *p, *q;
p = vector; /* Equivale a p = &vector[0]; */
q = &vector[4]; /* apuntamos al 5 elemento */
printf(%u, q-p);

El resultado ser 4, que es la "distancia" entre ambos punteros. Normalmente este tipo
de operaciones slo tendr sentido entre punteros que apunten a elementos del
mismo array. La suma de punteros no est permitida.

Pag.78

Gua de programas elaborados

#include <stdio.h>
#include <conio.h>
char cad[20]="Hola Buenos Dias\n";
char *punt; //declaracion de puntero.
void main(void)
{
//inicializacin de variable
punt=cad; //asignacion de direccion al puntero.
clrscr();
printf("a = %s", cad); //imprimo valor de variable
printf("\n&a = %x", cad); //imprimo direccin variable apuntada (en hexadecimal)
printf("\npunt = %x ", punt); //imprimo la direccin guardada (la variable apuntada)
printf("\n*punt = %s", punt); //imprimo el contenido de la direccin apuntada.
printf("\nTamao puntero %d Bytes", sizeof(punt));
getch();
}
#include <stdio.h>
#include <conio.h>
void main()
{
char carac='A', *r;
int a=12,b=45;
int *p, *q;
clrscr();
printf("Direccin de a=%p\n", &a); printf("Direccin de b=%p\n", &b);
printf("a = %d b = %d\n", a, b); printf("Direccin de caract = %p\n", &carac);
printf("carac = %c\n", carac); printf("Valor ASCII de carac = %d\n", carac);
printf("Direccin de p = %p\n", &p);
printf("Direccin de q = %p\n", &q);
printf("Direccin de r = %p\n", &r);
p = &a;
q = &b;
r = &carac;
printf("El puntero p apunta a la direccin: %p\n", p);
printf("Y su contenido es: %d\n", *p);
printf("El puntero q apunta a la direccin: %p\n", q);
printf("Y su contenido es: %d\n", *q);
printf("El puntero r apunta a la direccin: %p\n", r);
printf("Y el contenido de *r es: %d\n", *r);
printf("Como caracter ASCII *r contiene: %c\n", *r);
getch();
}
Pag.79

//Programa que suma un valor a una variable a travs de un puntero


#include <stdio.h>
#include <conio.h>
void main()
{
int a, *p;
a=5;
p=&a;
*p+=7; //*p=*p+7
printf("\nEl valor final de a es: %d", a);
getch();
}

#include <conio.h>
#include <stdio.h>
void main()
{
int mat[] = {1,2,3,4}, *pmat, i;
clrscr();
printf("\Empleamos notacin decimal\n");
printf("Hacemos que el puntero seale al primer elemento del array: pmat = mat");
pmat = mat;
//pmat=&mat[0]; //ES LO MISMO QUE pmat =mat
printf("\nComprobamos los valores: ");
printf("\nDireccin de inicio del array: mat = %u", &mat[0]);
getch();
printf("\nDireccin de pmat: &pmat = %u", &pmat);
getch();
printf("\nImprimimos las direcciones de memoria:\n");
for(i=0; i<4; i++)
{
printf("\n&mat[%u] = %u (pmat+%u) = %u ", i, &mat[i], i, (pmat+i));
printf(" mat[%u] = %u *(pat+%u) = %u" , i, mat[i], i, *(pmat+i));
}
getch();
}

Pag.80

BIBLIOGRAFA

Algoritmos y Programacin
Cristian Prez Berro
Nueva librera, 2007

Introduccin a la programacin estructurada en C.


Educaci (Universidad de Valencia).: Materials
Francisco A. Martnez Gil, Gregorio Martn Quetgls
Universitat de Valncia, 2003

Cmo programar en C++


Pearson: Educacin
Harvey M. Deitel, Paul J. Deitel
Pearson Educacin, 2003

Introduccin a la programacin en C
Marco A. Pea Basurto, Jos M. Cela Espn
Edicions UPC, 2000
Curso prctico de programacin en C y C++

Pag.81