Está en la página 1de 9

Algunos tópicos en el Lenguaje C

Cuando se evalúa una expresión aritmética que contiene diferentes tipos de datos, el compilador
convierte todos ellos a un tipo único. Estas conversiones pueden aumentar o disminuir la precisión del
tipo al que se convierten los elementos de la expresión. La conversión se hace operación a operación
y se lleva a cabo según el tipo que esté más a la derecha de la siguiente relación:
char  int  unsigned int  long  unsigned long float  double  long double
EJEMPLO:
char c;
int i;
long l;
float f;
double d;
x = ( i * c % l) - ( d / f ) + f;
Tomando en cuenta el orden de prioridad, primero evaluamos el contenido de los paréntesis, por lo
tanto en los primeros paréntesis evaluamos los tipos de izquierda a derecha:
i * c es un int, ya que el tipo int está a la derecha del tipo char en nuestra relación.
i % l es un long, el tipo long está a la derecha del tipo int en nuestra relación.
d / f es un double, ya que el tipo double está a la derecha del tipo float.
Evaluamos de nuevo de izquierda a derecha y queda de la siguiente forma:
x=( i * c % l ) - ( d / f ) + f ;
( int * char ) - ( double / float ) + float
int % long - double + float
long - double + float
double + float
double

long - double + float = double + float = double


Cuando en una expresión en C++ intervienen operandos de distinto tipo, los datos se convierten de
forma temporal al operando de mayor precisión para realizar la operación.
Cuando a un variable se le asigna un valor que no es de su tipo, C++ convierte el valor de la derecha
al tipo de la variable a la que se le va a asignar siempre que no haya pérdida de información.
Si se produce pérdida de información el compilador avisará de ello.
En una asignación de tipos distintos puede ocurrir que:
1. Un valor real (tipo double o float) puede truncarse (pierde la parte decimal) si se asigna a una variable
entera.
2. Un valor de tipo double puede ser redondeado si se asigna a una variable de tipo float.
3. Un valor de tipo entero puede ser modificado si se asigna a una variable entera de menor precisión
o a una variable de tipo char. Algunos de los bits más significativos pueden perderse.
Por ejemplo, dadas las siguientes declaraciones de variables:
long int k;
unsigned char m;
double p;
int n, q;
Para calcular la siguiente expresión: q = k + m * n / p el proceso es el siguiente:
1. Se realiza la multiplicación m * n. Para ello se convierte m (unsigned char) a int y a continuación se
multiplica por n. El resultado es de tipo int.
2. Se realiza la división. Como p es de tipo double, el resultado anterior de multiplicar m * n que es de
tipo int se convierte a double y se hace la división. El resultado es de tipo double.
3. Se realiza la suma. Para ello se convierte k (long) a double y se suma al resultado de la división
anterior. El resultado de la suma es de tipo double.
4. El último paso es asignar el resultado de tipo double a q que es de tipo int. En este caso el resultado
se pasa a tipo int por truncamiento, o sea, eliminando la parte fraccionaria. En este caso de pérdida
de precisión el compilador avisará de ello.
Estas conversiones las realiza C++ de forma automática. Esta conversión se conoce
como conversión implícita.
En algunos casos necesitaremos asignar datos de un tipo a variables que son de otro tipo y que el
compilador no nos avise ello y permita realizar la operación. En ese caso utilizaremos la conversión
explícita o casting.
En general, el uso del casting es obligatorio cuando se hacen asignaciones con pérdida de precisión.
Un casting lo podemos hacer, siguiendo el modelo de C, de dos formas: (tipo) expresión ó
tipo(expresión)
Por ejemplo:
float a = 10.2;
int b, c = 5;
b = (int)(a + c); // convierte a int por truncamiento. Asigna a b el valor 15
c = int (a); // asigna a c el valor 10
Si en las instrucciones anteriores no realizamos el casting el compilador avisará de la pérdida de
precisión y no nos dejará hacerlo.
Otro ejemplo. Dadas las variables:
int i = 7;
float f = 8.5;
La expresión (i + f) % 4 no es válida, ya que (i + f) produce un resultado en coma flotante.
Esto se puede solucionar con un casting:
((int) (i + f)) % 4.
Sea ahora la expresión ((int) f) % 3, es una expresión válida, que da como resultado el valor 2, pero
debemos tener en cuenta que lo que se convierte en entero es el valor de f, y sólo para esta expresión,
ya que después f sigue teniendo el valor 8.5.
Un casting también puede ser considerado como un operador unitario.
Además de esta forma de realizar un casting que es la tradicional de C, C++ incorpora 4 nuevos
operadores para realizar un casting de forma explícita:
static_cast<tipo>(expresión)
Convierte el tipo de la expresión al tipo indicado.
Se utiliza para realizar conversiones entre tipos relacionados, por ejemplo entre un float y un int.
const_cast<tipo>(expresión)
Convierte el tipo de la expresión al tipo indicado.
Se utiliza para eliminar la acción del calificador const sobre la expresión.
dynamic_cast<tipo>(expresión)
Convierte el tipo de la expresión al tipo indicado.
Se utiliza para realizar conversiones verificadas durante la ejecución, examinando el tipo del objeto
que convierte.
Si la conversión es entre punteros y durante la ejecución no se puede realizar, devuelve un cero
(puntero nulo).
reinterpret_cast<tipo>(expresión)
Convierte el tipo de la expresión al tipo indicado.
Se utiliza para realizar conversiones entre tipos no relacionados, por ejemplo, conversiones double *
a int * que static_cast no permite.
Por ejemplo:
float a = 10.2F;
int b, c = 5;
b = static_cast<int>(a + c); // Asigna a b el valor 15
c = static_cast<int>(a); // asigna a c el valor 10

ENTRADA Y SALIDA DEL LENGUAJE C


Se refiere a las operaciones que se producen en el teclado y en la pantalla de la computadora. En C
no hay palabras claves para realizar las acciones de Entrada/Salida, estas se hacen mediante el uso
de las funciones de la biblioteca estándar (stdio.h).
Para utilizar las funciones de E / S debemos incluir en el programa el archivo de cabecera, ejemplo:
stdio.h, mediante la declaratoria:
#include <stdio.h>
Las Funciones de E/S más simples son getchar() que lee un carácter del teclado, espera un retorno,
es decir un enter y el eco aparece. Es decir la tecla presionada.
putchar(): Imprime un carácter en la pantalla, en la posición actual del cursor.
Algunas variaciones:
getche(): Aparece el Eco
getch(): No aparece el eco
Estas instrucciones se encuentran en la biblioteca conio.h

Salida de datos con formato: la función printf()


La función printf() (de “print” = imprimir y “f” = formato) sirve para escribir datos en el dispositivo de
salida estándar (generalmente la pantalla) con un formato determinado por el programador. La forma
general de utilizarla es la siguiente: printf(cadena_de_formato, datos);
El prototipo de printf() se encuentra en el archivo de cabecera stdio.h (de “std” = standard e “io” =
input/output, es decir, entrada/salida; por lo tanto, “stdio” es un acrónimo de “entrada/salida estándar”)
El primer argumento, la cadena_de_formato, especifica el modo en el que se deben mostrar los datos
que aparecen a continuación. Esta cadena se compone de una serie de códigos de formato que indican
a C qué tipo de datos son los que se desean imprimir. Todos los códigos están precedidos del símbolo
de porcentaje (“%”). Por ejemplo, el código “%i” indica a la función que se desea escribir un número
de tipo int, y el código “%f”, que se desea escribir un número real de tipo float.
Los códigos de formato que se pueden utilizar en printf() son:
Código Formato
%d Un entero
%i Un entero
%c Una carácter
%s Una cadena
%f Un real
%ld Entero largo
%u Decimal sin signo
%lf Doble posición
%h Entero corto
%o Octal
%x Hexadecimal
%e Notación Científica
%p Puntero
%% Imprime Porcentaje
Entrada de datos con formato: la función scanf()
La función scanf() es, en muchos sentidos, la inversa de printf(). Puede leer desde el dispositivo de
entrada estándar (normalmente el teclado) datos de cualquier tipo de los manejados por el compilador,
convirtiéndolos al formato interno apropiado.
Funciona de manera análoga a printf(), por lo que su sintaxis es:
scanf(cadena_de_formato, datos);
El prototipo de scanf() se encuentra en el archivo de cabecera stdio.h (de “std” = standard e “io” =
input/output, es decir, entrada/salida)
La cadena_de_formato tiene la misma composición que la de printf(). Los datos son las variables
donde se desea almacenar el dato o datos leídos desde el teclado. ¡Cuidado!
Con los tipos simples, es necesario utilizar el operador & delante del nombre de la variable, porque
esa variable se pasa por referencia a scanf() para que ésta pueda modificarla.
FUNCIONES DE ENTRADA Y SALIDA (puts y gets)
Función gets
Lee una cadena de carácter introducido por el teclado. Se puede introducir caracteres hasta que se dé
un retorno de carro, (enter); el cual no es parte de la cadena; en su lugar se coloca un terminador
nulo\0.
Sintaxis:
char *gets(char *s);
Lee una cadena desde stdin.
gets lee una cadena de caracteres terminada con un retorno de línea desde la entrada estándar y la
almacena en s. El carácter de retorno de línea es reemplazado con el carácter nulo en s.
Observa que la manera en que hacemos referencia a una cadena dentro de la función es char *, el
operador * indica que debemos pasar como argumento la dirección de memoria donde estará
almacenada la cadena a leer. Baste decir que a nivel del compilador char *cad y char cad[], son
equivalentes, o casi. gets permite la entrada de caracteres que indican huecos, como los espacios y
los tabuladores. gets deja de leer después de haber leído un carácter de retorno de línea; todo aquello
leído será copiado en s, incluido en carácter de retorno de línea.
Esta función no comprueba la longitud de la cadena leída. Si la cadena de entrada no es lo
suficientemente larga, los datos pueden ser sobrescritos o corrompidos. Más adelante veremos que la
función fgets proporciona mayor control sobre las cadenas de entrada.
Función puts
Imprime en pantalla, el argumento guardado en la variable que se manda a impresión.
Sintaxis:
int puts(const char *s);
Envía una cadena a stdout.
puts envía la cadena s terminada con nulo a la salida estándar stdout y le añade el carácter de retorno
de línea.
Valor de retorno:
Si tiene éxito, puts devuelve un valor mayor o igual a cero. En caso contrario devolverá el valor EOF.

FUNCIONES DE CONTROL DE SOFTWARE


Sentencias de control
La estructura if
La estructura if adopta una de las dos formas siguientes:
if (expresión) sentencia;
O bien
if (expresión) sentencia;
else sentencia;
En donde expresión es una sentencia que se evalúa como verdadera (devuelve un valor no nulo) o
falsa (devuelve cero). La palabra sentencia puede ser una sentencia simple terminada con un punto y
coma, o un grupo de sentencias encerradas entre llaves {}.
La estructura switch
La estructura switch inspecciona una variable y la va comparando con una lista de constantes.
Cuando encuentra una coincidencia, se ejecuta la sentencia o grupo de sentencias asociado. La forma
de switch es
switch (variable) {
case cte1: sentencia;
break;
case cte2: sentencia;
break;
...
...
default: sentencia;
}
Donde variable es una variable o cualquier expresión que devuelva un valor. La
sentencia switch compara la variable con cte1, cte2,..., y si encuentra una coincidencia, ejecuta la
sentencia correspondiente. Por sentencia debemos entender tanto una sentencia simple como un
grupo de sentencias (que, en este caso, no se encierran entre llaves). Si no se encuentra ninguna
coincidencia se ejecuta la sección default (que no es obligatoria).

switch (n) {
case > 0: puts ("Positivo");
break;
case < 0: puts ("Negativo");
break;
default: puts ("Cero");
}
La sentencia break es opcional. Cuando se encuentra, provoca la salida de switch. En caso contrario
continuo la siguiente secuencia case o default aunque no se cumpla la condición.
Bucles
Existen en C tres tipos de bucles: for, while y do/while.
Bucles for
El bucle for es muy potente y flexible. Además de permitir las mismas operaciones que
cualquier for de otros lenguajes, tiene características que lo diferencian claramente de ellos. En su
formato tradicional este bucle tiene la forma
for (inicialización; condición; incremento) cuerpo_del_bucle;
Vemos que for tiene tres secciones: inicialización, en dónde se da un valor inicial a una variable de
control del bucle; condición, que es una expresión que devuelve un valor verdadero o falso, y hace
que el bucle se repita mientras sea cierta; e incremento, en dónde se determina la cuantía del
incremento o decremento de la variable de control. Las tres secciones están separadas por punto y
coma. El cuerpo del bucle puede estar formado por una o por varias sentencias. En este último caso
deben encerrarse entre llaves {}. El flujo de sentencias en este bucle es el siguiente:
inicialización
FALSA
condición
VERDADERA
cuerpo_del_bucle
incremento
Fijémonos que el for se sigue ejecutando MIENTRAS la condición sea verdadera.
El bucle while
Tiene la forma
while (expresión) cuerpo_del_bucle;
Siendo expresión cualquier expresión C válida. El cuerpo_del_bucle, puede estar formado por una
sentencia sencilla o por un bloque de sentencias, en cuyo caso, se encierran entre llaves {}. El flujo de
sentencias es
FALSA
Expresión
VERDADERA
cuerpo_del_bucle
Por lo tanto, en el bucle while el cuerpo_del_bucle se repite mientras expresión se evalúe como cierta.
Respecto del bucle while es conveniente tener presente lo siguiente:
 El cuerpo del bucle no se ejecutará NUNCA si la primera vez no se cumple la condición.
 El bucle puede ser INFINITO si no se modifican adecuadamente las variables de la condición
dentro del bucle.
El bucle do/while
Tiene la forma
do
cuerpo_del_bucle;
while (expresión);
Siendo sentencia una sentencia simple o un grupo de sentencias encerradas entre llaves {},
y expresión cualquier expresión válida C. El flujo de ejecución es el siguiente:
cuerpo_del_bucle
VERDADERA
Expresión
FALSA
Por lo tanto, en un bucle do/while el cuerpo_del_bucle se ejecuta al menos una vez, incluso
aunque expresión se evalúe como falsa, puesto que la evaluación se hace al final, justo lo contrario
del bucle while, en el que la evaluación de expresión se hace al principio.
Sentencia break
Es la misma sentencia que hemos visto para finalizar los case de la sentencia switch. Pero además
permite forzar la salida inmediata de un bucle (for, while o do/while) en cualquier momento, ignorando
el resto de sentencias.
Sentencia continue
Esta sentencia se utiliza en los bucles for, while y do/while. Cuando se ejecuta fuerza un nuevo ciclo
del bucle, saltándose cualquier sentencia posterior.
Etiquetas y sentencia goto
En C existe la sentencia de salto incondicional goto que fuerza un salto del programa a una línea
identificada por una etiqueta. La etiqueta se define con un identificador válido C, seguido por dos
puntos (:).
goto etiqueta;
...
...
etiqueta: sentencia;
...
...
La etiqueta puede estar antes o después del goto, pero siempre en la misma función.
Realmente, en lenguajes con suficientes estructuras de control (como C) no suelen presentarse
situaciones que hagan necesaria la sentencia goto. Sin embargo, en alguna ocasión puede ser
conveniente, bien porque la velocidad de proceso es importante (un salto con goto es más rápido que
otro tipo de controles de bifurcación), o bien porque su uso clarifica el código. El caso más habitual es
la salida de varios niveles de anidamiento.
for (...) {
while (...) {
for (...) {
...
...
if (...) goto salir;
...
...
}
}
}
salir: ...
...
En este ejemplo, la única alternativa a goto sería la realización de varias comprobaciones en cada
bucle que forzase sentencias break, lo cual haría más ilegible el código.
Función exit()
Esta función permite la finalización del programa en cualquier punto del mismo. Devuelve el control al
sistema operativo o a otro proceso padre, enviando un valor de retorno. Necesita la inclusión del
archivo de cabecera process.h, por medio de una sentencia #include.
Si en un programa escribimos
if (condición) exit (0);
Se produce el final del programa cuando condición es cierta, en cuyo caso se devuelve el valor 0 al
proceso padre.

CREACIÓN DE BIBLIOTECAS
Manual para para crear tu propia biblioteca en C/C++
El siguiente manual va a tratar sobre cómo crear tu propia biblioteca en un compilador de
C/C++. La biblioteca, o también mal conocida como librería (del inglés library) nos permite el uso de
funciones en un programa sin la necesidad de escribir su código en nuestro
programa, únicamente llamando a la biblioteca donde está contenida. Existen
bibliotecas estándares en C que ya vienen incluida en la mayoría de los compiladores, como
son stdio.h, math.h, time.h...
Para utilizar nuestra biblioteca, únicamente basta con situar en la cabecera del programa el nombre
de la biblioteca para poder utilizar todas las funciones contenidas en la misma.

A continuación se detallan los paso para la construcción de una biblioteca o librería:

MANUAL CREACIÓN BIBLIOTECA:


1º) Genera las funciones que te interesan y escríbelas todas juntas (código y cabeceras) en
un mismo archivo de texto (Puedes usar el editor de texto del compilador, el bloc de notas, igual
da...) tal y como se ilustra a continuación con un sencillo ejemplo:

int multiplica(int A, int B);


int suma(int A, int B);
int resta(int A, int B);

int multiplica(int A, int B)


{
return(A*B);
}
int suma(int A, int B)
{
return(A+B);
}
int resta(int A, int B)
{
return(A-B);
}

2º) El fichero creado anteriormente, guardalo con extension .h, por ejemplo
milibreria.h (importante no ejecutarlo para que no le pueda cambiar sola la extensión). Se deberá
guardar en la carpeta include del compilador. Esta carpeta se puede encontrar fácilmente en la
misma carpeta del compilador., accediendo a Mi PC (Equipo) y en la carpeta donde se guardan
todos los programas.
Otra opción es que si solo se desea usar mibiblioteca.h una única vez, se puede guardar el fichero
en la misma carpeta del código que queramos compilar. Dependiendo de este último paso
tendremos...

3º) Llamar a la biblioteca en el programa. Deberemos colocar en la cabecera del programa, junto
a los llamamientos de otras bibliotecas:

#include <milibreria.h> Cuando el fichero milibreria.h se encuentre en la carpeta include de nuestro


compilador.

#include "milibreria.h" Cuando el fichero milibreria.h esté en el mismo directorio que el archivo que
queremos compilar.

4º)Uso de las funciones de la biblioteca: Finalmente ya podemos usar las funciones


de milibreria.h sin necesidad de copiar el código, tal y como ilustra el programa siguiente:

#include <stdio.h>
#include <milibreria.h>

int main(void)
{
int X,Y;
scanf("%d %d",&X,&Y);
printf("X*Y=%d \n",multiplica(X,Y));
printf("X+Y=%d \n",suma(X,Y));
printf("X-Y=%d \n",resta(X,Y));
}

Y en el caso de que libreria.h este en la misma carpeta:

#include <stdio.h>
#include "milibreria.h"

int main(void)
{
int X,Y;
scanf("%d %d",&X,&Y);
printf("X*Y=%d \n",multiplica(X,Y));
printf("X+Y=%d \n",suma(X,Y));
printf("X-Y=%d \n",resta(X,Y));
}

También podría gustarte