Versión 3.0

800x600 mínimo
En esta lección:

Asignando enteros
-----
Mezclando tipos de datos
-----
Mas variables
-----
Caracteres de conversión
-----
Comparaciones lógicas
-----
Construcciones útiles
-----


Otras secciones:

Conceptos básicos
-----
Programando en C
-----
Programando en C++
-----
Programando Windows 9x.
-----
Teoría electrónica
-----
Circuitos electrónicos
-----
Actividades adicionales
-----
Hipervínculos
-----


Contácteme:

Dudas y comentarios
-----


Hola mundo

A lo largo de este capítulo nos referiremos al rango de una variable, esto significa los límites de valores que pueden ser almacenadas en una variable dada. Su compilador puede usar rangos diferentes para algunas variables debido a que el estándar ANSI no define límites específicos para todos los tipos de datos. Consulte la documentación de su compilador para saber el rango exacto para cada tipo de variable.

ASIGNANDO ENTEROS.

En el primer programa de este capítulo veremos ejemplos de enunciados de asignación. Tres variables están definidas para usarse en este programa y el resto del código consiste en una serie de ilustraciones de varios tipos de asignación. Las tres variables están definidas en una sola línea e inicialmente almacenan valores desconocidos. Las primeras dos líneas de asignación, líneas 6 y 7, asignan valores numéricos a las variables llamadas a y b, las cinco líneas siguientes ilustran las cinco funciones aritméticas básicas y cómo usarlas. La quinta función se llama operador modulo y devuelve el resto cuando las dos variables son divididas, solo se puede aplicar a variables de tipo entero mismas que definiremos mas adelante. Las siguientes dos líneas demuestran cómo combinar algunas variables en expresiones matemáticas relativamente complejas. Todos estos ejemplos tienen un uso meramente ilustrativo.


/* Este programa ilustra diversos enunciados de asignación */
int main()
{
    int a, b, c; /* Variables de tipo entero para los ejemplos */
 
    a = 12;
    b = 3;
    c = a + b; /* suma simple */
    c = a - b; /* substracción ó resta */
    c = a * b; /* multiplicación */
    c = a / b; /* división */
    c = a % b; /* modulo (resto) */
    c = 12*a + b/2 - a*b*2/(a*c + b*2);
    c = c/4+13*(a + b)/3 - a*b + 2*a*a;
    a = a + 1; /* incremento de variable */
    b = b * 5;
    a = b = c = 20; /* asignación múltiple */
    a = b = c = a + b * c/ 3;
    a = (b = (c = 20)); /* Igual a la línea 18 */
 
    return 0 ;
}
 
/* Resultado de la ejecución:
(Este programa no tiene salida.)
*/

La procedencia de los operadores es un tópico muy importante que Usted necesita estudiar en detalle en algún momento, por lo pronto necesitamos unas cuantas reglas. Cuando se tienen expresiones aritméticas combinadas, los operadores de multiplicación y división se completan antes que los operadores de suma y resta estando en el mismo nivel lógico, así cuando evaluamos a*b+c/d, la multiplicación y la división se ejecutan primero y después la suma. Sin embargo, en la expresión a*(b+c/d), la suma sigue de la división y posteriormente la multiplicación porque las operaciones están en niveles lógicos diferentes como lo define el uso del paréntesis. Los enunciados en las líneas 15 y 16 son perfectamente aceptables como están, pero como veremos mas adelante en este capítulo, hay otra forma de escribir estas sentencias con un código mas compacto.

En las líneas 17 y 18 se dan ejemplos de asignación múltiple. El compilador C rastrea el enunciado de asignación de derecha a izquierda, resultando un constructor muy útil. El compilador encuentra el valor 20, lo asigna a c, entonces continúa a la izquierda encontrando que el resultado del último cálculo debe asignarse a b. Como este resultado fue 20 asigna a su vez éste valor a b y continúa rastreando a la izquierda asignando el valor de 20 a la variable a. Este es un constructor muy útil cuando Usted inicializa un grupo de variables. La línea 18 ilustra que es posible efectuar algunos cálculos antes de asignar el resultado a un grupo de variables. Los valores de a, b y c, antes del principio de la línea 18 son utilizados para el cálculo, el resultado se asigna posteriormente a cada una de las tres variables.

PRIMERO DEFINIR, DESPUÉS EJECUTAR.

Aquí es un buen momento para definir una regla a seguir en C. La definición de variables se dá siempre antes que cualquier enunciado ejecutable en un bloque de programa, si Usted trata de definir una variable después de algunos enunciados ejecutables su compilador marcará un error. Un bloque de programa es uno o mas enunciados encerrados por llaves. El bloque puede incluso estar vacío como se dá en el caso de las etapas tempranas del desarrollo de un programa.

TIPOS DE DATOS ADICIONALES.

En estos momentos debe estar ya familiarizado con el tipo de dato entero (int), en el siguiente ejemplo le presentamos dos tipos nuevos, char y float.
El tipo de dato char es casi igual al entero excepto que solo se le pueden asignar valores entre -128 y 127 en la mayoría de las implementaciones de C para microcomputadoras debido a que generalmente es almacenado en un byte de memoria. Algunas implementaciones de C utilizan un elemento de memoria mayor para char dandole así un mayor rango de valores útilies. El tipo char se usa generalmente para datos ASCII, comunmente conocido como texto. El texto que Usted está leyendo fue escrito en una computadora con un procesador de texto que almacena las palabras en la computadora un caracter por byte. En contraste, el tipo de dato int se almacena en las modernas computadoras de 32 bits en cuatro bytes por dato de tipo int. Tenga en mente que aunque el tipo de dato char fue diseñado para almacenar representaciones de caracteres ASCII, puede ser utilizado a su vez para almacenar datos de valor pequeño, veremos mas de este tema cuando estudiemos cadenas en un capítulo posterior.


/* Tipos de datos nuevos */
int main()
{
    int a, b, c; /* Entero, de -32768 a 32767 sin punto decimal */
    char x, y, z; /* De -128 a 127 sin punto decimal */
    float numero, gato, casa; /* De 3.4E-38 a 3.4E+38 con punto decimal */
 
    a = b = c = -27;
    x = y = z = 'A';
    numero = gato = casa = 3.6792;
    a = y; /* a es ahora 65 (caracter A) */
    x = b; /* x es ahora -27 */
    numero = b; /* num será -27.00 */
    a = gato; /* a tomará el valor de 3 */
    return 0;
}
/* Resultado de la ejecución:
(Este programa no tiene salida.)
*/

Volver al principio

Hola mundo

MEZCLANDO TIPOS DE DATOS.

Es conveniente discutir la manera en que C maneja los tipos de datos int y char. La mayoría de las operaciones en C que están diseñadas para trabajar con variables de tipo entero trabajarán igualmente bien con variables de tipo caracter porque estas son variables enteras, es decir, no tienen parte fraccionaria, por esta razón es posible combinar tipos de datos int y char en casi cualquier forma que Usted desee, el compilador no se confundirá pero es posible que Usted sí por lo que es recomendable utilizar el tipo de dato adecuado para la variable en cuestión.

El otro tipo de dato nuevo es float, comunmente llamado dato de punto flotante el cual generalmente tiene un rango muy grande, un relativo número grande de dígitos significativos y un número mayor de palabras lógicas son requeridas para almacenarlo. El tipo de dato float tiene un punto decimal asociado por lo que se requieren varios bytes de memoria para almacenar una sola variable de tipo float.

Las primeras tres líneas del programa asignan valores a las nueve variables definidas por lo que podemos manipular algunos de los datos entre los diferentes tipos de variables. Como ya mencionamos, el tipo de dato char es en realidad un tipo de dato entero el cual es promovido a tipo int cuando es necesario sin requerir especiales consideraciones, de la misma manera un campo de datos de tipo char puede ser asignado a una variable int, lo contrario es también posible siempre y cuando el valor de la variable esté dentro del rango del tipo char, posiblemente de -128 a 127. Si el valor cae fuera de este rango, la mayoría de los compiladores C simplemente truncan los bits mas significativos y usan los bits menos significativos.

La línea 13 ilustra la facilidad de convertir un tipo int en float, sencillamente se asigna el nuevo valor y el sistema hace la conversión adecuada, sin embargo, al convertir de float en int existe una complicación dada la posibilidad de la presencia de una parte fraccionaria en un número de punto flotante, el sistema debe decidir que hacer con esta parte, por definición se truncará la parte fraccionaria.

 

Algunas constantes útiles están disponibles para su uso al determinar límites de rango en los tipos estándard, por ejemplo, los nombres INT_MIN e INT_MAX están disponibles en el archivo "limits.h" como constantes los cuales pueden ser utilizados en su código. INT_MAX es el número mas grande posible que su compilador puede utilizar para una variable de tipo int. El archivo "limits.h" contiene un gran número de límites que Usted puede utilizar simplemente incluyendo este archivo en su programa. Se recomienda ampliamente estudiar el archivo limits.h.

Volver al principio

Hola mundo

MAS TIPOS DE VARIABLES.

El siguiente ejemplo contiene la mayoría de los tipos de datos estándard disponibles en C, consulte la documentación de su compilador para una lista completa de los tipos disponibles con su compilador, existen además otros tipos, los llamados compuestos (p.e. arrays y estructuras) que serán cubiertos a su debido tiempo en este tutorial.


# include <stdio.h>
 
int main()
{
    int a; /* entero simple */
    long int b; /* entero largo */
    short int c; /* entero corto */
    unsigned int d; /* entero unsigned */
    char e; /* caracter */
    float f; /* punto flotante */
    double g; /* punto flotante de doble precisión */
 
    a = 1023;
    b = 2222;
    c = 123;
    d = 1234;
    e = 'X';
    f = 3.14159;
    g = 3.1415926535898;
 
    printf("a = %d\n", a); /* salida decimal */
    printf("a = %o\n", a); /* salida octal */
    printf("a = %x\n", a); /* salida hexadecimal */
    printf("b = %ld\n", b); /* salida decimal largo */
    printf("c = %d\n", c); /* salida decimal corto */
    printf("d = %u\n", d); /* salida unsigned */
    printf("e = %c\n", e); /* salida caracter */
    printf("f = %f\n", f); /* salida flotante */
    printf("g = %f\n", g); /* salida flotante doble */
  
    printf("\n");
    printf("a = %d\n", a); /* salida entero simple */
    printf("a = %7d\n", a); /* usa una amplitud de 7 campos */
    printf("a = %-7d\n", a); /* justificado por la izquierda con 7 campos */
 
    c = 5;
    d = 8;
    printf("a = %*d\n", c, a); /* utiliza 5 campos */
    printf("a = %*d\n", d, a); /* utiliza 8 campos */
    printf("\n");
    printf("f = %f\n", f); /* salida flotante */
    printf("f = %12f\n", f); /* 12 campos */
    printf("f = %12.3f\n", f); /* 12 campos y 3 decimales */
    printf("f = %12.5f\n", f); /* 5 decimales */
    printf("f = %-12.5f\n", f); /* justificado a la izquierda */
 
    return 0;
}

Con la introducción del estándard ANSI-C dos palabras clave han sido agregadas a C, estas no están ilustradas en los ejemplos pero las discutiremos aquí, estas son const y volatile y se utilizan para decirle al compilador que las variables de estos tipos necesitarán especial consideración. Cuando una variable es declarada como const su valor no padrá ser cambiado por el programa, si Usted trata inadvertidamente de modificar una entidad const el compilador generará un mensaje de error. Cuando utilizamos volatile declaramos que el valor puede ser cambiado por el programa y además puede ser cambiado por una entidad externa como puede ser un pulso de actualización de reloj almacenado en una variable. Ejemplos:


const int indice1 = 5; /* Una variable const debe inicializarse siempre */
const indice2 = 6;
const float valor_grandote = 1245.12;
volatile const int indice3 = 45;
volatile int indice4;

Volver al principio

Hola mundo

CARACTERES DE CONVERSION.

Enseguida tenemos una lista de algunos de los caracteres de conversión y la forma en que son utilizados con la instrucción printf ( ), una lista completa de los caracteres de conversión debe estar incluída en la documentación de su compilador, no se preocupe si por el momento no los entiende, es suficiente saber que cuenta con una gran flexibilidad disponible para cuando Usted esté listo para utilizarlas.

d Notación decimal
i Notación decimal (Nueva extensión ANSI)
o Notación octal
x Notación hexadecimal
u Notación unsigned
c Notación carácter
s Notación de cadena
f Notación de punto flotante

Cada uno de estos caracteres de conversión se utilizan después del signo de porcentaje (%) para indicar el tipo de salida deseada, los siguientes campos pueden agregarse entre estos dos caracteres:

- Justificación por la izquierda en su campo
(n) Amplitud de campo
· Separa (n) de (m)
(m) Dígitos significativos en punto flotante
l largo

Todos estos caracteres de conversión se utilizaron en el ejemplo anterior excepto la notación de cadena, misma que será cubierta mas adelante.

Volver al principio

Hola mundo

COMPARACIONES LÓGICAS.

En el siguiente código mostramos una gran variedad de enunciados de comparación, empezamos definiendo e inicializando nueve variables para ser utilizados en las comparaciones. El primer grupo es el mas simple porque la comparación se dá solo entre dos variables, cualquier variable puede ser reemplazada por una constante y aun seguir siendo válida la comparación, pero utilizar dos variables es el caso mas general. Observe que en este ejemplo hemos introducido el operador de negación que se representa con el símbolo de admiración ! , observe además que los comparadores lógicos "menor que" y "mayor ó igual que" están también disponibles pero no se ilustran en el ejemplo.

Para comprender algunos de los enunciados del ejemplo debemos entender lo que significa verdadero o falso en lenguaje C. Falso está definido como cero, y verdadero es cualquier valor diferente de cero, en los compiladores ANSI-C este valor es 1, sin embargo es recomendable como buena práctica de programación no utilizar este valor para ningún cálculo sino solo para propósitos de control. Cualquier variable de tipo int o char puede utilizarse para una evaluación de verdadero-falso. En el tercer grupo del ejemplo se introducen los conceptos de los operadores lógicos "and" ( && ) en el cual el resultado de la comparación es verdadero si ambas partes del enunciado && son verdaderas, y "or" ( || ) en donde la expresión se evalúa como verdadera si alguna de las dos partes de || es verdadera. Veamos el ejemplo.


int main() /* Comparaciones lógicas */
{
    int x = 11, y = 11, z = 11;
    char a = 40, b = 40, c = 40;
    float r = 12.987, s = 12.987, t = 12.987;
 
    /* Primer grupo de enunciados de comparación */
 
    if (x == y) z = -13; /* z = -13 */
    if (x > z) a = 'A'; /* a = 65 */
    if (!(x > z)) a = 'B'; /* No habrá cambios */
    if (b <= c) r = 0.0; /* r = 0.0 */
    if (r != s) t = c/2; /* t = 20 */
 
    /* Segundo grupo de enunciados de comparación */
 
    if (x = (r != s)) z = 1000; /* x = algún número
      positivo, z = 1000 */ 
    if (x = y) z = 222; /* x = y, y z = 222 */
    if (x != 0) z = 333; /* z = 333 */
    if (x) z = 444; /* z = 444 */
 
    /* Tercer grupo de comparación */
 
    x = y = z = 77;
    if ((x == y) && (x == 77)) z = 33; /* z = 33 */
    if ((x > y) || (z > 12)) z = 22; /* z = 22 */
    if (x && y && z) z = 11; /* z = 11 */
    if ((x = 1) && (y = 2) && (z = 3))
      r = 12.00; /* x = 1, y = 2, z = 3, r = 12.00 */
    if ((x == 2) && (y = 3) && (z = 4))
      r = 14.56; /* Ningún cambio */
 
    /* Cuarto grupo de comparación */
 
    if (x == x); z = 27.345; /* z siempre cambia */
    if (x != x) z = 27.345; /* Nada cambia */
    if (x = 0) z = 27.345; /* x = 0, z no cambia */
 
    return 0;
}

/* Resultado de la ejecución:
(Este programa no tiene salida.)
*/

Volver al principio

Hola mundo

CONSTRUCCIONES ÚTILES EN C.

Existen tres constructores en C que a primera vista no tienen sentido porque no son intuitivos, pero pueden incrementar la eficiencia del código compilado y son utilizados extensivamente por los programadores de C experimentados, Usted debe aprender a utilizarlos debido a que aparecen en prácticamente todos los programas que Usted verá en publicaciones, veamos estos nuevos constructores:


int main()
{
    int x = 0, y = 2, z = 1025;
    float a = 0.0, b = 3.14159, c = -37.234;
 
    /* incremento */
 
    x = x + 1; /* incremento de x */
    x++; /* post-incremento de x */
    ++x; /* pre-incremento de x */
    z = y++; /* z = 2, y = 3 */
    z = ++y; /* z = 4, y = 4 */
 
    /* decremento */
 
    y = y - 1; /* decremento de y */
    y--; /* post-decremento de y */
    --y; /* pre-decremento de y */
    y = 3;
    z = y--; /* z = 3, y = 2 */
    z = --y; /* z = 1, y = 1 */
 
    /* operaciones aritméticas */
 
    a = a + 12; /* Se suma 12 a la variable a */
    a += 12; /* Se suman otros 12 a la variable a */
    a *= 3.2; /* Multiplica a por 3.2 */
    a -= b; /* Resta b de a */
    a /= 10.0; /* Divide a entre 10.0 */
 
    /* enunciados condicionales */
 
    a = (b >= 3.0 ? 2.0 : 10.5 ); /* Esta expresión */
    if (b >= 3.0) /* Y esta expresión */
    a = 2.0; /* son idénticas, ambas */
    else  /* causarán el mismo */
    a = 10.5; /* resultado */
 
    c = (a > b ? a : b); /* c tendrá el mayor valor de a ó b */
    c = (a > b ? b : a); /* c tendrá elñ valor menor de a ó b */
 
    return 0;
}
 
/* Resultado de la ejecución:
(Este programa no tiene salida.)
*/

En la línea 8 simplemente se agrega 1 al valor de x, los siguientes dos enunciados también agregan uno al valor de x, pero no es tan intuitivo respecto a su funcionamiento. Por definición del lenguaje C un doble signo de mas (++) ya sea antes ó después de la variable, incrementa ésta en uno, adicionalmente si los signos mas están después de la variable, ésta se incrementa después de utilizarla, por el contrario, si los signos mas están antes de la variable, ésta se incrementa y después se utiliza. En el siguiente grupo se analiza el decremento de la variable aplicandose las mismas reglas que para el incremento de la variable.

Los operadores aritméticos por su parte se utilizan para modificar cualquier variable por algún valor constante, en la línea 25 se suma 12 a la variable a, en tanto que en la línea 26 el resultado es el mismo, solo que no es tan intuitiva como la instrucción anterior. Colocando el operador deseado antes del signo igual y eliminando la segunda referencia a la variable, esto se puede hacer con los cuatro operadores aritméticos. Al igual que los operadores de incremento y decremento, los operadores aritméticos son utilizados con frecuencia por los programadores experimentados por lo que es muy recomendable su familiarización con el uso de estos operadores.

El operador condicional consiste de tres expresiones separadas por un signo de interrogación y por un signo colon (dos puntos). El enunciado previo al signo de interrogación es evaluada a falso-verdadero, si es verdadero, el enunciado que está entre el signo de interrogación y el signo colon se valora, por el contrario, la expresión posterior al signo colon es valorada. El resultado es idéntico si se utiliza una expresión if con una clausula else pero la expresión condicional tiene la ventaja de ser mas compacta y por lo tanto compilará pocas instrucciones en el programa final.

Este ha sido un capítulo largo, sin embargo contiene información importante para ser un buen programador C, en el siguiente capítulo analizaremos la construcción de bloques de C, las funciones, en ese punto Usted tendrá a su alcance los materiales básicos que el permitirán escribir programas útiles y aplicables a la vida real.

Volver al principio

Hola mundo

© 1998, 1999 Virgilio Gómez Negrete, Derechos Reservados