Você está na página 1de 60

2.1) Estructura de un programa en C.

Todo programa escrito en C consta de una o ms funciones, una de las cuales se llama main. El programa siempre
comenzar por la ejecucin de la funcin main. Cada funcin debe contener:

Una cabecera de la funcin, que consta del nombre de la funcin, seguido de una lista opcional
de argumentos encerrados con parntesis.

Una lista de declaracin de argumentos, si se incluyen estos en la cabecera.

Una sentencia compuesta, que contiene el resto de la funcin.

Los argumentos son smbolos que representan informacin que se le pasa a la funcin desde otra parte del programa .
(Tambin se llaman parmetros a los argumentos).

Cada sentencia compuesta se encierra con un par de llaves, {.....}. Las llaves pueden contener combinaciones de
sentencias elementales (denominadas sentencias de expresin) y otras sentencias compuestas. As las sentencias
compuestas pueden estar anidadas, una dentro de otra. Cada sentencia de expresin debe acabar en punto y coma (;).

Los comentarios pueden aparecer en cualquier parte del programa, mientras estn situados entre los delimitadores
/* ................ */ (por ejemplo: /*esto es un ejemplo*/). Los comentarios son tiles para identificar los elementos
principales de un programa o simplemente para orientar a un posible usuario de ese cdigo.

Todo fichero fuente en C sigue la siguiente estructura; para verla ms claramente pondremos un ejemplo con sus
correspondientes comentarios, que nos vayan explicando cada una de las partes, muchas de las cosas que se vean, no se
conocen an, pero nos servirn para hacernos una idea de cmo se estructura un programa:

Ejemplo:

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

/*#include del sistema: Se deben especificar todos los ficheros de cabecera (ficheros con extensin .h)
correspondientes a las libreras de funciones utilizadas.
Son libreras implementadas y listas para que nosotros las usemos, con slo llamar a la funcin que tenga
implementada dentro dicha librera. Por ejemplo: la instruccin printf est incluida dentro de stdio.h, por tanto,
cuando decidamos usarla, tendremos que poner en esta seccin:
#include <stdio.h> */

#include <lista.h>

/* #include de la aplicacin: Ficheros de cabecera creados para el fichero fuente. Se puede decir que estos son los
que yo he creado, que son invocados escribiendo su nombre seguido de .h. (Ms tarde explicaremos cmo se crean).
Si lo pongo entre signos: < > (como lo tenemos en este ejemplo), dicha librera ser buscada en el directorio del
compilador INCLUDE que contiene las libreras. Si por el contrario pongo: #include "lista.h", entonces, dicha
librera ser buscada 1 en el directorio actual, y luego, si no est, ser buscada en el directorio del
compilador INCLUDE*/

extern void salida(void);


/* externvariables globales externas: Variables globales que voy a definir en otros mdulos que voy a
usar en este mdulo. A salida le hemos asignado el tipo de almacenamiento extern, pues tiene que ser
accedida desde otro archivo distinto de aquel en que es definida; por tanto, ha de ser una funcin
externa. */

#define CIERTO 1
#define FALSO 0

/* #define definicin de macros y constantes simblicas.*/

typedef struct {
int dia;
int mes;
int ano;
}FECHA;

/* typedef definicin de tipos: me sirve para crearme un tipo distinto de los preestablecidos de
partida.*/

int suma (int , int);

/* Declaracin de los prototipos de las funciones implementados en este mdulo: La declaracin de


una funcin le da informacin al compilador de una funcin que va a ser utilizada pero que todava no
ha sido implementada. En particular le dice al compilador qu tipo de datos requiere y cul devuelve la
funcin. En el ejemplo, la funcin con nombre suma
recibe dos nmeros enteros y da como salida otro nmero entero.*/
extern int a,b,c;

/* Declaracin de variables globales de este mdulo:


extern declaracin de funciones externas a este mdulo: Funciones que se utilizan en este
mdulo y que estn implementadas en otro mdulo.
static declaracin de las funciones internas no visibles para otros mdulos: Funciones que se
implementan en este mdulo y que no pueden ser utilizadas en otros mdulos. */

main(){
............
............
}
int suma(int x,int y){
...........
...........
}
/* Implementacin de las funciones: Se implementan todas las funciones del mdulo incluida la
funcin main().*/

NOTA: En un segundo archivo encontraramos la definicin de la funcin externa declarada en este primer archivo de
encima (extern void salida(void);), esta definicin ser:

...........
...........
extern void salida(void)
{
printf("Hola!");
return; /* salimos de la funcin, y volvemos al lugar donde se le llam sin devolver nada.*/
}
...........
...........
2.2) Identificadores y palabras clave.

a) Identificadores:

Los usamos para nombrar a varios elementos de un programa, como variables, funciones y arrays. Un identificador est
formado por letras (a|b|c|...|z|A|B|C|...|Z), y dgitos (0|1|2|3|...|9), la nica restriccin que se nos pone es que el primer
carcter tiene que ser una letra. El lenguaje C distingue entre maysculas y minsculas, entonces hemos de tener
cuidado si se intercambian dentro de un mismo identificador (aunque esto no es una buena prctica). El carcter
subrayado (_), tambin lo podemos incluir como una letra.

Ejemplos.

Para acabar con el tema de los identificadores, diremos, que su longitud mxima en el estndar ANSI es de 31
caracteres, aunque algunas implementaciones reconocen slo los 8 primeros caracteres.

b) Palabras clave:

No se pueden utilizar como identificadores, ya que tienen su significado predeterminado. Las palabras clave en orden
alfabtico son:

auto double int struct


break else long switch
case enum register typedef
char extern return union
const float short unsigned
continue for signed void
default goto sizeof volatile
do if static while

En sucesivos captulos iremos indicando cmo, y cuando, podemos usarlas.

Existen algunos compiladores que introducen alguna palabra clave ms, para ello bastar que consultemos el manual de
referencia de dicho compilador.

NOTA: Las palabras clave son siempre minsculas.

Ejemplos de identificadores:

Ejemplos correctos:
y y22 ERRORES
nombre radio X
temp por_ciento Y

Ejemplos errneos:

6d El primer carcter tiene que ser una letra.


"z" Las comillas (") son un carcter ilegal.
por-
No confundir el guin (-) con el subrayado (_).
ciento
por
El espacio en blanco es ilegal.
ciento

2.3) Constantes:

El lenguaje C tiene 4 tipos bsicos de constantes:

Constantes enteras.
Constantes de coma flotante.
Constantes de carcter.
Constantes de cadena de caracteres.

Antes de entrar en detalle en cada una de ellas diremos que las constantes enteras y de coma flotante son llamadas,
constantes de tipo numrico. Digamos ahora unas reglas que se pueden aplicar a todas estas constantes de tipo numrico.

o No se pueden incluir ni comas ni espacios en blanco en las constantes.

o Si lo deseamos, la constante puede ir precedida de un signo (-).

o El valor de la constante no puede exceder de un lmite mximo y un mnimo


especificados. Para cada tipo de constante, estos lmites varian de un compilador a otro.

1) Constantes enteras:

Consiste en una secuencia de dgitos, estas constantes se pueden escribir en decimal (base 10), octal (base 8) y
hexadecimal (base 16).
Una constante decimal es cualquier combinacin de nmeros tomados del 0 al 9. Si la constante tiene 2 o ms dgitos,
el primero ha de ser distinto de 0.

Ejemplos.

NOTA: De las constantes enteras largas diremos que se especifican poniendo una L (mayscula o minscula) al
final. Ejemplo:477898856L (decimal larga).

De las constantes enteras sin signo diremos que se representan aadiendo una U (mayscula o minscula) al final de la
constante.Ejemplo: 40001U (decimal sin signo).

Por ltimo tenemos las constantes enteras largas y sin signo, se aade una UL al final de la constante (en mayscula o
minscula) en ese orden. Ejemplo: 0xfffffUL (hexadecimal larga sin signo).

2) Constantes de coma flotante:

Es un nmero en base 10 que contiene un punto decimal (.) o un exponente (o ambos).

Si existe un exponente, su efecto es de desplazar la posicin del punto decimal a la derecha si el exponente es positivo,
o a la izquierda si es negativo. Si no se incluye punto decimal en el nmero, se supone que se encuenttra a la derecha del
ltimo dgito.

La interpretacin de una constante de coma flotante con exponente es la misma que en notacin cientfica, excepto
que sustituimos la base 10 por la letra E (o e).

Ejemplos.

Como nos podamos imaginar la magnitud de una constante en coma flotante se encuentra dentro de un rango mucho
mayor que el de las constantes enteras, este suele andar entre un mnimo de 3.4E-38 hasta un mximo de 3.4E+38
(aunque esto suele variar segn versiones).

NOTA: Tener en cuenta que las costantes enteras son exactas, sin embargo las de coma flotante son aproximaciones, y
puede darse el caso de que la computadora nos presente por pantalla el resultado 0.5 y su representacin en la memoria
sea la de 0.499999999.

3) Constantes de carcter:
Es un solo carcter, encerrado entre comillas simples.

Ejemplos.

El carcter puede ser cualquier representacin ASCII o una secuencia especial con la barra invertida ( \ ). Las
constantes de caracteres se toman como un valor entero.

Varias constantes de carcter con su valor:

'C' 67
Las comillas (") son un carcter
"z"
ilegal.
'x' 120
'&' 38

NOTA: si queris ver la tabla de caracteres ASCII, se encuentra disponible en el apndice.

Estos valores sern los mismos para todas las computadoras que utilicen el conjunto de caracteres ASCII (que son la
gran mayora).

Secuencias de escape: Ciertos carcteres no imprimibles, como las comillas dobles ("), el apstrofo o comilla simple ('),
etc...; se pueden expresar en trminos de secuencia de escape.

CDIGO SIGNIFICADO
\b retroceso (backspace)
\f avance de pgina
\n nueva lnea
\r retorno de carro
\t tabulador horizontal
\" comilla doble
\' comilla simple
\0 nulo
\\ barra invertida
\v tabulador vertical
\a alarma
\ddd constante octal
\xddd constante hexadecimal

Por tanto, algunas de estas constantes de carcter, expresadas como secuencias de escape, se escribiran:

'\n' '\f' '\"' (comilla doble) '\\' (barra invertida) '\'' (comilla simple)
4) Constantes de cadena de carcteres:

Es una secuencia de caracteres encerrada entre comillas dobles. A las cadenas de caracteres el compilador les aade un
carcter nulo '\0' al final, y las almacena como una matriz de caracteres.

Ejemplos.

NOTA: Como hemos dicho anteriormente el compilador inserta automticamente un carcter nulo \0 al final de toda
constante de cadena de caracteres, como el ltimo carcter de sta. Este carcter no aparece cuando se visualiza la
cadena.

Diferenciar:

'D' "D"

La primera es una constante de carcter con su valor entero correspondiente.

La segunda, en cambio, es una constante de cadena de un solo carcter, sin valor entero equivalente, constando de dos
caracteres: el carcter especificado, seguido del carcter nulo \0.

Ejemplos de constantes enteras:

Ejemplo 1:

1912 3 8 6578 0

Una constante entera octal est formada por cualquier combinacin de dgitos tomados del 0 al 7. El primer dgito
obligatoriamente tiene que ser 0 (esto es para distinguir la constante como un nmero octal).
Ejemplo 2:

0 03 0654 032

Ejemplos incorrectos:

654 No comienza por 0.


278 Dgito ilegal (8).
45.6 Carcter ilegal (.)).

Una constante entera hexadecimal debe comenzar por 0x o 0X, a continuacin puede aparecer cualquier combinacin
del 0 al 9 o de la aa la f (tanto maysculas como minsculas).

Ejemplo 3:

0x 0x3 0x7f 0xacd

Ejemplos de constantes de coma flotante:

2.4 por 10 elevado a -3 es equivalente a 2.4E-3 2.4e-3

8 por 10 elevado a +3 es equivalente a 8000

8 por 10 elevado a +3 es equivalente a 8E+3

8 por 10 elevado a +3 es equivalente a 8E3

8 por 10 elevado a +3 es equivalente a 8.0e3

Ejemplos de constantes de carcter:

'4' 'E' 'h' ' ' (espacio en blanco)


Ejemplos de constantes de cadena de caracteres:

Ejemplo 1: "El resultado es correcto"

Ejemplo 2: "234234-23"

Ejemplo 3: "" (representa la cadena vaca).

Ejemplo 4: "Lnea 1\nLnea 2\nLnea 3"

(ocupa 3 lneas a consecuencia de los caracteres de nueva lnea que se incluyen en ella).

Se mostrara as:

Lnea 1
Lnea 2
Lnea 3

Ejemplo 5: "\tSi quieres seguir, presiona \"RETURN\"\n"

Se mostrara:

Si quieres seguir, presiona "RETURN" (Colocndose el cursor en la siguiente lnea).

2.4) Tipos de Datos.

Una variable es un objeto del lenguaje cuyo valor se puede cambiar. Antes de utilizar una variable sta debe de ser
declarada. Al declarar una variable, se le asocia un identificador, es decir, un nombre, con un tipo de almacenamiento
cuya forma determina la visibilidad y existencia de la variable.

El tipo de la variable nos indica el conjunto de valores que puede tomar y las operaciones que pueden realizarse con
ella. Existen cinco tipos de datos bsicos en C:
Tipos de
Descripcin Memoria
Datos

2 bytes o una palabra (vara


int Cantidad entera
segn compilador).

char Carcter 1 byte.

float Almacena valores reales en punto flotante. 1 palabra (4 bytes).

double Almacena valores reales en doble precisin. 2 palabras (8 bytes).

Se utiliza para definir una funcin que no devuelve ningn valor o


void
declarar punteros genricos (lo veremos ms tarde).

Estos tipos bsicos admiten una modificacin del rango de valores, aplicando las siguientes palabras reservadas:

short (corto).

long (largo).

signed (con signo).

unsigned (sin signo).

Las modificaciones se aplican a los tipos int y char, a excepcin del modificador long que tambin puede aplicarse al
tipo double. Las posibles combinaciones son:

TIPO Nmero de bits Rango


char 8 -128 a 127
unsigned
8 0 a 255
char
signed char 8 -128 a 127
short 16 -32768 a 32767
int 16 -32768 a 32767
unsigned int 16 0 a 65535
signed int 16 -32768 a 32767
short int 16 -32768 a 32767
unsigned
16 0 a 65535
short int
signed short
16 -32768 a 32767
int
long int 32 -2147483648 a 2147483647
signed long
32 -2147483648 a 2147483647
int
unsigned
32 0 a 4294967295
long int
long 32 -2147483648 a 2147483647
unsigned
32 0 a 4294967295
long
float 32 3.4E-38 a 3.4E+38
double 64 1.7E-308 a 1.7E+308
64 80 (segn 1.7E-308 a 1.7E+308 3.4E-
long double
versin). 4932 a 1.1E+4932

NOTA: En esta tabla mostramos los valores ms tpicos, hansido cogidos de Turbo C, sin embargo, estos pueden variar
de un compilador a otro.

Esto nos sirve simplemente para, ahorrar memoria en algunos casos en los que la variable que vamos a usar sepamos a
ciencia cierta que no va a tomar valores muy grandes; o por el contrario usar long o double para evitar que se nos
desborde el Rango del que disponemos.

El tipo char se utiliza para representar caracteres individuales. Por tanto, el tipo char requiere slo un byte de memoria.
Cada tipo chartiene una interpretacin como entero equivalente, de esta forma un char es una clase especial de entero
pequeo. En la mayora de los compiladores el entero tipo char puede tomar valores entre 0 y 255. Tambin se puede
utilizar datos unsigned char (con valores de 0 a 255) o datos signed char (con valores de -128 a 127).

Ejemplos 1:

int abajo arriba; /* Estoy declarando dos variables de tipo entero.*/


/* Declaro dos variables enteras sin signo, lo que significa que si el Rango de un
unsigned int
entero est entre: -32768 y 32767; en un entero sin signo su parte negativa la uso en
fahr,celsius;
la positiva, estando su Rango entre: 0 y 65535. */

Ejemplo 2:

short int a,b,c;


long int r, s, t;
int p,q;

/* Algunos compiladores reservan menos espacio de memoria para las variables a, b ,c que para p,
y q. Los valores tpicos son 2 bytes para las variables declaradas como short int, y 4 bytes (una
palabra) para cada variable int. De forma semejante, algunos compiladores reservan espacio de
memoria adicional para las variables r,s y t, declaradas como long int. Es un valor tpico el de 2
palabras (8 bytes), por tanto los valores permitidos para r, s, y t sern mayores que los permitidos
para p y q si utilizamos un compilador de este tipo.*/
2.5) Declaracin de variables.

En C todas las variables han de ser declaradas antes de ser utilizadas. Las variables pueden declararse en tres sitios
diferentes:

Dentro de las funciones (variables locales).

Fuera de todas las funciones (variables globales).


En la definicin de los parmetros de las funciones.

La declaracin tiene el siguiente formato:

<clase><tipo><iden>[=<exp>][,<iden>[=<exp>][...]];

NOTA: lo que ponemos entre corchetes [...] indica opcionalidad.

El <tipo> determina el tipo de dato que almacena la variable.

En <iden> se declara un identificador que opcionalmente puede ser inicializado al valor de <exp>; se
pueden declarar ms identificadores separados por comas, pudiendo llevar cada uno su propia
inicializacin.

El = nos sirve para inicializar las variables dentro de la declaracin de tipo. Para hacer esto la
declaracin debe consistir en un tipo de datos, seguido por un nombre de variable, un signo (=) y una
constante del tipo apropiado. Al final se debe poner, como de costumbre, un punto y coma (;).Por
tanto, la primera vez que nos aparezca dicha variable, si no ha sido asignada posteriormente a su
declaracin de tipo, tomar el valor que le hemos dado en dicha declaracin.

Ejemplo.

La <clase> determina la forma de almacenamiento de la variable, que determina su visibilidad y su existencia. Existen
cuatro formas de almacenamiento:

o auto: Variables locales a una funcin o a un bloque, es decir, su existencia est ligada a esa funcin o bloque.
La variable se crea en la pila del sistema cuando se invoca la funcin o cuando se ejecuta el cdigo dentro del
bloque, y se destruye cuando acaba la funcin o bloque. Si no se especifica una clase al declarar una variable,
sta siempre es automtica.

o extern: Variables con almacenamiento permanente. Todas las funciones y bloques declarados despus de una
variable externa podrn acceder a ella. Una variable es de clase externa a una unidad de compilacin cuando no
se ha definido en esa unidad. En estos casos, el compilador no necesita reservar zonas de memoria para este
tipo de variables. El uso de variables externas proporciona un mecanismo adecuado de transferencia de
informacin entre funciones.En particular, podemos transferir informacin a una funcin sin usar argumentos.
Hemos de distinguir entre definiciones de variables externas y declaraciones de variables externas.
Una definicin de variable externa se escribe de la misma forma que una variable ordinaria. Tiene que aparecer
fuera, y normalmente antes, de las funciones que acceden variables externas. Una declaracin de variable
externa tiene que que empezar por el especificador de tipo de almacenamiento extern. El nombre de la variable
externa y su tipo tienen que coincidir con su correspondiente definicin de variable externa que aparece en la
funcin. Una declaracin de variable externa no puede incluir una asignacin de valores iniciales.
o static: Variables que existen desde el comienzo hasta el final de la ejecucin del programa. Una variable de
clase esttica puede ser global a todo el programa, local a una unidad de compilacin, o local a una sola
funcin. Todas las variables globales, por defecto, son de clase esttica. Si una variable global se declara
explcitamente de clase esttica, esta variable se considera como local a una unidad de compilacin donde se
declara. Una variable local a una funcin y de clase esttica, conserva su valor de una llamada a otra.

o register: Variables que residen en uno de los registros de la CPU. Las variables de tipo regitro siempre son
automticas y , por tanto, locales a una funcin. Slo se puede utilizar la clase registro con los tipos entero y
carcter. Se suele usar para contadores.

Ejemplos.

La visibilidad de una variable va a depender del sitio en el que se ha declarado. En funcin de esto tenemos:

Variables locales: Las variables que se declaran dentro de un bloque de sentencias se denominan variables
locales. Estas variables se crean al comienzo del bloque y se destruyen al salir del bloque al que pertenecen.

Variables globales: una variable es global cuando se declara fuera de todos los bloques. Las variables
globales se conocen a lo largo de todo el programa y se pueden utilizar desde cualquier sitio. Todas las
funciones y bloques declarados despus de una variable global, podrn acceder a ella. Si dentro de un bloque
se repite la declaracin de una variable definida en un bloque exterior, el acceso se referir exclusivamente a
la variable dentro del bloque ms interno. Es decir, el nombre de un bloque externo es vlido a menos que un
bloque interno lo vuelva a definir.

Cuando se declare una variable, como se dijo anteriormente, se le puede asignar un valor inicial (cualquier expresin
vlida en C), independientemente de que lo mantenga o no a lo largo de todo el programa. Las
variables globales y estticas se inicializan a cero si no se especifica ningn valor. Ambas se deben inicializar con
expresiones constantes. Las variables estticas las inicializa el compilador una sola vez, al comenzar el programa. Las
variables locales y de registro tienen valores desconocidos hasta que se les asigna uno dentro del programa. Si tienen
valores iniciales, se asignan cada vez que se ejecuta el bloque donde se definen.

Ejemplos de declaracin:

int a=4;
char asterisco='*';
float suma=0.11;

Ejemplos de formas de almacenamiento:

Ejemplo 1:

int a, b,c; a, b y c son variables enteras.


float
raiz1 y raiz2 son variables de coma flotante.
raiz1,raiz2;
char
indicador es una variable de tipo carcter.
indicador;
char texto es un array de tipo carcter de 80 elementos. Fijmonos en los
texto[80]; corchetes que me encierran la especificacin del tamao.

Ejemplo 2:

int a;
int b;
int c;
float raiz1;
float raiz2;
char indicador;

NOTA: el ejemplo 1y el ejemplo 2 son equivalentes.

Ejemplo 3:

#include <stdio.h>
void incrementa(); /* funcin que no devuelve ningn valor void */
/* estoy declarando la funcin que voy a implementar posteriormente.*/
main()
{
register cont;
for(cont=1;cont <= 3; cont++) { /* Inicializo bucle en la 1 vuelta a cont=1,*/
printf("Iteracin %d\t", cont); /* incrementa en cada vuelta el cont a 1 (cont++)*/
incrementa(); /* repito el cuerpo del bucle mientras cont<=3 */
} /* fin del for */

/* El %d del printf me indica que voy a representar por pantalla un nmero entero cont, si en lugar de ser cont
de tipo entero, fuera de tipo float, y pusiese en el printf un %d, me escribira por pantalla su parte entera (todo
esto de la entrada y salida se ver mejor en el captulo siguiente).*/
} /* fin del main() (programa principal)*/

void incrementa(){
static int a=1;
int b=1;

printf("a=%d b=%d\n", a,b);


a++;b++;
} /* fin de la funcin incrementa */

La salida que dar este programa es:

Iteracin 1 a=1 b=1


Iteracin 2 a=1 b=1
Iteracin 3 a=1 b=1

Ejemplo 4:

Primer archivo:

#include <stdio.h> /*programa simple de varios archivos para escribir "Hola!".*/


extern void salida(void); /*declaracin funcin externa.*/

main()
{
salida();
}

Segundo archivo:

extern void salida(void) { /*definicin de funcin externa.*/

printf ("Hola!");
return;
}

Observemos como a salida se le asigna el tipo de almacenamiento extern, pues tiene que ser accedida
desde otro archivo distinto de aquel en que es definida; por tanto, ha de ser una funcin externa. As se
incluye la palabra clave extern tanto en la declaracin de la funcin (primer archivo), como en
la definicin de funcin (segundo archivo). Como extern es un tipo de almacenamiento por defecto,
podamos haber prescindido de escribir extern tanto en la declaracin como en la definicin.

2.6) Operadores.

Los operadores son smbolos que indican cmo se deben manipular los operandos. Los operadores junto con los
operandos forman unaexpresin, que es una frmula que define el clculo de un valor. Los operandos pueden ser
constantes, variables o llamadas a funciones, siempre que stas devuelvan algn valor. El compilador evala
los operadores, algunos de izquierda a derecha, otros de derecha a izquierda, siguiendo un orden de precedencia. Este
orden se puede alterar utilizando parntesis para forzar al compilador a evaluar primero las partes que se deseen.

Tipos de operadores:
Aritmticos.
Casting.
Monarios.
Relacionales y Lgicos.
Asignacin.
Condicional.
Tratamiento de bits.
Punteros.
Secuencial.
Acceso a estructuras y uniones.
[ ] y ( ).

Aritmticos:

OPERADOR PROPSITO
+ adicin
- sustraccin
* multiplicacin
/ divisin
% resto de divisin entera

NOTA: El % a veces es llamado operador mdulo.

o El % requiere que sus dos operandos sean enteros, y el segundo no nulo.

o El de divisin (/) requiere que el segundo operando sea no nulo, aunque los operandos no requieren ser enteros.
Aqu podemos tener cuatro casos:

1) Si dicha divisin se produce para dos operandos enteros el resultado ser un nmero entero que ser
truncado, o sea, cogeremos slo la parte entera del resultado. Si es de

2) Si la divisin es entre dos nmeros en coma flotante el resultado ser otro nmero en coma flotante.
3) Si la divisin es entre un nmero entero y otro en coma flotante, el resultado ser un nmero en coma
flotante.

4) Si la divisin tiene algn operando negativo, o los dos, entonces la divisin entera (entre dos nmeros
enteros) estar truncada hacia cero, esto quiere decir que el resultado ser siempre menor en valor absoluto que
el verdadero cociente.

Ejemplo.

o Si tenemos 2 operandos, y ambos son tipos de coma flotante con precisin distinta (float y double), el operando
de menor precisin (float) se transformar a la precisin del otro (double).

o Si tenemos un operando del tipo coma flotante y el otro un char o un int, el char/int, se transformar al tipo de
coma flotante.

o Si un operando es del tipo long int, y el otro no es del tipo coma flotante (ejemplo int), entonces ste se
transformar a long int.

o Si ningn operando es del tipo coma flotante, ni long int, ambos se convertirn en int, y el resultado ser int.

Casting:

El lenguaje permite cambiar el tipo de una variable a travs del operador de casting , que se emplea anteponiendo al
operando el nombre del tipo requerido, encerrado entre parntesis:

(<tipo>) <operando>

donde <tipo> es uno de los tipos bsicos, un puntero o un modificador de tipo.

Ejemplo.
Monarios:

Son operadores que actan sobre un slo operando para producir un nuevo valor. En C todas las constantes numricas
son positivas. Por tanto, un nmero negativo es en realidad una expresin, que consiste en el operador monario menos
(-), seguido de una constante numrica positiva. No debemos confundir este menos, con el de la operacin de la
sustraccin, el cual requiere dos operandos.

Otros dos operadores monarios interesantes son:

++ Que es el operador incremento, hace que su operando se incremente en uno.

-- Que es el operador decremento, hace que el operando se decremente en uno.

Los operadores incremento y decremento pueden ser utilizados de dos formas diferentes, dependiendo de donde se
escriba el operador, antes o despus del operando. Si el operador precede al operando (Ej: ++i), el valor del operando se
modificar antes de que se utilice con otro propsito. Si el operador sigue al operando (Ej: i--), el valor del operando se
modificar despus de ser utilizado.

NOTA: El operador incremento y el de decremento son operadores monarios y de asignacin, por tanto, en el
apartado Asignacin los volvemos a mencionar.

Otro operador monario digno de mencin es el operador de tamao: sizeof. ste devuelve la longitud en bytes del
operando, que puede ser una variable o un especificador de tipo (en este caso, debe ir encerrado entre parntesis).

Ejemplos.

Por ltimo, decir que cast (visto anteriormente en el apartado Casting), puede ser considerado un operador monario.

Lgicos y Relacionales:

Los operadores lgicos y relacionales tratan con valores verdaderos y falsos. Una expresin con operadores lgicos o
relacionales devuelven siempre un valor verdadero o falso. El lenguaje interpreta un valor verdadero cuando es diferente
de cero, y falso cuando es igual a cero. Los diferentes operadores de este tipo que existen son:

OPERADOR PROPSITO
> mayor que
>= mayor o igual que
< menor que
<= menor o igual que
== igual
!= distinto
&& AND lgico
|| OR lgico
! NOT lgico

NOTA: Los operadores tienen un orden de precedencia, pudindose diferenciar de mayor a menor precedencia, en caso
de igualdad de precedencia todos se asocian de izquierda a derecha (excepto los monarios, los condicionales, y los de
asignacin, que lo hacen de derecha a izquierda), esto quiere decir que si la asociatividad es de izquierda a derecha, y se
nos presentan operadores con la misma precedencia, comenzaremos a mirar los operadores ms a la izquierda, e iremos
avanzando hacia la derecha, dicho esto presentamos los distintos grupos de operadores:

monarios: -, ++, --, !, sizeof(tipo).

multiplicacin(*), divisin(/) y resto(%) aritmticos.

suma(+), y sustraccin(-) aritmticas.

<, <=, >, >=.

==, !=.

&& (AND lgico).

|| (OR lgico).

operador condicional (se ver posteriormente).

operador de asignacin (se ver posteriormente).

Dado que el lenguaje interpreta como falso el valor cero, y como verdadero cualquier valor diferente de cero, se pueden
emplear operadores aritmticos en las expresiones lgicas y de comparacin.
Ejemplos.

Asignacin:

Se utiliza el operador =, dentro de una asignacin, para asignar valores a una variable. Tiene el siguiente formato:

<variable>=<expresin>

tambin admite la forma:

<variable><operador>=<expresin>

que equivale a:

<variable>=<variable><operador><expresin>

donde <operador> es cualquiera de los operadores binarios. Por tanto, se tiene los siguientes operadores de
asignacin:

OPERADOR PROPSITO
++ incremento unario
-- decremento unario
= asignacin simple
*= asignacin de la multiplic.
/= asignacin de la divisin
%= asignacin del resto
+= asignacin de la suma
-= asignacin de la resta
<<= asignacin del desplazam. a la izquierda
>>= asignacin del desplazam. a la derecha
&= asignacin de la operacin AND
|= asignacin de la operacin OR
^= asignacin de la operacin XOR

Ejemplos.

Cuando se evala una expresin se obtiene un tipo de resultado que depende de los operandos. Si un operador tiene
operandos de tipos diferentes, stos se convierten a tipo segn una jerarqua preestablecida. Las conversiones
aritmticas implcitas se realizan mediante la siguiente secuencia, y en ese orden:

o char y short se convierten a int.

o si un operando es long double, el otro se convierte en long double, y el resultado tambin.

o en otro caso, si un operando es double, el otro se convierte en double, y el resultado tambin.

o en otro caso, si un operando es float, el otro se convierte en float, y el resultado tambin.

o en otro caso, si un operando es unsigned long, el otro se convierte en unsigned long, y el resultado tambin.

o en otro caso, si un operando es long, el otro se convierte en long, y el resultado tambin.

o en otro caso, si un operando es unsigned, el otro se convierte en unsigned, y el resultado tambin.

o en otro caso, los operandos son de tipo int, y el resultado es de tipo int.

IMPORTANTE: Cuando se realiza una asignacin de variables de diferentes tipos, el valor del lado derecho se ajusta al
tipo de variable del lado izquierdo de la expresin.

Condicional:
Este operador (?:) se utiliza para reemplazar estructuras sencillas de decisin. Si se desea que una instruccin
determinada se ejecute segn una cierta condicin, se emplea este operador ternario de la siguiente forma:

<condicin>?<expresin-v>: <expresin-f>

Primero se evala la <condicin>.


Si es verdadera, se evala la <expresin-v>.
Si es falsa, se evala la <expresin-f>.

Ejemplos.

Tratamiento de bits:

El C proporciona un grupo de operadores de manipulacin de bits. Estos operadores son:

OPERADOR PROPSITO
& operacin AND.
| operacin OR.
^ operacin XOR.
>> desplazam. a la derecha.
<< desplazam. a la izquierda.

Estos operadores slo pueden usarse con los tipos int y char y funcionan bit a bit. El operador de desplazamiento se
puede utilizar para realizar multiplicaciones o divisiones rpidas, pues cada desplazamiento a la izquierda multiplica por
2, y cada desplazamiento a la derecha divide por 2. El C distingue entre desplazamientos aritmticos y lgicos:

Los desplazamientos aritmticos se realizan sobre tipos enteros y mantienen el signo (el bit ms alto).

Con los desplazamientos a la izquierda el bit no se altera.


Con los desplazamientos a la derecha el bit se copia en la posicin siguiente, con la intencin
de mantener el signo del dato.

Los desplazamientos lgicos se realizan sobre datos unsigned. No tienen ninguna consideracin
particular con el signo.

Punteros:

En temas posteriores entraremos ms a fondo sobre ellos, ya que son una parte imprescindible del lenguaje. De ellos
slo diremos que los operadores unitarios * y & se utilizan con punteros. Cuando se evala el operador unitario &, se
obtiene la direccin del operando. El operador *, al evaluarse, devuelve el valor de la variable a la que apunta el
operando; por lo tanto, el operando debe ser un puntero.

Secuencial:

El operador secuencial (,) se utiliza para concatenar varias expresiones. El lado izquierdo de la coma siempre se evala
primero.

Ejemplo:

m=(n=30,n++,n*2)

Asigna 30 a la variable n, despus incrementa n, para posteriormente multiplicar el resultado del incremento
por 2, valor que es asignado a m. El valor de m ser 62.

Acceso a estructuras y uniones:

Este apartado, al igual que en el de los Punteros,lo trataremos en un tema posterior. Slo decir que los operadores . y -
> se utilizan para acceder a los campos de uniones o de estructuras. Cuando un puntero apunta a una estructura, se
emplea el operador -> para acceder a los campos, y el operador . se utiliza en otro caso.

[ ] y ( ):
Los corchetes se utilizan para acceder a los diferentes elementos de una matriz (se ver posteriormente en temas
sucesivos). Para seleccionar un elemento se necesita un ndice que indique la posicin a utilizar. Los parntesis se
pueden utilizar dentro de las expresiones para modificar el orden de evaluacin predeterminado por el lenguaje.

Ejemplo de operadores Aritmticos:

Supongamos que a y b son variables de tipo carcter que representan los caracteres P y F respectivamente, si realizamos
las siguientes operaciones obtendremos:

b 70
a+b 150
a+b+7 157
a+b+'7' 205

Hemos de recordar que si los operandos difieren en el tipo pueden sufrir una conversin de tipo antes de que la
expresin alcance su valor final. En general, diremos que su valor final se expresar con la mayor precisin posible,
siendo consistente con los tipos de datos de los operandos.

Ejemplos del operador Casting:

Supongamos que i es una variable entera con un valor de 3, y f un variable de coma flotante con un valor de 4.5. La
expresin:

(i+f) % 7

sera invlida, ya que el operando (i+f) es de coma flotante en lugar de entero (y el mdulo slo admite enteros), sin
embargo utilizando el casting la podemos hacer vlida poniendo:

((int)(i+f))% 7

Ejemplos de operadores Monarios:

Supongamos que i es una variable entera, y f una variable de coma flotante.


sizeof i devuelve 2
sizeof f devuelve 4

Supongamos un valor inicial para i de 8:

++i la i tomar el valor de 9.

Supongamos ahora que j inicialmente tiene un valor de 7:

--j la j tomar el valor de 6.

Ejemplos de operadores Lgicos y Relacionales:

Supongamos que i es una variable entera con valor de 7, f una variable de coma flotante con valor de 5.5 y c una
variable de carcter que representa la 'w'.

EXPRESIN INTERPRETACIN VALOR


f>5 cierto 1
(i+f)<=10 falso 0
(i>=6)&&(c=='w') cierto 1
(1)c!='p'||i+f<=10 cierto 1
!(f>5) falso 0
i>(f+1) cierto 1
(2)i>=6&&c=='w' cierto 1
!(i>(f+1)) falso 0
c!='p' cierto 1
(f<11)&&(i>100) falso 0

(1): Observemos como en este ejemplo se pone de manifiesto la precedencia superior del != (distinto) sobre el OR
lgico (||), y del menor o igual (<=) sobre el OR lgico, y a su vez la precedencia del + sobre el <= tambin queda de
manifiesto, por todo ello no nos hace falta poner: (c!='p')||((i+f)<=10).
(2): De la misma forma que en (1), prescindimos de los parntesis ya que la precedencia nos ahorra dicho trabajo.

Ejemplos del operador de Asignacin:

Supongamos que i y j son variables enteras, con los valores de 5 y 7, respectivamente; f y g variables de coma flotante
con valores de 5.5 y -3.25 respectivamente; x,y y z, tienen los valores 2, 3 y 4 respectivamente:

EXPRESIN
EXPRESIN VALOR FINAL
EQUIVALENTE
i+=5 i=i+5 10
f-=g f=f-g 8.75
j*=(i-3) j=j*(i-3) 14
f/=3 f=f/3 1.833333
i%=(j-2) i=i%(j-2) 0
3 (ya que i es
i=3.3
variable entera).
-3 (ya que i es
i=-3.9
variable entera)
(1)i='x' 120
(1)i=('x'-'0')/3 24
(2)x*=-
x=x*(-2*(y+z)/3) 8
2*(y+z)/3

(1): 'x' corresponde al carcter ASCII nmero 120, y el '0' corresponde al 48.
NOTA: Como hemos podido suponer el valor que tena inicialmente i, por ejemplo en (1), es machacado cuando se le
asigna otro valor final.

Ejemplos del operador Condicional:

o Supongamos que m=50, cul ser el valor asignado a n en la expresin siguiente?

n=(m==99?1:2)

En este ejemplo, se nos est diciendo que Si m es igual a 99, tendramos que coger 1 (que es el que forma
la <expresin-v>); si por el contrario m es distinto de 99, entonces tendramos que coger la <expresin-f> (que en este
caso tiene el valor de 2). Como se da el segundo paso, cogeramos el 2, por tanto, a n se le asigna el valor de 2 (n=2).

o Supongamos que f y g son variables de coma flotante en la siguiente expresin condicional.

(f<g)?f:g

Esta expresin condicional toma el valor de f, si f es menor que g; de otra forma la expresin condicional tomar el
valor de g. En otras palabras, la expresin condicional devuelve el valor de la menor de las dos variables.

o Supongamos que a, b y c son variables de tipo entero, en este ejemplo aparecen seis grupos de precedencia
distintos:
c+=(a>0 && a<=10)?++a:a/b;

(esto es un sentencia que la explicamos debajo de este ejemplo).

La sentencia comienza por la evaluacin de la expresin compuesta

(a>0 && a<=10)

Si esta expresin es cierta evaluamos la expresin: ++a, si es falsa evaluamos la expresin a/b. Por ltimo tenemos que
hacer la operacin de asignacin (+=), haciendo que se incremente c en el valor que he obtenido de la expresin
condicional.

Si a, b y c posen los valores 1, 2 y 3, respectivamente, entonces, al evaluar la expresin condicional obtendremos el


valor de 2 (ya que evaluaremos la expresin ++a), y posteriormente a c se le asignar el valor de 5 (ya que la asignacin
sera: c=3+2).

2.7) Expresiones.
El uso de expresiones involucrando operadores es especialmente frecuente en C, como en muchos otros lenguajes de
programacin. El resultado de una expresin puede representar condiciones lgicas que son ciertas o falsas. La certeza se suele
representar con el valor entero 1 (o simplemente distinto de cero), y la falsedad se representa con el valor entero 0. Pongamos
algunos ejemplos sencillos de expresiones:

a + b aparece el operador suma (+).


x = y en esta expresin aparece el operador asignacin, explicado ms abajo.
esta expresin tendr el valor de 1 si x es menor o igual que y, y de 0 si y es
x<=y
mayor que x.
x==y esta expresin tendr el valor 0 si x<>y, y de 1 si x es igual que y.
++i esta expresin incrementa el valor de i en uno.

2.8) Sentencias.

Una sentencia hace que la que se consiga llevar a cabo una accin por parte de la computadora. Hay tres tipos de sentencias en
C:

o Sentencias de expresin: Consiste en una expresin acabada con un punto y coma (;), la ejecucin de esta hace
que se evale la expresin.

Ejemplo.

o Sentencias compuestas: Estn formadas por varias sentencias individuales encerradas entre dos llaves({...}).
Las sentencias individuales pueden ser a su vez sentencias de expresin, sentencias compuestas o sentencias de
control. A diferencia de una sentencia de expresin, las compuestas no acaban con un punto y coma. Las
sentencias compuestas hacen posible incluir unas sentencias dentro de otras.

Ejemplo.

Este tipo de sentencias nos quedarn ms claras cuando veamos los bucles (for, while,...), la idea general que
tenemos que tener de ellas es la de que me agrupan cdigo para poder delimitarlo, por ejemplo: me dicen donde
comienza (abriendo una llave ( { )), y donde termina una funcin (cerrando una llave ( } )); o incluso para
delimitar donde comienza (abriendo una llave ( { )), y donde termina el bucle (cerrando una llave ( } )) que voy
a ejecutar.

o Sentencias de control: se utilizan cuando deseamos conseguir ciertas acciones especiales en los programas,
comprobaciones lgicas, bucles y ramificaciones. Muchas sentencias de control necesitan que las otras
modalidades de sentencias que tenemos, estn presentes dentro de ellas.

NOTA: Aunque el bucle while(condicin) lo veremos en otra seccin, pondremos un fcil ejemplo que lo usa.

Ejemplo de sentencias de expresin:

a=3;
c=x+y;
++i;
n=(m==99?1:2);
printf("Suma=%d",c);

Ejemplo de sentencias compuestas:

{
pi=3.14;
c=x+y;
++i;
}

Ejemplo de sentencias de control:


/* La sentencia compuesta: {...},se seguir ejecutando hasta que el valor de cont exceda al de n.*/

while(cont<=n)
{
printf("x=");
scanf("%f",&x);
suma+=x;
++cont; /* cont se incrementa en uno en cada pasada del bucle.*/
}

La sentencia que aqu representamos contiene una sentencia compuesta que es:

{.........}

que a su vez contiene cuatro sentencias de expresin:

printf("x=");
scanf("%f",&x);
suma+=x;
++cont;

/* En este incremento el operando cont se modificar antes de que se utilice con otro propsito, aunque
en este caso concreto, se producira el mismo efecto si lo ponemos: cont++ */

4.1) Estructura if.

El formato general de la sentencia if es el siguiente.

No olvidemos que: Lo que ponemos entre corchetes [...], indica, opcionalidad.

La expresin, al evaluarse, debe dar un valor:

falso (igual a cero). Se ejecuta la instruccin siguiente a la estructura if, a menos que aparezca la
parte else, en cuyo caso se ejecuta <sentencia-f>.

verdadero (distinto de cero). La expresin ejecuta la <sentencia-v>.


Ejemplos.

Si se desea que se ejecuten un conjunto de sentencias, se debe de seguir la siguiente sintaxis:

Ejemplos.

La estructura if se puede anidar con otras estructuras if. En este caso, si aparece la parte else, se asociar al ltimo if,
osea, se refiere alif ms prximo que est en el mismo bloque que el else y que no est asociado con otro if.

Ejemplos.

Ejemplos simples de estructura if:

Ejemplo 1:

if (x < 100) printf("%f",x);

/*Esta sentencia hace que el valor de la variable de coma flotantex se visualice si su valor es menor que 100.*/

Ejemplo 2:

if (estado=='A')

printf("OK");
else
y=0;
printf("Esto lo hago siempre.");

/* Esta sentencia visualiza la palabra OK, si estado tiene el valor de 'A'; si por el contrario estado no tiene el valor
de 'A', entonces, se ejecutar el else, y a la y se le asignar el valor de 0. Fijmonos en que tanto en el caso de irme
por el camino del if, como por el camino del else visualizar el mensaje: Esto lo hago siempre. */

Ejemplo 3:

if ((estado=='A') || (x < 100))

printf("OK");
else y=1;

/* Esta sentencia usa una expresin lgica, que visualiza la palabra OK, si estado tiene el valor de 'A' o x es menor
que 100; por el contrario si no se cumple ninguna de estas condiciones, nos iremos al else y asignaremos a la
variable y el valor de 1.*/

Ejemplos de estructura if que ejecuta un conjunto de sentencias:

Ejemplo 1:

if (indicador != 0) {

printf("Vlvula abierta");
x=1;
}

/* Esta sentencia contiene una sentencia compuesta que se ejecuta si indicador tiene un valor no nulo; fijmonos en
que: if (indicador != 0)... equivale a: if (indicador)...*/

Ejemplo 2:

if ((estado=='A') || (x < 100)) {

printf("OK");
y=1;
}

/* Esta sentencia usa una expresin lgica, que visualiza la palabra OK, y se asigna a la y el valor de 1,
si estado tiene el valor de 'A' o x es menor que 100.*/

Ejemplo 3:

if (estado=='A')
printf("OK");
else{
y=0;
printf("Esto no lo hago siempre.");
}

/* Diferenciar el ejemplo 4 de este otro, el mensaje: Esto no lo hago siempre, slo se visualizar cuando vaya por el
camino del else.*/

Ejemplos de estructuras if anidadas:

Ejemplo 1:

if (x >= 100)

if (x < 150) y=1;


else y=0;

/* Este ejemplo nos representa la anidacin con estructuras if. Si x es mayor o igual que 100, entraremos en el
siguiente nivel de anidacin, que me llevar al siguiente if, comprobando si x es menor que 150, si esto es cierto,
asignaremos a la yel valor de 1; si por el contrario x no es menor que 150, (o sea, que x va a ser mayor o igual que
150, ya que por el primerif supe al entrar por l, que x era mayor que 100), asignar el valor de 0 a la variable y.*/

Ejemplo 2:

if (x >= 100) {

if (x < 150) y=1;


}
else y=0;
printf ("Esto lo hago siempre");

/* Este ejemplo es distinto del anterior. Si x es mayor o igual que 100, entraremos en el siguiente if, comprobando
si x es menor que 150, si esto es cierto, asignaremos a la y el valor de 1, y posteriormente visualizaremos: Esto lo
hago siempre; si por el contrario x no es menor que 150, no haremos nada ms y nos iremos a visualizar: Esto lo
hago siempre. Si el primer if no se cumple (x es menor que 100), pasar al else, y asignar el valor de 0 a la
variable y, visualizando posteriormenteme el mensaje: Esto lo hago siempre*/

Ejemplo 3:

if (i) {

if (j==0) y=1;
if (k==3) y=2;
else y=3;
}
else y=4;
printf ("Esto lo hago siempre.");

/* El primer if me da acceso al resto de los if del ejemplo, o sea:


o si la i es cierta (distinto de cero), pasaremos a comprobar el if que tenemos a continuacin: if
(j==0); independientemente de que entremos o no en l, no me influye para comprobar el siguiente if, al
cual le corresponde el else que va a continuacin; si k es igual a 3 asignar a la y el valor de 2, y
posteriormente visualizar por pantalla el mensaje que aparece fuera de la condicional: Esto lo hago
siempre; si k<>3, me ir al else, asignando a la y el valor de 3, y posteriormente me ir igualmente al
mensaje de printf.

o si la i es falsa (igual a cero), pasaremos directamente al ltimo else, asignando a la y el valor de


4.*/

4.2) Estructura switch.

Esta estructura permite considerar decisiones para ms de dos posibilidades. El formato general de esta sentencia es:

NOTA: Cada case admite distintas sentencias, y a su vez, podemos poner distintas etiquetas case para distintas opciones
dentro de un mismo switch.

La variable <var> se evala y compara sucesivamente con todas las constantes que aparecen junto a la palabra
reservadacase. Si alguna de ellas es igual al valor de <var>se ejecuta la sentencia o bloque de sentencias
correspondientes. Si no aparece la palabra reservada break, contina la comparacin con el resto de las opciones. Si
aparece break, se termina la ejecucin de la estructura switch. La opcin default, es opcional, indica la sentencia
que se ejecuta en caso de que el valor de la variable <var> no se corresponda con ninguna de las constantes
expresadas. La estructura switch no permite que dos constantes tengan el mismo valor. Si se evalan constantes de
caracteres, se emplean sus equivalentes numricos.

Ejemplo: Aqu presentamos un ejemplo de switch con el uso de un bucle while (se ver en el captulo siguiente). Dada
la cadena "BuEnos dIas.". Cuenta el nmero de vocales (ya sean maysculas o minsculas). Lo presentamos en forma
de traza.

Ejemplos.

Se puede tener un switch formando parte de la secuencia de sentencias de otro switch. Incluso si las
constantes case del switch interior y del exterior contienen valores comunes, no aparecen conflictos.
Ejemplo.

Ejemplos de estructura switch:

Ejemplo 1:

#include<stdio.h>
main() {
char ch;
printf("Introduzca una vocal: ");
ch=getchar();
switch(ch) {
case 'a': puts("Se ha pulsado una a.");
break;
case 'e': puts("Se ha pulsado una a.");
break;
case 'i': puts("Se ha pulsado una a.");
break;
case 'o': puts("Se ha pulsado una a.");
break;
case 'u': puts("Se ha pulsado una a.");
break;
default: puts("Error");
}
}

NOTA: Vamos seleccionando una determinada opcin del case, segn sea a, e, i, o, u, si no es ninguna de ellas la
que hemos introducido por teclado por medio de la funcin getchar(), ejecutaremos la opcin default, que
visualizar: Error.

Ejemplo 2:

switch (eleccion=getchar()) {
case 'r':
case 'R':
printf("ROJO");
break;
case 'b':
case 'B':
printf("BLANCO");
break;
case 'a':
case 'A':
printf("AZUL");
break;
}

NOTA: Se presentar ROJO si eleccion representa r o R, se presentar BLANCO si eleccion representa b o B, y


AZUL sieleccion representa a o A. No se visualizar nada si eleccion tiene asignado algn otro carcter. Si nos
damos cuenta, en este ejemplo, cada grupo de sentencias tiene dos etiquetas case para contemplar maysculas y
minsculas, de la misma forma, cada uno de los dos primeros grupos acaba con la sentencia break.La
sentencia break transfiere el control fuera de la sentencia switch para que no se ejecute ms de un grupo de
sentencias.

Ejemplo 3:

switch (eleccion=toupper(getchar())) {
case 'R':
printf("ROJO");
break;
case 'B':
printf("BLANCO");
break;
case 'A':
printf("AZUL");
break;
default:
printf("ERROR");
}

NOTA: La funcin toupper me pasa a mayscula el carcter que introduzca, si el carcter introducido no es ni R, ni
B, ni A, por medio de default visualizar la palabra: ERROR.

Ejemplo 4: Suponemos indicador una variable entera, x e y, variables de coma flotante:

switch (indicador) {
case -1:
y=x * x;
break;
case 0:
y=x/2;
break;
case 1:
y=x;
break;
case 2:
case 3:
y=2 * (x+1);
break;
default:
y=0;
}

NOTA: En este ejemplo asigno a y un determinado valor, segn lo que valga la variable indicador, pudiendo ser -1,
0, 1, y 2 3 (ya que en este ltimo caso, tanto si es 2, como si es 3, asignar a la variable y el valor de 2*(x+1)); en
caso de no ser indicador ninguno de los valores mencionados anteriormente, asignaremos a la y el valor de 0.

Ejemplos de estructuras anidadas con switch:

Ejemplo 1:

switch(x) {
case 1:
switch(y) {
case 0: printf("error de divisin por cero");
break;
case 1: x=1;
y=7;
}
break;
case 2:
...........
...........

/* si al entrar al switch la x tiene el valor de 1, entonces entrar en el siguiente switch, y me comportar como en
unswitch normal, tener en cuenta que el break del switch(y) me sacara fuera de este switch, por eso encuentro,
otro break, al final del case 1 del switch(x), que me saca fuera de este otro switch. */

4.3) Estructura for.

El formato general de la sentencia if es el siguiente.

La inicializacin es una expresin simple, normalmente una asignacin a la variable de control del bucle de un valor
inicial. La condicin es una expresin lgica o de comparacin que determina el fin del bucle. El incremento es una
expresin simple que modifica la variable de control al final de cada vuelta.

El funcionamiento de la estructura for es el siguiente:

1) Se evala la expresin de inicializacin.

2) Se evala la condicin. Si el resultado es falso, termina la ejecucin de la estructura for. Si es


verdadero, sigue por el paso 3.

3) Se ejecuta el bloque de instrucciones dentro de la estructura.


4) Se evala la expresin final, que normalmente altera la variable de control, y se vuelve al paso
segundo.

Variando las tres expresiones de la estructura for, se pueden realizar diferentes tipos de bucles.

Ejemplo: A continuacin se presenta un ejemplo con traza del bucle for. Por medio del cual realizmos la suma de los 8
primeros nmeros enteros. Dando el resultado por pantalla.

NOTA: Si slo consta el for de una sentencia, entonces podemos prescindir de las llaves ({ } ).

Ejemplos.

No es necesario que nos aparezcan las tres expresiones en la sentencia for, aunque deben aparecer los puntos y
comas. Sin embargo, se deben entender perfectamente las consecuencias de esta omisin. Las expresiones primera y
tercerase pueden omitir si se inicializa y/o altera el ndice de alguna otra forma. Si omitimos la segunda expresin
se dar por supuesto que sta, al ser evaluada dar siempre 1 (cierto); por tanto, tendremos un caso de bucle infinito,
a menos que introduzcamos una sentencia que rompa el ciclo (Ej: break o return). En cualquier caso en la gran
mayora de las ocasiones incluiremos las tres expresiones en el for.

Ejemplo.

Para acabar con el for sera conveniente hacer una mencin sobre la existencia de un operador coma (,), que se utiliza
principalmente en esta sentencia. Este operador me permite que aparezcan dos expresiones en situaciones en donde slo
se utilizara una expresin ordinariamente. Por tanto, sera posible encontrarse algo como:

for (expresion 1a, expresion 1b; expresion 2; expresion 3) sentencia

Como vemos la expresion 1a se encuentra separada de la expresion 1b por una coma, en lugar de aparecer una
sola expresin, como habitualmente.


for (expresion 1a; expresion 2; expresion 3a, expresion 3b) sentencia

Como vemos la expresion 3a se encuentra separada de la expresion 3b por una coma, en lugar de aparecer una
sola expresin, como habitualmente.
Ejemplo.

Ejemplos de estructura for:

Ejemplo 1:

#include <stdio.h>
main() {
int n,i;
int suma;
printf("Suma desde 0 hasta n.\n");
printf("Introduce un nmero n: ");
scanf("%i", &n);
for(i=suma=0;i<=n;i++)
suma=suma+i;
printf("Suma desde 0 hasta %d=%d\n", n, suma);
}

NOTA: Este ejemplo visualizara lo siguiente:

Suma desde 0 hasta n.


Introduce un nmero n:

En este punto nos pedira un nmero por teclado, que nos va a servir para darle valor a la variable entera n (%i:
entero decimal, octal, o hexadecimal). Supongamos que introducimos el 3; seguidamente el bucle inicializa
la i y suma al valor de 0 (i=suma=0;). Como el valor de i (que es 0), es menor o igual que el valor de n (que es 3),
ejecuto el cuerpo del bucle, que asignar en la primera vuelta a la variable suma el valor de 0 (0+0), tras realizar el
cuerpo del bucle, incrementar el valor de ien 1, volviendo a comprobar la condicin: i<=n; as hasta dar cuatro
pasadas en el bucle, el valor de suma finalmente ser:

1 iteracin: suma=0+0;
2 iteracin: suma=0+1;
3 iteracin: suma=1+2;
4 iteracin: suma=3+3;

6, visualizando por pantalla:

Suma desde 0 hasta 3=6.

Ejemplo 2:

#include <stdio.h>

main() /*visualiza los nmeros del 0 al 9.*/


{

int digito, vueltas=0;


for (digito=0; digito<=9; ++digito){
printf("%d ", digito);
vueltas++;
}
}
Visualizar: 0 1 2 3 4 5 6 7 8 9

Como vemos tenemos dentro del for tres expresiones encerradas entre parntesis. La primera expresin asigna un
valor de 0 a la variable entera digito, la segunda expresin establece que el bucle se repetir hasta que el valor
actual de digito no sea mayor que 9, y la tercera expresin incrementa en 1 el valor de digito en cada pasada del
bucle.

Ejemplo de estructura for prescindiendo de la primera y tercera expresin:

Ejemplo 1:

#include <stdio.h>

main() /*visualiza los nmeros del 0 al 9.*/


{

int digito=0, vueltas=0;


for (; digito<=9; ) {
printf("%d ", digito++);
vueltas++;
}
}

Visualizar: 0 1 2 3 4 5 6 7 8 9

NOTA: El ejemplo anterior es equivalente a este, pero variando la sentencia for.

Ejemplo de estructura for con el operador coma:

Ejemplo 1:

...............
...............
for ((cont=0, contr=6); cont <=40; (++cont, --contr)) {
.........
.........
}
..............
..............

El efecto de este cdigo incorporando el operador (,) coma es:

En la primera entrada se inicializa cont y contr a 0 y a 6 respectivamente.


Se evala la condicin: cont <= 40, si es cierta seguimos, sino, salimos.

Se ejecuta el cuerpo del bucle for.

Se evala la expresin final, incrementando, y decrementando, cont y contr


respectivamente, y volvemos al paso 2.

4.4) Estructura while.

Esta estructura tiene el siguiente formato:

NOTA: Si slo consta el while de una sentencia, entonces podemos prescindir de las llaves ( { } ).

La condicin es cualquier expresin simple que al evaluarse devuelve el valor verdadero o falso. El bucle se repite
mientras la condicin sea verdadera. Cuando es falsa, el programa pasa a la instruccin siguiente, despus del cuerpo de
la estructura.

Si quisisemos hacer el equivalente del for con el while pondramos:

Si: for (expresin 1; expresin 2; expresin 3) sentencia

con el while sera:

expresin 1;
while (expresin 2) {
sentencia
expresin 3;
}

Tanto el while como el for son muy usados para recorrer arrays y cadenas de caracteres.

Ejemplo: Aqu presentamos la traza de un bucle while, la cual calcula la media entre los nmeros impares del 3 al 11,
realizando sumas sucesivas, culminando con la divisin de la suma de todos ellos entre el nmero de nmeros sumados,
mostrndose el resultado por pantalla.
Ejemplos.

El usar while o for es principalmente cuestin de preferencia personal. Por ejemplo, en:

while ((c=getchar()) ==' ' || c=='\n' || c=='\t')


;

/*ignora espacios en blanco. Su condicin recibe un carcter por teclado, con la instruccin getchar(), si el carcter
introducido es un espacio en blanco, un retorno de carro (nueva lnea), o un tabulador horizontal, sigo ciclando, y
pidiendo nuevos caracteres por teclado, hasta que el introducido sea distinto de los mencionados anteriormente.*/
en este caso no hemos hecho inicializacin o reinicializacin, por lo que el while es ms natural.

El for, en cambio es ms preferible cuando existe una inicialiazacin simple e incrementos, puesto que mantiene las
proposiciones de control del ciclo juntas y visibles al principio del mismo. Esto es ms obvio en:

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


............
............

que es la forma ms usual de procesar los primeros n elementos de un arreglo en C.

Ejemplos de estructura while:

Ejemplo 1:

#include <stdio.h>

main() { /* visualizar los nmeros del 0 al 9.*/

int digito=0;

while (digito<=9) {
printf"%d ",digito);
++digito;
}
}

Visualizar: 0 1 2 3 4 5 6 7 8 9

NOTA: Inicialmente se le asigna a digito el valor de cero. El bucle while visualiza el valor actual de digito,
incrementando su valor en uno y repitindose el ciclo, hasta que el valor de digito sea mayor que 9. El efecto total
es que el cuerpo del bucle se repetir diez veces, generndose diez visualizaciones de salida. Como en la
instruccin printf no hemos puesto un \n de salto de lnea, entonces, los nmeros del 0 al 9 aparecern seguidos, y
slo separados por un espacio en blanco, que es el que aparece entre comillas en la instruccin printf.

Ejemplo 2:

#include <stdio.h>

main() {

int i=0, j=0, final=40;

while(i<final) {

i=j*10;
printf("%d\n",i);
j++;
}
j=100; /* sentencia que ejecutamos cuando deje de cumplirse la condicin del while. */
}

Visualizar: 0

10
20
30
40

Traza:
1 comprobacin del bucle: (0<40), cierto.
2 comprobacin del bucle: (0<40), cierto.
3 comprobacin del bucle: (10<40), cierto.
4 comprobacin del bucle: (20<40), cierto.
5 comprobacin del bucle: (30<40), cierto.
6 comprobacin del bucle: (40<40), falso, entonces, nos vamos a la
sentencia: j=100;.

4.5) Estructura do-while.


El formato general de esta estructura es:

NOTA: Si slo consta el do-while de una sentencia, entonces podemos prescindir de las llaves ( { } ).

Ejemplo.

Por tanto, se trata de repetir el cuerpo del bucle (grupo de sentencias), hasta que la condicin se haga falsa (valor
nulo), o mejor dicho, vamos a ejecutar el grupo de sentencias mientras la condicin sea cierta (valor no nulo),
entonces, como mnimo siempre vamos a ejecutar el cuerpo del bucle al menos una vez, ya que la condicin de
salida (<exp-condicin>) la encontramos al final.

Ejemplo: Se muestra a continuacin la suma de los 7 primeros nmeros enteros con un bucle do..while mostrndose por
pantalla las diferentes sumas sucesivas, as como el resultado final.

Ejemplo.

Ejemplo de estructura do-while con una sentencia:

Ejemplo 1:

#include <stdio.h>

main() { /* visualizar los nmeros del 0 al 9.*/

int digito=0;

do

printf("%d ",digito++);
while (digito<=9);
}
Visualizar: 0 1 2 3 4 5 6 7 8 9

Ejemplo de estructura do-while con ms de una sentencia:

Ejemplo 1:

...........
...........
do {
printf("\n\nIntroduzca una letra: ");
c=getche(); /*devuelve el carcter leido desde la consola, y lo visualiza.*/
c=toupper(c); /* devuelve el carcter c en mayscula, y si no lo hay, devuelve el mismo*/
printf("\nSu mayscula correspondiente es: %c",c);
} while (c!='X');
j=100; /* sentencia que ejecutamos cuando deje de cumplirse la condicin del do-while. */
...........
...........

Traza: Hago dos retornos de lnea, por haber dos /n, y se visualiza:

Introduzca una letra:

Supongamos que introducimos una a, la cual ser almacenada en la variable c como 'a'.
Se transformar en mayscula con toupper(c) y ser de nuevo asignada a la variable
carcter c.
1 comprobacin: Como c tiene el valor de 'A', es distinto de 'X', condicin cierta,
seguimos en el bucle.
..............
..............
Los pasos anteriores se repetiran hasta que introdujsemos una x (ya sea mayscula o
minscula), que me haran falsa la condicin, y en consecuencia salir, y desplazarme a la
sentenciaj=100;.

4.6) Sentencias que rompen ciclos.

La sentencia break.
La sentencia continue.
La sentencia exit().
Sentencia goto.
La sentencia break:

Se utiliza para salir de un bucle (while, do-while o for), cuando se da alguna condicin especial. Cuando se ejecuta esta
sentencia, el control del programa pasa inmediatamente a la instruccin siguiente al bucle. La escribimos simplemente
poniendo:

Ejemplos.

Esta sentencia ya fue vista con el switch, en el cual era empleada para saltarse el resto de las posibilidades, cuando ya
habamos entrado en una.

La sentencia continue:

Fuerza a que comience una nueva vuelta dentro de la estructura correspondiente. Dentro de los ciclos
while, y do-while, se evala la condicin de salida; en el for, se efecta un salto a la expresin de incremento.
Se utiliza para saltarse el resto de la pasada actual a travs de un bucle. El bucle no termina cuando se encuentra una
sentenciacontinue, sencillamente no se ejecutan las sentencias que se encuentren a continuacin en l, y se salta
directamente a la siguiente pasada a travs del bucle.
Para usarse basta poner:

Ejemplo.
La sentencia exit():

Esta funcin devuelve el control al sistema operativo o a cualquier otro proceso anterior. La funcin permite devolver
un valor indicando si es una terminacin errnea o correcta. Esta funcin, incluida en <stdlib.h> tiene la siguiente
sintaxis:

Lo que realiza dicho de otra forma es, cerrar todos los archivos y buffers y termina el programa. El valor de status lo
recibe el proceso que realiz la llamada al programa, y me indica el estado de terminacin.

La sentencia goto:

La sentencia goto se utiliza para alterar la secuencia de ejecucin normal del programa, transfirindose el control a
otra parte de l. En su forma general, la sentencia goto se escribe

en donde etiqueta es un identificador que se utiliza para sealar la sentencia a la que se


transferir el control. Se puede transferir el control a cualquier otra sentencia del
programa. La sentencia por la que vamos a continuar ha de encontrarse etiquetada, y
dicha etiqueta ha de encontrarse seguida por dos puntos (:). Por tanto aparecer:
etiqueta: sentencia

Ejemplo.

Hemos de decir ante todo que aunque todos los lenguajes de propsito general populares poseen la sentencia goto, NO
ES ACONSEJABLE SU USO, ya que los elementos estructurados de C permiten realizar todas estas operaciones sin
tener que recurrir a la sentencia goto, sus usos ms habituales van en tres direcciones fundamentalmente:

Bifurcar a sentencias o grupos de sentencias bajo determinadas condiciones. Esto se puede


conseguir con la sentencia if-else.

Saltar al fin de un bucle en determinadas condiciones, no ejecutndose por tanto el resto del
bucle en la pasada actual. Esto lo podemos conseguir con la sentencia continue.

Finalizar totalmente la ejecucin de un bucle bajo determinadas condiciones. Esto lo podemos


conseguir con la sentencia break.

Hemos de decir, sin embargo, que hay situaciones espordicas en las que se hace til, no obstante no conviene cojerlo
como norma.

Ejemplos de sentencia break:

El ejemplo que se muestra a continuacin est realizado para los tres tipos de bucles, ste continuar mientras el valor
actual de la variable de coma flotante x no sea mayor que 100. Sin embargo, se saldr del bucle si se detecta un valor
de x negativo.
Ejemplo 1: (con un bucle while).

............
............
scanf("%f", &x);

while (x<=100) {
if (x<0) {
printf("ERROR - VALOR NEGATIVO DE X");
break;
}
/* procesar el valor no negativo de x, en este punto sabemos que dicha variable no es
negativa, ya que si lo fuera, hubisemos entrado en el if y hubisemos salido del bucle con
el break*/
.........
.........
scanf("%f", &x);
}

Ejemplo 2: (con un bucle do-while).

............
............

do {
scanf("%f", &x);
if (x<0) {
printf("ERROR - VALOR NEGATIVO DE X");
break;
}
/* procesar el valor no negativo de x */
.........
.........
} while (x<=100);

Ejemplo 3: (con un bucle for semejante).

............
............

for(cont=1; x<=100; ++cont) {


scanf("%f", &x);
if (x<0) {
printf("ERROR - VALOR NEGATIVO DE X");
break;
}
/* procesar el valor no negativo de x */
.........
.........
}
Ejemplo de sentencia continue:

Ejemplo 1:(con un bucle for).

#include <stdio.h>

main() {

char ch;
for (ch=getch(), ch!=0; ch=getch()) {
if (ch=='a' || ch=='a' || ch=='a' || ch=='a' || ch=='a' )
continue;
putchar(ch); /* devuelve el carcter escrito, si no hay errores */
}

NOTA: getch() asigna a ch el valor que le introduzcamos por la consola, pero no lo visualiza.

Si entro en el if ejecutar continue, la cual me llevar a la expresin de incremento del for, para seguidamente
comprobar de nuevo la condicin.

Ejemplo 2: (con un bucle do-while)

............
............

do {
scanf("%f", &x);
if (x<0) {
printf("ERROR - VALOR NEGATIVO DE X");
continue;
}
/* procesar el valor no negativo de x */
.........
.........
} while (x<=100);

En este ejemplo tras entrar en el if y ejecutar continue, pasar a evaluar la condicin de salida: (x<=100), en este
caso (de entrar en el if) no se ejecutar la parte en la que se procesa el valor actual de x si ste es negativo.

NOTA: Darse cuenta de las diferencias que hay con el break.

Ejemplo de sentencia goto:


Ejemplo 1: Este ejemplo trata de transferir el control fuera de un bucle si se da una condicin inesperada:

/*bucle principal*/
scanf("%f",&x);
while(x<=100) {
.........
.........
if(x<0) goto error;
........
........
scanf("%f",&x);
}
............
............
/*rutina de detecin de error*/
error: {
printf("ERROR - VALOR NEGATIVO DE X");
............
............
}

Como vemos transferimos el control fuera del bucle while, a la sentencia compuesta con la etiqueta error, si se
detecta un valor negativo de la variable x. Como vemos esto mismo lo podamos haber hecho usando la
sentencia break.

4.7) Bucles anidados.

Los bucles se pueden anidar uno en otro. Los bucles internos y externos no necesitan ser generados por el mismo tipo
de estructura de control. Sin embargo, es esencial que: UN BUCLE SE ENCUENTRE COMPLETAMENTE
INCLUIDO DENTRO DEL OTRO, ADEMS, CADA BUCLE HA DE SER CONTROLADO POR UN NDICE
DIFERENTE.

Hemos de introducirlos de esta forma:


do { /* 1 */

for (...............) { /* 1 */ while (..........) { /* 1 */ do { /* 2 */


.............. ......... ................
.............. ......... ................
for (..........) { /* 2 */ while (...) { /* 2 */
...... ......... } while (....);
...... .........
} /* fin de 2 */ }/* fin de 2 */ /*fin de 2 */
............... .......... ...............
............... .......... ...............
} /* fin de 1 */ } /* fin de 1 */ } while (....);
/* fin de 1 */

Importante: Hay que ver que el bucle ms exterior es el que manda, o sea, cuando deje de complirse la condicin del
bucle interior, no se ejecutar ms veces, si por el contrario, entramos dentro del bucle exterior, en cada vuelta del
exterior, se producirn sucesivas vueltas en el bucle interior, hasta que nos salgamos de ste, cuando se produzca esto, el
exterior podr dar su segunda vuelta (si se cumple su condicin).
6.1) Introduccin: Definicin de funciones.
Un principio de la programacin modular establece que un programa debe descomponerse en mdulos. A cada uno de
estos mdulos se le puede asociar una funcin. Cuando el programa se descompone en mdulos hay que determinar
cuando se debe terminar la descomposicin. Un buen principio de diseo es asociar a cada funcin una, y slo una, tarea
perfectamente definida.

El formato general en la definicin de una funcin es:

donde:

<tipo>: especifica el tipo de variable que devuelve la funcin. Si no especificamos ningn tipo la funcin es
de tipo entero.

<nombre>: identificador asignado a la funcin.

<param_formales>: son las variables que recibe la funcin cada vez que se invoca. Deben ir encerrados entre
parntesis. Si la funcin no emplea parmetros, los parntesis deben mantenerse.

<cuerpoFuncin>: consiste en un conjunto de declaraciones y sentencias que implementan la funcin. Para


salir de una funcin se utiliza la sentencia return, que produce la salida inmediata hacia el cdigo que la
invoc. La sentencia return puede devolver un valor acorde con el tipo que se ha indicado al declarar la
funcin. El valor puede indicarse con una variable, una constante o una expresin. Una funcin puede tener
varias sentencias return, es decir varias salidas.

Una funcin ha de disearse de la forma ms general posible. Es aconsejable que toda la informacin que necesite se
pase en los argumentos, de forma que no proliferen las variables globales, pues facilitan los errores laterales que se
crean cuando muchas funciones alteran las mismas variables.

Ejemplo:

int cabeceras(char *mensaje, int fila, int columna) {

if (fila>25 || fila<1 || columna<1 || columna>80)


return(0);
gotoxy(fila,columna);

printf(mensaje);

return(1);
}

/* La funcin retorna un entero, ya que nos lo indica el primer int que hay delante del nombre de la
funcin (cabeceras), esta funcin me devolver:
0: Si entro en el if.
1: Si no entro en el if.
mensaje es una forma de declarar un array de caracteres como un puntero. */

6.2) Variables locales y globales.

Las reglas de mbito de un lenguaje son las reglas que controlan si un fragmento de cdigo conoce o tiene acceso a otro
fragmento de cdigo o de datos.

Una variable local es aquella cuyo mbito se restringe a la funcin que la ha declarado se dice entonces que la
variable es local a esa funcin. Esto implica que esa variable slo va a poder ser manipulada en dicha seccin, y no
se podr hacer referencia fuera de dicha seccin. Cualquier variable que se defina dentro de las llaves del cuerpo de
una funcin se interpreta como una variable local a esa funcin.

Cuando una variable x es local a una funcin func1, significa que la funcin func1 es la propietaria de dicha variable, y
puede acceder a ella y modificarla. Si cualquier otra funcin del programa necesita conocer el valor de la variable x, es
la funcin func1 la que debe transferir el valor de x a travs del paso de argumentos en la llamada a la funcin. Si
adems esta funcin desea modificar el valor de dicha variable, entonces tendr que devolver el nuevo valor a func1, y
ser func1 quien se encargue de asignar el valor devuelto a su variable x.

El argumento formal (los veremos en la siguiente seccin) mbito de un argumento formal es el mismo que el de una
variable local; el argumento formal definido en la cabecera de una funcin slo podr ser accedido dentro del cuerpo de
dicha funcin, y no en otros lugares del programa.

Una variable global es aquella que se define fuera del cuerpo de cualquier funcin, normalmente al principio del
programa, despus de la definicin de los archivos de biblioteca (#include), de la definicin de constantes
simblicas y antes de cualquier funcin. El mbito de una variable global son todas las funciones que componen el
programa, cualquier funcin puede acceder a dichas variables para leer y escribir en ellas. Es decir, se puede hacer
referencia a su direccin de memoria en cualquier parde del programa.

Ejemplo: Se muestra la diferencia entre las variables locales y globales, con la consiguiente diferenciacin en los
mbitos que abarcan:

El uso de variables globales no es aconsejable a pesar de que aparentemente nos parezca muy til, esto se debe a varias
razones fundamentales:

Legibilidad menor.

Nos condiciona en muchos casos que el programa slo sirva para un conjunto de casos determinados.
El uso indiscriminado de variables globales produce efectos colaterales. Esto sucede cuando existe
una alteracin no deseada del contenido de una variable global dentro de una funcin, bien por invocacin,
bien por olvidar definir en la funcin una variable local o un parmetro formal con ese nombre. La correccin
de dichos errores puede ser muy ardua.

Atenta contra uno de los principios de la programacin, la modularidad. El bajo acoplamiento supone no
compartir espacios de memoria con otras funciones, y potenciar el paso de informacin (llamadas) para que la
funcin trate la informacin localmente.

Las variables declaradas dentro de una funcin son automticas por defecto, es decir, slo existen mientras se ejecuta la
funcin. Cuando se invoca la funcin se crean estas variables en la pila y se destruyen cuando la funcin termina. La
nica excepcin la constituyen las variables locales declaradas como estticas ( static ). En este caso, la variable
mantiene su valor entre cada dos llamadas a la funcin an cuando su visibilidad sigue siendo local a la funcin.

Una funcin siempre es conocida por todo el programa, excepto cuando se declara como esttica, en cuyo caso slo la
podrn utilizar las funciones del mismo mdulo de compilacin.

En C, todas las funciones estn al mismo nivel de mbito. Es decir, no se puede definir una funcin dentro de otra
funcin. Esto es por lo que C no es tcnicamente un lenguaje estructurado en bloques.

Tambin puede suceder que en un mismo mbito aparezcan variables locales y globales con el mismo nombre. Cuando
sucede esta situacin, siempre son las variables locales y argumentos formales los que tienen prioridad sobre las
globales. Para ver reflejado todo esto ms grficamente se muestra un ejemplo a continuacin:
6.3) Acceso y argumentos de funciones. Prototipos.

a) Acceso a una funcin:

Se puede acceder ( llamar )a una funcin especificando su nombre, seguido de una lista de argumentos cerrados entre
parntesis y separados por comas. Si la llama a la funcin no requiere ningn argumento, se debe escribir a continuacin
del nombre de la funcin un par de parntesis vacos. La llamada a la funcin puede aparecer sola (esto es, puede formar
una expresin simple), o puede ser uno de los operandos de una expresin ms compleja.

Ejemplo.

b) Argumentos de una funcin. Prototipos:

Los argumentos que aparecen en la llamada a la funcin se denominan argumentos actuales, mientras que
los argumentos formales son los que aparecen en la primera lnea de definicin de la funcin. (Tambin se llaman
los argumentos actuales, a veces, argumentos simplemente, o parmetros actuales). En una llamada normal a una
funcin, habr un argumento actual por cada argumento formal. Los argumentos actuales pueden ser constantes,
variables simples, o expresiones ms complejas. No obstante, cada argumento actual debe ser del mismo tipo de datos
que el argumento formal correspondiente.

Los parmetros formales son variables locales a una funcin, ya que son creados al entrar en la funcin (se crean en la
pila) y destruidos cuando sta termina. El tipo de variable declarado para cada parmetro formal debe ser el mismo que
se utilice cuando se llama a la funcin Si esto no sucede, pueden introducirse errores, ya que el compilador no verificar
los tipos. Para prevenir estos errores se emplean los prototipos de las funciones. Los prototipos consisten en declarar al
principio del programa (de cada mdulo si el programa contiene varios mdulos) las funciones que se utilizan y los tipos
de sus argumentos. De esta forma el compilador puede reconocer una incongruencia entre el prototipo de una funcin y
su llamada.
Los prototipos, tambin nos pueden solveltar los errores que se pueden dar al hacer una llamada a una
funcin func2 (que no devuelve un entero), y que aparece implementada debajo de func1, siendo llamada desde func1,
por tanto, para resolver el problema de orden de definicin son tiles igualmente los prototipos o declaraciones por
adelantado. Veamos como sera todo esto:

Los parmetros son siempre pasados por valor. Por tanto, el parmetro de la funcin recibe el valor de la variable que se
utiliza como argumento. Cualquier modificacin sobre estos parmetros no afecta a las variables que se utilizan para
llamar a la funcin, puesto que el parmetro en estos casos es una copia de esas variables.

Ejemplos.

Veamos un ejemplo en el que se modifica el valor de su argumento.

Se visualiza el valor original de a (a=2) cuando comienza la ejecucin de main. Este valor se pasa a la
funcin modificar, en donde se multiplica por 3 y se visualiza el nuevo valor. Ntese que se altera el valor del
argumento formal que se visualiza en la funcin. Finalmente, el valor de a en main (el argumento actual) se vuelve a
visualizar, despus de haberse devuelto el control a main desdemodificar.

Se genera la siguiente salida:

a=2 (desde main, antes de llamar a la funcin)


a=6 (desde la funcin, despus de modificar el valor)

a=2 (desde main, despus de llamar a la funcin)

Pasar los argumentos por valor tiene sus ventajas y sus desventajas. Algo positivo es que los valores hallados
dentro de la funcin no son vistos fuera de ella. Su desventaja es que impide que se transfiera informacin desde la
funcin hasta el punto de llamada mediante los argumentos. Por tanto, el paso por valor implica que la transferencia
de informacin slo puede realizarse en un sentido.

Cuando sea necesario modificar el valor de la variable utilizada para llamar a la funcin hay que pasar la direccin de
dicha variable. Por tanto, los parmetros deben ser declarados como punteros (se vern en temas sucesivos). El nico
caso en el que sin necesidad de especificarlo explcitamente se pasa la direccin de una variable como argumento es
cuando se pasa una matriz.

Las dos formas descritas anteriormente seran:

Paso por valor Paso por variable


Prototipo fun(int,int) fun(int *, int *)
Llamada fun(arg1,arg2) fun(&arg1, &arg2)
Implementacin fun(int par1,int par2) fun(int *par1, int *par2)

Ejemplo de acceso a una funcin:

Leer un carcter y convertirlo a mayscula utilizando una funcin definida por el programador que sea llamada desde el
programa principal ( main() ).

#include <stdio.h>

main()
{

char minus, mayus;


char minus_a_mayus (char); /* declaracin de funcin (lo veremos en el apartado 6.3) b))*/

printf("Por favor introduce una letra: ");


scanf("%c", &minus);
mayus=minus_a_mayus(minus);
printf("\nLa mayscula equivalente es: %c\n\n",mayus);

char minus_a_mayus( char c1) /* definicin de funcin */


{

char c2;

c2= (c1>='a' && c1<='z') ? ('A' + c1 - 'a'): c1;


return(c2);

Este programa contiene una llamada a la funcin definida por el programador minus_a_mayus. La llamada es una
parte de la expresin mayus=minus_a_mayus(minus).
Activar la funcin mediante la llamada a sta hace que se transfiera el valor de minus a la funcin. Este valor es
representado por c1 dentro de la funcin, con return(c2) devolvemos el valor de la mayscula que lo hemos
introducido anteriormente en la variable carcter c2.

Ejemplos de argumentos de una funcin:

Ejemplo 1:

Estas dos formas son equivalentes:

int cabeceras(mensaje, fila, columna)


char *mensaje;
int cabeceras(char *mensaje, int fila, int columna) { int fila;
if (fila>25 || fila<1 || columna<1 || int columna;
columna>80) {
return(0); if (fila>25 || fila<1 || columna<1 ||
gotoxy(fila,columna); columna>80)
printf(mensaje); return(0);
return(1); gotoxy(fila,columna);
} printf(mensaje);
return(1);
}

Para esta funcin se declarara el prototipo:


int cabeceras (char *, int, int);

6.4) Argumentos de main().

Los argumentos pasados en la lnea de rdenes del DOS a un programa son recibidos por la funcin main(). Existen dos
variables predefinidas dentro del lenguaje que reciben los argumentos que se pasan al ejecutar un programa.

Tipo Labor que realiza


argc entero contiene el nmero de argumentos que se han introducido.
argv array array de punteros a caracteres.

El argv contiene los argumentos que se han pasado desde el sistema operativo al invocar el programa. La declaracin de
los argumentos es:

La variable argc como mnimo valdr 1, ya que el nombre del programa se toma como primer argumento, almacenado
con argv[0], que es el primer elemento de la matriz. Cada elemento del array apunta a un argumento de la lnea de
denes. Todos los argumentos de la lnea de ordenes son cadenas.

Ejemplo:

Estas dos formas son equivalentes:


#include <stdio.h>
#include <stdio.h>
main(argc, argv)
int argc; main(int argc, char *argv[])
char *argv[]; {
{
if(argc!=2) {
if(argc!=2) { printf("Ha olvidado su nombre.\n");
printf("Ha olvidado su nombre.\n"); exit(1);
exit(1); }
} printf("Hola %s", argv[1]);
printf("Hola %s", argv[1]); }
}

Este programa imprime Hola y su nombre en la pantalla si se escribe directamente tras el nombre del programa.
Supongamos que hemos llamado al programa nombre.c, entonces, al compilarlo se crear un nombre.exe, al llamar al
programa nombre con un nombre, por ejemplo: Juan, para ejecutar el programa tendr que introducir nombre Juan. La
salida del programa sera Hola Juan.

En la mayora de los entornos, cada argumento de la lnea de rdenes debe estar separado por un espacio o una
tabulacin. Las comas, puntos y comas, y similares no se consideran separadores.

Por ejemplo: Si hubisemos introducido:

nombre Pepe, Antonio, Miguel

Sern consideradas como tres cadenas, y la salida sera:

Ha olvidado su nombre.

ya que entraramos en el if por ser (argc!=2) cierto. Sin embargo:

nombre Pepe,Antonio,Miguel

es una sola cadena, ya que las comas no son separadores vlidos. La salida sera:

Hola Pepe,Antonio,Miguel

6.5) La sentencia return y las funciones de tipo void.

La sentencia return tiene dos usos importantes. Primero, fuerza una salida inmediata de la funcin en que se encuentra.
O sea, hace que la ejecucin del programa vuelva al cdigo que llam a la funcin. En segundo lugar, se puede utilizar
para devolver un valor.

La vuelta de una funcin ocurre cuando se ha ejecutado la ltima sentencia de la funcin y, conceptualmente,
se encuentra la llave } del final de la funcin.

Todas las funciones, excepto aquellas de tipo void, devuelven un valor. Este valor se especifica
explcitamente en la sentencia return. Si no la sentencia return, el valor devuelto por la funcin queda
tcnicamente indefinido. En otras palabras mientras una funcin no se declare como void, puede ser usada
como operando en cualquier expresin vlida de C.

Veamos todo esto en un ejemplo grficamente:

Si una funcin devuelve un entero, no es necesario declararla de tipo int, pues para el lenguaje todas las funciones
devuelven un entero, a menos que se indique lo contrario. Si una funcin que devuelve un carcter se declara de tipo
entero, el carcter se convierte adecuadamente, por lo que no es necesario declarar la funcin de tipo carcter.

Cuando un funcin no devuelve un valor entero, se debe especificar el tipo de resultado que entrega antes de llamar a la
funcin. No obstante, si se declaran prototipos para las funciones, no hay por qu preocuparse posteriormente del orden
en que se declaran las funciones.

Ejemplo:

#include <stdio.h>

int mul(int, int); /* prototipo */

void main (void) /* no recibe nada ni devuelve nada la funcin principal (main()) */
{
int x=10, y=20, z;
z=mul(x,y); /* 1 */
printf("El resultado es: %d",mul(x,y)); /* 2 */
mul(x,y); /* 3 */
}

mul(int a, int b)
{
return(a*b);
}

Esta funcin devuelve a la salida:

El resultado es: 200

En la lnea 1 el valor de vuelta de mul() es asignado a z.

En la lnea 2 el valor de vuelta no se asigna, sino que se usa la funcin printf().

Finalmente en la lnea 3 el valor de vuelta se pierde porque no se asigna a otra variable ni se usa como parte
de una expresin.

Você também pode gostar