Sei sulla pagina 1di 27

c 


       
    c


 c

En el siguiente link puede encontrarse una descripción general del lenguaje C.

½? ëescripción General del Lenguaje C (G  )

  c

Œn ejemplo simple de un programa en gcc, el que es equivalente a este otro programa


en gcc (modificado). La diferencia radica en que en el primero las funciones son
definidas después de que han sido utilizadas y en el segundo las funciones son definidas
primero y luego utilizadas, además de que en ésta no se incluyen las librerías ï y
ï   . En ambos casos la ejecución de los programas comienza dentro de la función

 donde se declaran tres variables locales i1, i2 e i3. Luego se ejecutan las siguientes
instrucciones:

Se asigna a la variable i1 el valor de la constante MAX que fué definida anteriormente


con un valor del tipo entero 2.
Se asigna a la variable i2 el valor del tipo entero que retorna la llamada a la función
denominada: cuadrado(i2). El parámetro de entrada de esta función es i1, cuyo valor es
2. Como ésta función retorna el valor de i1*i1, el valor de i2 es 4.
Se asigna a la variable i3 el valor de la función cubo(i2), en este caso 64.
Para indicar el estado en el que el programa ha terminado se utiliza la función
return(EXIT_SŒCCESS)

Ejemplo en lenguaje C, de la simulación de compra de un boleto en el metro.

  !

Los identificadores son los "!#!   !!!"!


  c, como ser:

½? unciones.
½? *ariables.
½? Constantes simbólicas.
½? Estructuras de datos.
½? ëefiniciones de tipos (hechas mediante typedef).

Los   !!!$ con:


½? Letras (las del alfabeto mayúsculas y minúsculas, menos la ñ, Ñ y las
acentuadas). No es posible emplear acentos o caracteres especiales del alfabeto
español.
½? ëígitos numéricos (0, 1, 2, 3, 4, 5, 6, 7, 8, 9)
½? Símbolo de subrayado ( _ )

Sin embargo,   "!  . Las letras mayúsculas se


consideran diferentes a las minúsculas (u ï ï ï  ). Tampoco pueden emplearse
como identificadores el conjunto de palabras reservadas del lenguaje C:

auto double if static


break else int struct
case entry long switch
char extern register typedef
continue float return union
default for sizeof unsigned
do goto short while

En la práctica,   !" $ %&'!     $"  


"! compuestos por varias palabras. Además, se acostumbra emplear letras
minúsculas para nombrar a las variables y las mayúsculas se reservan para las
constantes simbólicas.

Se recomienda "!#! ! (!   que se defina o


del valor que la variable guarde. Por ejemplo, una variable que guardará la edad de un
empleado podría llamarse  
  o  , y no simplemente , aunque éste es
un identificador válido y el programa funcionará correctamente este nombre.

!


Los siguientes son todos identificadores válidos en C.

puntero
nombre_empleado
area
TAMANO_STRING
EdadEmpleado
potencia10
i
For
iF
Nombre
nombre

En el caso de los dos últimos, se consideran identificadores distintos (¿por qué?).

Los siguientes son identificadores inválidos. Entre paréntesis se indica por qué.

1texto (empieza con un número)


nombre-empleado (no se puede usar el guión, sólo el subrayado)
teléfono (no se pueden usar caracteres especiales del Español)
while (esta es una palabra reservada del lenguaje C)

*  "!

Para poder resolver un problema empleando un computador es necesario contar con


algún  !      ! en forma temporal. Esto se logra con las
 ï.

En C, las variables reciben nombres que respetan las reglas de los identificadores.
Además,  (  "" ! ! , que define básicamente
la clase de dato que se almacenará en ella y la forma en que deberá ser tratado.

Como se verá más adelante,  (  ""!   (  !!


  , y esto debe hacerse respetando una sintaxis establecida.

En resumen: ) (  "!"#    *! !  


  $ 

La forma genérica es la siguiente:

ƒtipo> ƒidentificador> [ ß ƒvalorInicial>] ;

ëonde <tipo> puede ser:   u . [] significa opcional. <valor_inicial> puede
corresponder a una constante del tipo entero, real, caractér, arreglo, etc..

Ejemplo de declaraciones de variables:

int numero ;
char nombre ;

Ejemplos de declaraciones de variables asociados a un dato:

int numero = 10 ;
Char nombre = ´G´ ;

Las variables pueden ser declaradas como globales (pueden ser utilizadas y modificadas
por todas las funciones), locales (sólo pueden ser utilizadas y modificadas por la
función donde se definió a ésta) y static (pueden ser utilizadas sólo por la función que
definió a ésta y además no inicializada cada vez que se la utiliza ). Más detalles de la
declaración de variables y asignación de valores a las variables.

å!+ !

Cada uno de los distintos objetos que son manipulados dentro de un programa tiene
asociado un  ï. ëesde el punto de vista de almacenamiento o para llevar a
cabo operaciones sobre estos objetos, es necesario tratarlos de distinta manera. Así, la
mayoría de los lenguajes de programación separan aquellos objetos que son caracteres
de los que son números enteros y números con decimales.

En el caso del lenguaje de programación C, !! !,! ! son:

½? Los tipos enteros:  (-32768 a 32767), ï  (-128 a 127) y   (-


4294967296 a 4294967295) para manipular números enteros.
½? Los tipos reales:  (con 7 decimales de aproximación) y   (con 16
decimales de aproximación) para manipular números con decimales.
½? El tipo: u  (´a´,´z´,´?´,´$´,´@´,´G´,´7´, etc. En total los 256 caracteres del
código ASCII) para caracteres, letras y símbolos.
½? Así como algunos más complejos como los ï y los  ï

Además, es posible definir  ï ïu


ï a partir de los tipos básicos
existentes en el lenguaje.

Es importante recordar que todo objeto dentro de un programa tiene un tipo de datos
asociado, y es necesario tener esta asociación en mente a la hora de manipular,
almacenar, operar y hasta desplegar en pantalla dicho objeto.

å!!

Las variables de tipos de datos enteros pueden almacenar únicamente ( !


-!! !. Si se intenta almacenar un valor con decimales en una
variable entera, se producirá un  u
  del valor.

El tipo entero básico es  . Existen además las variantes ï  , que permite
almacenar valores más pequeños (con el subsecuente ahorro de espacio en memoria), y
el   , que soporta números más grandes (pero con mayor gasto de memoria).

El valor máximo que se puede almacenar en las variables de cada uno de estos tipos
depende de la arquitectura del computador y del compilador que se estén empleando.

å! !

Las variables de tipos de datos reales pueden almacenar valores numéricos con
decimales.

El tipo real básico es  . Existe también la variante  , que permite almacenar
valores en  uï , más grandes y con mayor cantidad de decimales. Sin
embargo, el uso de este tipo provoca un mayor gasto de memoria que si se empleara el
tipo básico  .

La cantidad de decimales, así como el valor máximo que se puede almacenar en


variables de estos tipos depende de la arquitectura del computador y del compilador que
se estén empleando.

c  !
å ! u 
Las variables de tipos de datos u , pueden almacenar un caracter del u
á á (256 caracteres). En realidad, lo que se guarda no es el caracter en sí, sino el
código correspondiente. Por lo tanto, puede verse al tipo u  como un subtipo del tipo
 , que puede almacenar enteros entre 0 y 255. ëe hecho, las expresiones de tipo u 
pueden manipularse como enteros.

Las constantes de tipo u  se representan delimitadas por comillas simples. Así, para
escribir el caracter que representa la letra A mayúscula escribimos:

'A'

El hecho de que las expresiones de tipo u  se consideren como enteros permite llevar
a cabo (!!.!!u $.!!. Por ejemplo, es
posible llevar a cabo las siguientes asignaciones, las cuales son todas equivalentes y
almacenan en la variable correspondiente la letra A mayúscula (código ASCII 65).

char ch;
int i;

ch = 65;
i = 'A';

ch = 'A';
i = 65;

Además, puede emplearse el símbolo \ para denotar caracteres mediante su código


ASCII. Con esta notación, el caracter 'A' puede representarse también como:

'\65'

Esta notación es muy útil para representar caracteres especiales, que no aparecen en los
teclados y no se pueden ver en la pantalla. Este es el caso del caracter nulo (ASCII 0):
'\0', el cual se empleará más adelante para indicar el final de los ï  ï. Así, las
siguientes son representaciones equivalentes en C para el caracter constante que
representa la letra A mayúscula:

'A'

65

'\65'

La preferencia en usar la tercera notación y no la segunda es por simple claridad, para


dejar bien claro que se está manipulando un caracter y no un número (aunque para el C
es lo mismo).

Otros caracteres especiales que se pueden representar mediante esta notación son:

'\n':

½? Caracter de nueva línea (muy usado en  , más adelante)

'\t':
½? Tabulador (también útil en  )

'\\':

½? Caracter \ (esta es la única forma de especificarlo)

Más adelante estudiaremos cómo organizar los caracteres como arreglos de u , de


manera que puedan manipularse cadenas de texto (ï  ï). Las cadenas de texto se
especifican entre comillas dobles: "iic1102 sección 3"

!

Œna función es un !! (posiblemente acompañadas de algunos


datos temporales) que llevan a cabo una subtarea dentro de un programa más complejo.

Por ejemplo, dentro de un programa que convierte una lista de temperaturas expresadas
en grados ahrenheit, a grados Celsius , podríamos definir una función que haga una de
las conversiones, y la emplearíamos varias veces para lograr completar nuestra tarea.

Tenemos entonces que  ! !  !"  !,


para las cuales !! !! ! ! !  *$
  !*"!"!  ! !!  . Para el
caso de una función que calcula el área de un círculo, la entrada que requiere la función
sería el radio del círculo, y la salida que arrojaría luego del cómputo sería el valor para
el área. Este hecho se ilustra en el diagrama que se muestra abajo, en el que podemos
ver la tarea de transformación de datos que cumple una función: !  

ïu 
    u 
ï ï   ïï .

Por otra parte, para especificar el proceso de transformación que debe llevar a cabo la
función, es necesario emplear las instrucciones del lenguaje de programación. Es
necesario respetar algunas pautas, tanto para la especificación de los parámetros de
entrada, como del valor de retorno, pero la estructura general es la misma.

!#   

/ .!  !

La sintaxis general de definición de las funciones es la siguiente:


ƒtipo_retorno> ƒnombre_función>  ƒlista_parámetros> 
ƒdeclaración_de_variables_locales> 
ƒcuerpo_de_la_función> 
(ƒvalor_retorno>) 

ƒtipo_retorno es el tipo del valor que devolverá la función. !!" 


!#((0(  (para por ejemplo definir funciones que
solo imprimen valores o ciertos mensajes en pantalla, para los que no es necesario que
devuelva valor alguno). Para definirlos o declararlos, se utiliza como tipo de retorno la
palabra reservada ( A estas funciones se las conoce también como !,
porque no devuelven ningún valor.

ƒnombre_función debe ser sustituido por un identificador que corresponde al nombre


con que se invocará la función posteriormente (o llamada de la función). ëebe ser un
identificador válido. El (   ! !  " 
.

<lista_parámetros> corresponde con una lista de variables denotadas por identificadores


asociados a un tipo, cada uno representa un parámetro de entrada. La lista de
parámetros puede ser vacía pero ! -!!"  .

La <declaración_de_variables_locales1 se refiere a (  "! ! que podrán ser


utilizadas únicamente dentro de la función. uera de ella, no serán reconocidas.

El <cuerpo_de_la_función> es una lista de instrucciones, separadas por punto y coma.

<valor_retorno>, debe ser una expresión (constante, aritmética, lógica del tipo que se
especificó como <tipo_retorno>, y establece la expresión que retornará la función una
vez que haya terminado.

!


½? unción que convierte temperaturas ahrenheit a Celsius


½? unción que convierte temperaturas Celsius a ahrenheit
½? unción que calcula el área de un círculo

/ .!      !!  ! 

La sintaxis general de las llamadas a las funciones definidas es la siguiente:

ƒvariable> = ƒnombre_función> ( ƒlista_parámetros> ) ;

ƒvariable corresponde a una variable denotada por un identificador del mismo tipo del
valor que devolverá la función.

ƒnombre_función es el identificador que corresponde al nombre con que se invoca a


la función.

<lista_paramétros> debe corresponder a una lista de variables denotadas por


identificadores asociadas a un tipo, o expresiones de un tipo. Ya sean variables o
expresiones, éstas deben corresponder en cuanto a cantidad, posición y tipos a las
variables que se definieron como parámetros de entrada en la definición de la función.
Representan los valores que se entregan como entrada a la función. Si en la definición
de la función no se usó parámetro alguno, entonces en la llamada tampoco debe
escribirse ninguna expresión o variable, pero ! -!!"  .

!


½? Llamada a la unción que convierte temperaturas ahrenheit a Celsius


½? Llamada a la unción que convierte temperaturas Celsius a ahrenheit
½? Llamada a la unción que calcula el área de un círculo

 ,!  $* 2

Tal y como se mostró en el diagrama presentado anteriormente, las funciones


transforman una entrada para producir una salida.

La materia prima con la que trabajará la función le es pasada a través de sus


 ,!  .

El resultado del procesamiento llevado a cabo por la función es devuelto como su ( 
.

Tanto los argumentos de entrada como el valor de retorno tienen un tipo de datos
asociado. En el ejemplo de la función que calcula el área de un círculo, los parámetros
de entrada son la constante pi y el radio del círculo, de tipo real ( ), y el valor de
retorno, también real, es el valor calculado para el área.

    @$!  !c

)  c*!,  (  !!!. Estas instrucciones son


escritas dentro de funciones que realizan una tarea en particular con los parámetros de
entrada, para devolver valores que corresponden a sus resultados. Algunas instrucciones
son escritas fuera de las funciones, éstas son algunas directivas como #include, #define
o declaración de variables. )   "-! !.

 "3    0! !!!.


Básicamente, este orden comienza por la ejecución de las directivas (#include y
#define), declaraciones de variales globales que se encuentran escritas al principio del
programa. Luego el orden de ejecución continúa tomando en cuenta inicialmente la
función
 Esta función consta también de declaraciones, instrucciones y llamadas a
las definiciones de otras funciones. El orden de ejecución de las instrucciones dentro de
la función
 es secuencial de arriba a abajo y es así como es posible recién seguir la
ejecución del resto de las funciones.

Para el primer programa visto en este capítulo vea su orden de ejecución.

.!!
Se conocen como expresiones los valores que son manipulados dentro de un programa.
Estos valores !!    !*( !
 ! !* . ! !(  "!*!
!! !.!  !   .

Las expresiones, al igual que el resto de las entidades dentro de un programa, tienen
asociado un tipo de datos. Este tipo indicará la forma en que podremos manipular la
expresión, por ejemplo, en cuáles variables podremos almacenar su valor.

Existe un conjunto de operadores para cada tipo de datos, de manera que siempre es
posible construir una nueva expresión a partir de una o varias ya existentes. Tenemos,
por ejemplo, operadores aritméticos para construir expresiones numéricas, y operadores
lógicos para construir expresiones booleanas.

.!!4- !

 !.!! - !!( !-!*!! s.


Pueden ser constantes, resultados de operaciones aritméticas como sumas o
multiplicaciones, contenido de variables numéricas, o combinaciones de las anteriores
unidas mediante operadores aritméticos.

5 !" !




+ Suma

- Resta

* Multiplicación

/ División

% Módulo (sólo sobre tipo int)

5 ! !




- Signo negativo

++ Incremento

-- Decremento




++ -- -(unitario)

* / %

+ -

4! ( 


Por la izquierda

.!!
Los operandos pueden ser variables o constantes numéricas. Sin embargo, los
operadores unarios ++ y -- fueron pensados para aplicarse a variables y el operador
unario - a constantes.

operando operador -binario operando

operador-unario operando

Caso particular:

½? ++ -- (notación pre o postfija)

!.!! - !


2 + 3 * 2 * tiene precedencia sobre + (Resultado: 8)

(2 + 3) * 2 los paréntesis alteran la precedencia (Resultado:


10)

-2 / x si x vale ce ro se producirá un error de ejecución

x++ notación postfija (retorna el valor antes del


incremento)

++x notación prefija (retorna el valor después del


incremento)

2 - 1 + 3 asociatividad por la izquierda: 4

15 % 6 operador módulo o residuo (Resultado: 3)

-x le cambia el signo al contenido de x


3 * 4 % 5 igual precedencia, pero es asociativo por
izquierda (Retorna: 2)
3 * (4 % 5 ) los paréntesis alteran la precedencia (Retorna:
12)
1 + 15 % 6 % tiene precedencia mayor (Retorna: 4)

.!! !6  !

A diferencia de otros lenguajes de programación, C no cuenta con un tipo de datos que


permita manipular valores booleanos, o de verdad. Este tipo de valores se emplean para
dirigir al programa por un determinado flujo de ejecución dependiendo de la evaluación
a   o  ï de una expresión lógica.

En C, las instrucciones que dependen de valores lógicos dependen en realidad de un


valor entero que se interpreta como  ï cuando es cero, y como   en caso
contrario (es decir, cuando es distinto de cero).

5 !" !




&& ‰  (hace la conjunción lógica de dos valores booleanos -


enteros-).
|| G (hace la disjunción lógica de dos valores booleanos -
enteros-).

5 ! !




! G lógico

5 !  !  




Este tipo de operadores permite comparar el valor de dos expresiones de cualquier tipo,
devolviendo como resultado un valor booleano (entero).

== igual

!= distinto

ƒ menor

ƒ= menor o igual

> mayor

>= mayor o igual




La precedencia está establecida por el siguiente orden de evaluación. La asociatividad


se aplica de izquierda a derecha, para operadores con igual precedencia.

ƒ ƒ= > >=

== !=

&&

||

.!!

Los operandos de las expresiones booleanas son valores enteros (booleanos),


incluyendo aquellos que resulten de la comparación mediante los operadores
relacionales mencionados anteriormente. Pueden emplearse paréntesis para dejar clara
la precedencia de evaluación.

operando operador -logico-binario operando

operador-logico-unario operando

!.!!"  !


x Verdadero cuando el contenido de la variable x


es distinto de 0.

!x Verdadero cuando el contenido de la variable x


es igual a 0.

1 Verdadero siempre.

1 || x Verdadero siempre, no importa lo que sea x.

0 Falso siempre.

0 && x Falso siemp re, no importa lo que sea x.

(x > 5) && !y Verdadero cuando el contenido de la variable x


es mayor que 5, y el contenido de y es 0.

(x==1) Verdadero si el valor de la variable x es 1.

5 == 6 retorna 0, osea Falso.


4 >= 2 Retorna 1, osea Verdad.
((4 % 2 == 0) || (4 % 3 == 0) && 0


  !! !c


Máxima

( ) [ ] - ->
! ~ ++ --
* / %
+ -
ƒƒ >>
ƒ ƒ= > >=
== =
&
|
&&
||
= += -= /=

Mínima

!!

Las instrucciones son las órdenes que reconoce un computador mientras se encuentra
ejecutando un programa. ëe hecho, un programa es una ! !!
que al ejecutarse resuelve algún problema para el usuario.

Los programas están escritos en un lenguaje de programación, el cual define el conjunto


de instrucciones válidas que podemos utilizar al escribirlos.

En nuestro caso emplearemos el lenguaje de programación C, por lo que será necesario


que estudiemos las instrucciones que componen dicho lenguaje. A lo largo del curso
vamos a ir introduciendo estas instrucciones de manera paulatina, hasta llegar a cubrir
un subconjunto bastante importante del lenguaje.

Las instrucciones disponibles pueden clasificarse dentro de alguna de las siguientes


categorías:

½? Secuenciales
o? Ejemplos: declaraciones de variables, asignaciones, llamado a funciones,
salida ( ) y entrada (ïu )
½? Control de flujo (o decisión)
o? Ejemplos: , ï u
½? Iteración
o? Ejemplos: , ,  

/ .!

La sintaxis de las instrucciones en C varía bastante dependiendo de cada instrucción. En


general, toda instrucción debe ir terminada por un $ , de la siguiente
manera:

ƒinstruccion> ;

Existe instrucciones complejas que pueden abarcar varias líneas, y que pueden contener
otras instrucciones dentro de ellas en forma subordinada.

Además, las instrucciones se pueden agrupar en bloques, delimitados por corchetes: { },


de la siguiente manera:


 ƒinstruccion1> ;
ƒinstruccion2> ;
...
ƒinstruccionN> ;

+  *  "!$4! 

Las variables permiten representar los datos que se están manipulando dentro de un
programa. Como se mencionó anteriormente, todas las variables tienen un tipo de datos
asociado, el cual determina la forma de almacenar e interpretar los datos en las
variables.

+  *  "!

  3  (  "!!    ( 


0,"% *" *! ' Esta declaración debe incluir el tipo y el
identificador con que se hará referencia a la nueva variable. Es posible introducir varias
variables del mismo tipo dentro de la misma declaración. La sintaxis general de una
declaración de variables es la siguiente:
ƒtipo1> ƒlista_de_variables > ;
ƒtipo2> ƒlista_de_variables> ;
...
ƒtipoN> ƒlista_de_variables> ;

Las listas de variables están formadas por una serie de identificadores válidos,
separados por comas, de la siguiente manera:

ƒidentificador1>, ƒidentificador2>, ..., ƒ identificadorM>

La declaración de variables puede aparecer en el nivel más alto del programa (fuera de
toda función), en cuyo caso el ámbito de las variables ahí declaradas lo será el programa
en su totalidad, incluyendo todas las funciones. A este tipo de variables se les conoce
como " !.

Las declaraciones que son internas a las funciones provocan que el ámbito en donde son
reconocidas las variables se limite a la función en que son declaradas. A estas se las
conoce como  !

  *  * (  "(   


(.*( #   !  
  *# (  "    ,!   

En todo caso, para poder referenciar una variable global dentro de una función, la
declaración debe aparecer anterior a la definición de la función.

Œna característica que resulta a menudo de mucha utilidad, es la posibilidad de dar un


valor inicial a las variables en el momento de su declaración. Esto se logra de la
siguiente manera:

ƒtipo> ƒidentificador> = ƒvalor_inicial> ;

Es importante recordar que la existencia de una variable está limitada a la existencia de


la función en que fue declarada. Esto quiere decir que los valores almacenados en una
variable   para posteriores llamados a la función en que está declarada. Sin
embargo, es posible hacer que estos valores sean permanentes y que se mantengan
intactos a lo largo de la ejecución del programa. Para esto, es necesario declarar las
variables como !, !, de la siguiente manera:

ï
 ƒtipo> ƒidentificador> ;

Las variables definidas dentro de una función con la característica !  se comportan,
en cuanto a la perdurabilidad de los valores que se almacenan en ellas, de la misma
manera que las variables globales. Es decir, estas variables se crean una única vez y los
valores guardados permanecen durante toda la ejecución del programa. Sin embargo, su
alcance es limitado y pueden ser accesadas únicamente desde la función en que fueron
declaradas.

!

½? int suma, producto;


o? Se declaran dos variables, ï
y u , ambas de tipo  .
½? int acumulado=0;
o? Se declara la variable u
 , de tipo  , y se inicializa con el valor
0.
½? static float interes;
o? Se declara la variable  ï, de tipo  , y con la característica de
estática, por lo que su valor perdurará entre distintos llamados a la
función en que está siendo declarada.

Ejemplo de un programa que utiliza variables globales, locales y static que muestra la
vida útil de las variables..

5 4! 

El operador de asignación ( = ) permite almacenar datos en las variables. Es un operador


binario, que requiere que su primer operando (el del lado izquierdo) sea una variable. El
segundo operando (el del lado derecho) puede ser otra variable, un valor constante, o
una expresión en general. La sintaxis general de este operador es la siguiente:

ƒvariable> = ƒexpresion> ;

En caso de que el valor_asignado sea una constante, el resultado de esta operación es


que el valor expresado se almacenará en la variable especificada al lado izquierdo.

Si el valor_asignado es otra variable, se hará una copia del valor almacenado en la


segunda variable y se almacenará en la variable del lado izquierdo. Si se trata de una
expresión, ésta se evaluará previamente y su resultado se almacenará en la variable
indicada.

En todo caso, es necesario tener en cuenta algunas consideraciones sobre los tipos de las
variables y de los valores que se están asignando. Más adelante se tratarán los aspectos
relativos a la conversión de tipos.

!

½? indice = 0;
o? Se almacenará el valor 0 en la variable í u
½? suma = a+b;
o? Se obtendrá la suma de las variables y , y el resultado se almacenará
en la variable ï

½? NuevaX = *iejaX;
o? El valor de la variable *  se copiará a la variable  
½? j = (i = 9)
o? Asigna el valor de 9 a las variables  y


 "!(  "!%( !!'
En este ejemplo ilustraremos la problemática de intercambiar el contenido de dos
variables. Al igual que cuando nos enfrentamos al problema de intercambiar el
contenido de dos vasos, en este caso será necesario emplear un tercer elemento de
almacenamiento (variable o vaso), para guardar temporalmente durante el intercambio
uno de los contenidos.

½? ëiagrama del intercambio empleando los vasos


½? Código en C para intercambio de variables (ï )


* 7 !*  "!

Se muestra un programa con una función en la que se declaran dos variables, una de
tipo ï u y otra con existencia limitada (no ï u). El valor almacenado en la variable
de tipo ï u sobrevive a varios llamados mientras que la otra pierde su valor anterior y
deberá ser inicializada nuevamente en cada llamado.

½? Código en C para el ejemplo


½? Ejemplo de ejecución

Esquema de la vida útil de las variables


 ,! !!

Se muestra un programa con una variable global y una función que recibe un parámetro.
Se ilustra el paso de parámetros a la función y la forma en que la función devuelve
valores. Además, se muestra como dichos parámetros son copiados a almacenamiento
temporal de la función al hacer el llamado, por lo que los cambios de que son objeto no
afectan el parámetro real que se pasó.

½? Código en C para el ejemplo


½? Ejemplo de ejecución

c(!å!%å á'

 c "  ! !.!!


(   " ! ! !. Existen  !! !(!!#!(  
 "   , sin participación del programador. Por ejemplo, si se asigna
una expresión entera a una variable de tipo real, el valor de la expresión se convertirá
primero al tipo real antes de llevar a cabo la asignación. Este resulta ser el caso más
simple de una conversión de tipos, pero existen algunas situaciones en las que se
requiere de cierta atención especial:

½? ëe un tipo real a uno entero


o? Se trunca el valor a su parte entera. La parte decimal se pierde.
½? Asignaciones entre u  e 
o? Puesto que en C se manejan los caracteres mediante su código ASCII
(que es un número entero), este tipo de asignaciones funciona en general
sin problemas.

Además, existen conversiones de tipo que se llevan a cabo en el momento de evaluar


expresiones aritméticas, por ejemplo, al intentar sumar un valor  con uno  . En
estos casos,     #  á*! !*
!( á*! !
*$! !,á
%
'. En general:

½?  se convierte en   y 


½? u  se convierte en 
½? si hay un operando  , el otro se convierte a   y el resultado es  

Por último, es posible hacer una conversión de tipo en forma explícita, indicando entre
paréntesis el tipo al que se quiere convertir una determinada expresión. Esto se hace
siguiendo la siguiente sintaxis:

(ƒtipo>) ƒexpresion>

!

½? parte_entera = 7/4;
o? A la variable     se le asignará el resultado de la división pero
truncado: 1
½? (int)(7.0/4.0)
o? El resultado de esta expresión también es 1
½? 7.0/4.0
o? El resultado de la división será exacto, con todos los decimales
½? 7.0/4
o? Se convierte el 4 a 4.0 y la división arroja decimales
½? x = 7.0/4.0
o? El resultado de la división tendrá decimales, pero si la variable  es de
tipo entero al asignar el valor habrá truncamiento.
½? (float)1
o? Convierte 1 a tipo  , resultando en 1.0

!   

Œn programa es un conjunto de instrucciones y datos que implementan la solución a un


problema. En el caso del lenguaje de programación C las instrucciones están
estructuradas como un conjunto de funciones, cada una de las cuales cumple con alguna
tarea en particular.

Existe una función principal (llamada


 ), que debe aparecer en todo programa, y
que será llamada en forma implícita cuando la ejecución del programa dé inicio. Es
común visualizar esta función como una especie de programa principal, desde donde se
hacen llamados a las demás funciones para implementar la solución al problema en
cuestión.

Al igual que las instrucciones, los datos del programa también pueden estructurarse,
definiéndolos fuera o dentro de las funciones. Los datos se definen en la forma de
variables, las cuales son visibles (accesibles) en ciertas partes del programa,
dependiendo del lugar en que fueron definidas. Para mayor detalle puede consultarse la
sección sobre declaración de variables.

/ .!

A pesar de que existen muchas maneras de estructurar un programa en C, presentamos


la estructura general de un programa, según las normas que seguiremos en todos los
ejemplos que se presentarán.

/ .!8 


§  ?ƒlibrerías>

§ ?ƒidentificador> ƒconstante>


???
? definición_de_nuevos_tipos_de_datos>
????
??? definición_de_funciones>

ƒtipo> @
 {

ƒcuerpo_de_la_función_principal>

½? La directiva para la consideración de librerías o bibliotecas de funciones


predefinidas es #include. En la sección de inclusión de bibliotecas se hace
referencia a aquellos grupos de funciones que se requieran para un correcto
funcionamiento del programa (es decir, aquellas que van a ser llamadas). Por
ejemplo, si deseamos incluir ï  para emplear las funciones de la biblioteca
de entrada y salida estándar, se escribiría:

§include ƒstdio.h>

ëe esta forma el compilador tendrá conocimiento de las funciones que contiene


la biblioteca.
Otras bibliotecas son:

§include ƒstdlib.h> /* funciones básicas */


§include ƒstdlib.h> /* funciones matemáticas
básicas */
§include ƒstring.h> /* funciones para manejar
cadenas */

½? La definición de constantes simbólicas se realiza con #define y consiste en


asignar a un identificador un valor que permanecerá constante durante su uso en
el programa. La definición de nuevos tipos de datos se estudiarán en
profundidad más adelante, por lo que no entraremos en su explicación por ahora.
½? En la <definición de funciones> se escribe la declaración e implementación de
las funciones propias (es decir, escritas por nosotros mismos), y que van a ser
empleadas a lo largo del programa.
½? La función
  es la función principal del programa. Al iniciar el programa
esta función se llamará en forma implícita, por lo que podría considerarse como
el cuerpo principal del programa. Más adelante en el curso se verá como
especificar al programa argumentos desde la línea de comandos del sistema
operativo, los cuales serán pasados como parámetros de entrada a la función

 .
½? El cuerpo de la función principal es un conjunto de instrucciones que
implementan la funcionalidad del programa (es decir, especifican lo que hará el
programa).




Programa de ejemplo, compuesto por dos funciones para conversión de temperaturas, y


una función principal
 , que hace algunos llamados a las funciones para crear una
pequeña tabla de equivalencia de temperaturas.

½? Equivalencia de temperaturas (ahrenheit-Celsius)

  $/  

  $ !  ! 0 !  !.


ëe esta forma, el usuario puede suministrar al programa sus datos de entrada, y puede
recibir de éste los resultados obtenidos.

Para llevar a cabo esta interacción es necesario contar con instrucciones destinadas para
tal efecto. Las bibliotecas del lenguaje de programación C incluyen un amplio conjunto
de instrucciones destinadas a llevar a cabo entrada y salida de datos. Quizá las de mayor
uso son las orientadas a la entrada y salida de datos u 
 (biblioteca ï ).

Para llevar a cabo salida con formato contamos con la instrucción  , la cual permite
desplegar en la pantalla del computador información de variados tipos, permitiéndonos
a la vez especificar la forma en que dichos datos deberán aparecer (formato).

Para obtener entradas con formato disponemos de la instrucción ïu , la cual permite


capturar desde el teclado del computador información de variados tipos, permitiéndonos
a la vez especificar la forma en que dichos datos deberán interpretarse durante la
lectura.
Tanto la instrucción  , como ïu  utilizan una serie de caracteres de conversión
para especificar el formato que deberá tener la información de salida y entrada,
respectivamente. ëe este modo será posible interpretarla correctamente.

/   
  

La función  , de la biblioteca de entrada y salida estándar (ï ) permite desplegar


datos en la pantalla, con la posibilidad de especificar el formato con que se desea que
aparezcan.

/ .!8 


  ( "cadena -de-formato", ƒlista_de_argumentos> ) ;

La cadena de formato debe ir delimitada por comillas dobles, y debe incluir una
especificación de conversión por cada argumento en la lista de argumentos. El texto que
se incluya en la cadena de formato aparecerá durante el despliegue, y cada
especificación de conversión será reemplazada por el correspondiente argumento.

La lista de argumentos consiste de una secuencia de expresiones que se desean


desplegar. Las expresiones pueden ser variables, constantes u operaciones que deben
resolverse antes del despliegue. También es posible especificar llamados a funciones
que devuelvan algún valor.

!  !c(!

Las especificaciones de conversión definen la forma en que serán tratados y


desplegados los argumentos de  . Cada especificación de conversión empieza con
el caracter especial % y termina con alguno de los caracteres de conversión que se
detallan más adelante. Además, entre el símbolo % y el caracter de conversión pueden
incluirse:

½? Œn signo menos, que indica que el campo debe ajustarse a la izquierda


½? Œn número entero, que indica el tamaño mínimo que deberá ocupar el campo al
desplegarse
½? Œn punto seguido de un número entero, que indica las posiciones decimales que
deberán desplegarse. ëe ser necesario se agregarán ceros al final.

Los caracteres de conversión indican a   la forma en que deberá interpretar el


argumento. Se mencionan a continuación aquellos de mayor uso:

½? d - Número entero en notación decimal (base 10)


½? c - Caracter
½? s - Cadena de caracteres (ï  )
½? e - Número con decimales, expresado en notación exponencial o de punto
flotante (mantisa y exponente)
½? f - Número con decimales, expresado en notación de punto fijo (parte entera,
punto, parte decimal)
ëentro de la expresión de conversión pueden especificarse las siguientes secuencias que
tienen un significado especial:

½? %% - Para imprimir un símbolo de %


½? \n - Para provocar que el cursor cambie de línea
½? \t - Para producir una tabulación en el despliegue
½? \ASCII - ëespliega el caracter con el código ASCII suministrado

Para una referencia más amplia debe consultarse el libro  

 
!   de Kernighan y Ritchie.

!


½? printf("El valor de la variable x es: %d\n", x);


o? ëesplegará: (  (  ".!
 (si x contenía un valor
igual a 100), y avanzará a la siguiente línea luego del despliegue

printf("El valor de dos + cinco es: %d\n", 2+5);

o? ëesplegará: ( !9!


: y avanzará a la siguiente línea
luego del despliegue

printf("El area de un circulo con radio %.2f es %.2f\n", radio, area);

o? ëesplegará:    !; (suponiendo


los valores indicados para las variables) y avanzará a la siguiente línea
luego del despliegue

printf("Este es el numero 2 con formato %%5d: %5d", 2);

o? ëesplegará: !!   <=


&&&& (en donde _
representa un espacio en blanco)

printf("Este es el numero 2 con formatos %%-5d y %%d: %-5d %d", 2, 2);

o? ëesplegará: !!   !<>=$<


 &&&&&
(en donde _ representa un espacio en blanco)

printf("Este es el caracter %c cuyo codigo ASCII es %d", 'A', 'A');

o? ëesplegará: !!  4$4/c!?=


+(!! !c(!
Ejemplo de impresión en pantalla (  ). Imprime un valor de tipo  utilizando
varios formatos dentro de  .

½? *er el código fuente


½? Ejemplo de ejecución

   
 u 

La función ïu , de la biblioteca de entrada y salida estándar (ï ) permite capturar


datos desde el teclado, con la posibilidad de especificar el formato para interpretarlos.

/ .!8 


ï
 ( "cadena_de_control", ƒlista_de_argumentos> ) ;

La cadena de control, al igual que en el caso de la cadena de formato de  , debe ir


delimitada por comillas dobles, y debe incluir una especificación de conversión por
cada argumento en la lista. Estas especificaciones se utilizarán para dirigir la
interpretación de las secuencias de entrada.

La lista de argumentos consiste de una secuencia de punteros a variables, en las cuales


se almacenarán las entradas dadas por el usuario, una vez interpretadas por ïu . La
cadena de control puede contener:

½? Espacios en blanco, tabuladores o finales de línea, los cuales no se tomarán en


cuenta.

½? Caracteres ordinarios (distintos de %), los cuales se espera que coincidan con el
próximo caracter %, distinto de blanco del flujo de entrada.

½? Especificaciones de conversión, formadas por el caracter %, un número opcional


que indica el tamaño máximo del campo, y el caracter de conversión, de manera
similar a como se definió para el caso de  .

Cada especificación de conversión dirige la conversión del próximo campo de la


entrada. El resultado se almacena en la variable apuntada por el argumento (por el
puntero). Œn campo de entrada se define como una cadena de caracteres delimitada por
espacios en blanco (incluyendo tabulador y fin de línea). El campo concluye en el
primer blanco, o cuando se alcance el máximo señalado en la especificación de
conversión.

Los caracteres de conversión pueden ser:

½? d - indica que se espera un número decimal (el argumento debe ser un puntero a
 ).
½? h - similar al anterior, pero el argumento debe ser puntero a ï  .
½? lx - similar a los anteriores, pero el argumento debe ser puntero a   .
½? c - indica que se espera un caracter (el argumento debe ser un puntero a u ).
Para leer el primer caracter distinto de blanco debe emplearse %1s.
½? s - indica que se espera una cadena de caracteres (el argumento debe ser un
puntero a caracter, o el nombre de un vector de caracteres).
½? f - indica que se espera un número con decimales (el argumento debe ser un
puntero a  ). La entrada puede darse en notación de punto fijo (parte entera,
punto, decimales), o de punto flotante (mantisa, E, exponente).
½? lf - similar al anterior, pero el argumento debe ser puntero a  .

!


½? scanf("%d", &edad);
o? Espera un entero que será almacenado en la variable edad.

scanf("%4d", &agno);

o? Espera el año actual (4 dígitos). El valor ingresado se guardará en la


variable agno. Si se ingresan más de 4 dígitos, los restantes se
descartarán, o se dejarán para la siguiente llamada a ïu .

scanf("%d %f", &edad, &salario);

o? Se esperan dos números: El primero debe ser entero y el segundo puede


tener decimales. Los valores se guardarán en las variables edad y salario,
respectivamente. El usuario puede separar los valores durante la entrada
con espacios en blanco, tabuladores o caracteres de fin de línea (es decir,
presionando las teclas ƒ  ó ƒ  ).

scanf("%s", nombre);

o? Se espera una cadena de caracteres (ï  ). La entrada se almacenará en


el vector nombre, y se delimitará con un ASCII(0) al final. Obsérvese
que el argumento no incluye el símbolo &, pues los nombres de vectores
son en sí punteros. ëebe tenerse cuidado de que el vector puede
almacenar la totalidad de la entrada, o pueden producirse errores de
ejecución muy serios. Œna manera de controlar esto es incluir un tamaño
máximo dentro de la expresión de formato.

 @0!!

Ejemplo de entrada desde el teclado (  ). Lee el valor de tres variables de tipo  . Al


ingresarlas, el usuario las podrá delimitar empleando espacios en blanco, tabulaciones, o
incluso ingresándolas en diferentes líneas.

½? *er el código fuente


½? Ejemplo de ejecución

c !* $5!4!!*! !

c !

Con el objetivo de hacer los programas más legibles, es importante la incorporación de


comentarios que ayuden a comprender lo que hizo el programador. ! 
    # !##  
! ! !!A2/c@+6/

Con este fin, el lenguaje ofrece la posibilidad de incluir dentro del programa cualquier
texto que pretenda comentar el código escrito. Este texto puede abarcar una o varias
líneas, y debe incluirse dentro de los delimitadores mostrados a continuación.

/ .!8 


› Comentario - No debe incluir la combinacion de caracteres


slash-asterisco, pues se emplea para terminar el comentario
›

!

/* Programa para calcular ...
Escrito por ...
*/
int radio; /* Guarda el radio del circulo */
/* Funcion que calcula el area de un circulo */
float area(float radio) { ...

 $! !!(! !

A pesar de que el lenguaje de programación C ofrece una amplia libertad en cuanto a la


forma en que pueden escribirse los programas, !! ! "  !
 !# $  !  !,!"!, y por lo tanto más fáciles de
comprender y modificar. Aunque no es posible ofrecer una lista exhaustiva de todas las
decisiones de formato que un programador debe enfrentar al escribir sus programas,
intentaremos establecer algunas pautas, y el resto lo dejaremos para ser percibido a lo
largo del curso al estudiar los ejemplos.

Ahora bien, las normas aquí mostradas ! "! !, y reflejan únicamente las
preferencias del autor. Existen muchas otras, quizá hasta mejores. Lo importante aquí es
adoptar un estándar y respetarlo al máximo posible. ëe esta forma escribiremos
programas correctos, no sólo en cuanto a su funcionalidad, sino también en cuanto a su
apariencia.

4!!!


½? ¿ëónde poner los corchetes?


½? funcion (argumentos) {
½? ...
}

½? ¿Cómo indentar el código?

Los programas normalmente tienen una estructura jerárquica (por niveles), y es


importante destacarla al escribirlos. Esto se logra mediante indentación, es decir,
dejando algunos espacios entre el código que esta en un nivel y el del siguiente
nivel. Pero ¿cuándo indentar?. Lo más sencillo es mirar los ejemplos. Œna regla
sencilla es que   (3#! "  ! se estará creando un nuevo
nivel y por lo tanto es necesario indentar. Por ejemplo:

int main (...) {


...
while (...) {
...
for (...) {
...
}
...
}
...
}

½? Para ponerle nombre a las cosas

Trate siempre de que el nombre ayude a comprender la función del objeto que
está identificando. Por ejemplo, una variable que almacena la edad de un
empleado podría llamarse  , o mejor aún  
 , y no simplemente
. Las funciones deben tener nombres activos, como  u  ï , y no
simplemente  ï , o peor aún un nombre sin sentido. Cuanto más
significativos sean los nombres, menor será la cantidad de comentarios que
deberá incluir.

½? ¿Cuándo poner comentarios?


Es importante     #!. 
#      , cuáles son sus entradas y cuáles
sus salidas, así como las restricciones que tiene, si es que existen. Toda función
deberá tener un comentario similar. Además, aquellas variables cuyo nombre no
sea lo suficientemente explícito, deberán tener un comentario sobre su objetivo
en la declaración. Por ejemplo:

/* Programa para ...


El programa lee del usuario ...
... y le devuelve como respuesta ...
Restricciones: No es posible ...
*/

int x; /* Almacena el valor para ... */

int EdadEmpleado; /* Obvio: No hace falta comentario


*/

/* Funcion para .... */


...

/* Funcion para .... */


...

/* Funcion princip al: Hace lo siguiente ... */


main() {

/* Dentro del codigo tambien puede haber


comentarios,
para explicar aspectos que pueden ser dificiles
de
comprender */



½? Simulando la preparación de un 

Potrebbero piacerti anche