Introducción al lenguaje C. Tipos básicos de datos

Elementos de un programa C. Tipos básicos de datos. E/S básica. Sentencias de control. Funciones. Asignación dinámica de memoria. Ficheros. Ficheros indexados: la interfase Btrieve. Compilación y enlazado. Biblioteca de funciones de Turbo C

  • Enviado por: Juan
  • Idioma: castellano
  • País: España España
  • 11 páginas
publicidad

3

Tipos básicos

de datos

Tipos básicos de datos

En C es necesario declarar todas las variables antes de ser utilizadas. Al declarar una variable debemos asignarle uno de los 5 tipos básicos de datos. Estos tipos básicos son los que se muestran en la siguiente tabla.

TIPO

PALABRA RESERVADA

TAMAÑO EN BYTES

sin valor

void

0

carácter

char

1

entero

int

2

coma flotante (simple precisión)

float

4

coma flotante (doble precisión)

double

8

Toda variable declarada de uno de los tipos anteriores (salvo void) se supone que puede ser positiva o negativa a menos que se aplique uno de los modificadores que veremos más adelante.

El tipo void se usa para definir funciones que no devuelven ningún valor (no tienen sentencia return). Por ejemplo, ninguna de las funciones main() utilizadas hasta ahora devuelve valores. Esto provoca un "Warning" en la compilación, que se evita escribiendo void main (), en lugar de escribir simplemente main(). Además, el tipo void se usa en ciertas operaciones de punteros que se estudiarán en el Capítulo 7.

Las variables de tipo char se usan para almacenar caracteres simples o números enteros de tamaño byte. Cuando se asigna un carácter simple a una variable de tipo char, se almacena su código ASCII. Esto permite hacer operaciones matemáticas con este tipo de variables. Por ejemplo, el siguiente programa

#include <stdio.h>

void main ()

{

char caracter;

caracter = '$';

caracter *= 2;

printf ("%c %d", caracter, caracter);

}

muestra en pantalla H 72, puesto que la asignación del carácter '$' a la variable caracter almacena en la variable su código ASCII (36). El %c es el código de formato para visualizar caracteres simples.

El tipo int se utiliza para declarar variables que almacenarán números enteros, sin decimales.

Los tipos float y double permiten almacenar números con decimales.

Cómo declarar variables

Una sentencia C que declare variables debe respetar la siguiente sintaxis:

[clase de almacenamiento][modificador] tipo variable[, variable, ...];

Las clases de almacenamiento y los modificadores del tipo se estudiarán en los próximos apartados del capítulo.

Ejemplos válidos de declaración de variables son:

char letra1, letra2;

int m, n;

float p, q;

double z;

Estas declaraciones deben situarse al principio de la función y antes de cualquier instrucción o llamada a función. Pueden ir precedidas por alguno de los modificadores de tipo que estudiaremos a continuación.

Modificadores del tipo de una variable

Un modificador del tipo es una palabra reservada que antecede a la definición del tipo de la variable, y permite cambiar el tamaño, rango y la característica de signo/sin signo. Los modificadores de tipo son:

  • short

  • long

  • signed

  • unsigned

Estos modificadores se aplican únicamente a los tipos char e int, salvo el long, que en un caso se puede aplicar al tipo double.

La tabla siguiente muestra los rangos y tamaños de cada tipo, según se apliquen los modificadores.

Tipo

Modificadores

Rango

Ocupa

char

unsigned

0 a 255

1 byte

signed

-128 a 127

1 byte

int

short

unsigned

0 a 65.535

2 bytes

signed

-32.768 a 32.767

2 bytes

long

unsigned

0 a 4.294.967.295

4 bytes

signed

-2.147.483.648 a 2.147.483.647

4 bytes

float

±3,4*10-38 a ±3,4*10+38

4 bytes

double

±1,7*10-308 a ±1,7*10+308

8 bytes

long

±3,4*10-4932 a ±1,1*10+4932

10 bytes

Respecto de estos modificadores hay que tener en cuenta los siguientes aspectos:

a) El modificador signed no es necesario. Todas las variables enteras, por defecto, se consideran con signo.

signed char equivale a char

signed int " int

b) El tipo de dato char no es afectado por los modificadores short y long.

short char equivale a long char y a char

c) Turbo C permite una notación breve para declarar enteros sin usar la palabra reservada int.

unsigned equivale a unsigned int

short " short int

long " long int

unsigned short " unsigned short int

unsigned long " unsigned long int

d) Los modificadores signed y unsigned provocan un error si se aplican a los tipos float y double.

e) Los modificadores short y long no afectan a float.

f) Al tipo double no le afecta el modificador short. El modificador long se puede aplicar a partir de la versión 2.00 de Turbo C.

g) La precisión que se puede obtener para los tipos de datos reales viene dada por la siguiente tabla:

TIPO

PRECISIÓN

float

7 dígitos

double

15 dígitos

long double

19 dígitos

Variables locales y variables globales

Dependiendo del lugar del programa en que se declare una variable, a ésta se le llama local o global. Una variable puede declararse en 4 lugares diferentes de un programa:

  • Fuera de todas las funciones (global)

  • Dentro de una función (local a la función)

  • Dentro de un bloque enmarcado por llaves { } (local al bloque)

  • Como parámetro formal (local a la función)

Una variable global es conocida por todo el programa, mientras que una variable local sólo es conocida por la función o bloque en donde está definida.

Variables globales

Cuando una variable está declarada fuera de todas las funciones, incluso fuera de main (), se denomina GLOBAL y es conocida por todas las funciones del programa.

Variables locales

Una variable es LOCAL cuando se declara:

  • dentro de una función

  • como argumento de una función

  • en un bloque de sentencias enmarcado por { }

En cualquiera de estos casos, la variable sólo es conocida por la función o bloque en donde está definida. Se crea al entrar a la función o bloque y se destruye al salir. Esto permite que dos variables locales a diferentes funciones pueden tener el mismo identificador, pero se consideran dos variables diferentes. Por claridad, no se recomienda utilizar nombres iguales para variables diferentes.

A continuación se muestra un programa que pretende ilustrar las diferencias entre variables locales y globales. En él se declara una variable global y, conocida por todas las partes del programa, y varias variables locales, todas con el mismo nombre x: una local a main(), otra local a un bloque dentro de main(), y otra local a una función.

#include <stdio.h>

int y; /* Global. Conocida tanto por main() como por MiFuncion() */

main ()

{

int x; /* Esta x es local a main () */

y = 100;

x = 1;

printf ("x=%d, y=%d", x, y) /* Visualiza x=1, y=100 */

{ /* Comienza bloque */

int x; /* Esta x es local al bloque */

x = 2;

printf ("x=%d, y=%d", x, y) /* Visualiza x=2, y=100 */

MiFuncion () /* Visualiza x=3, y=100 */

printf ("x=%d, y=%d", x, y) /* Visualiza x=2, y=100 */

} /* Fin del bloque */

printf ("x=%d, y=%d", x, y) /* Visualiza x=1, y=100 */

}

MiFuncion ()

{

int x; /* Local a MiFuncion() */

x = 3;

printf ("x=%d, y=%d", x, y) /* Visualiza x=3, y=100 */

}

Clases de almacenamiento

Existen cuatro clases de almacenamiento, que se identifican con las palabras reservadas:

  • auto

  • extern

  • static

  • register

que anteceden al tipo de dato en la declaración de las variables.

El modo de almacenamiento de una variable determina

  • qué partes del programa la conocen (ámbito)

  • qué tiempo permanece en la memoria (tiempo de vida)

Variables automáticas (auto)

Una variable es de clase auto si es local a una función o bloque. La variable se crea cuando se llama a la función y se destruye al salir de ella.

El especificador auto es redundante, pues todas las variables locales son automáticas por defecto.

...

Funcion ( ...

{

auto int a; /* Declara la variable como local a Funcion */

...

Variables externas (extern)

Cuando una variable se define fuera de una función se clasifica como externa y tiene alcance global.

Una variable global puede volver a declararse dentro del cuerpo de una función, añadiendo la palabra reservada extern.

...

int a; /* Variable global */

main ()

{

extern int a; /* Es la misma variable */

...

Esta redeclaración es innecesaria cuando todas las funciones están en el mismo módulo. Sin embargo, si un programa consta de varios módulos diferentes, es necesaria la palabra extern para que sea reconocida por módulos distintos del que contiene la declaración de la variable.

Por ejemplo, supongamos que PROG1.C y PROG2.C son dos módulos que se compilan separadamente y, posteriormente, se enlazan para formar un solo módulo ejecutable.

PROG1.C

PROG2.C

#include <stdio.h>

#include <stdio.h>

int x;

extern int x, y;

int y;

FuncionExterna ()

main ()

{

{

printf ("x=%d, y=%d", x, y);

x = 10; y = 20;

}

printf ("x=%d, y=%d", x, y);

FuncionInterna ();

FuncionExterna ();

}

FuncionInterna ()

{

printf ("x=%d, y=%d", x, y);

}

En el módulo PROG1.C (que se compilará a PROG1.OBJ) hay una llamada a FuncionInterna(). Esta función no necesita la redeclaración de x e y puesto que reside en el mismo módulo en el que estas variables están declaradas como globales. Sin embargo, hay una llamada a FuncionExterna(), y esta función reside en un módulo distinto (PROG2.C) que se compilará por separado (a PROG2.OBJ). Para que FuncionExterna() pueda reconocer a las variables x e y que están declaradas como globales en PROG1.C, es necesario redeclararlas como de clase extern. En caso contrario, PROG2.C "creería" que son variables locales propias no declaradas, por lo que se generaría un error en la compilación.

A partir de los módulos objeto PROG1.OBJ y PROG2.OBJ, mediante el enlazador, se crea un módulo ejecutable, por ejemplo PROG.EXE. Este programa visualizaría en 3 ocasiones la línea

x=10, y=20

puesto que para las tres funciones -main(), FuncionInterna() y FuncionExterna()- las variables x e y son las mismas.

Variables estáticas (static)

Una variable estática existe durante todo el tiempo de ejecución del programa.

Si se aplica la clase static a una variable local, Turbo C crea un almacenamiento permanente para ella, como si fuese global. La diferencia entre una variable local estática y una variable global es que la primera sólo es conocida por la función o bloque en que está declarada. Se puede decir que una variable local estática es una variable local que mantiene su valor entre llamadas.

Por ejemplo, cada vez que se llama a la función

incremento ()

{

int n;

n++;

printf ("n=%d", n);

}

se visualiza n=1, mientras que si la función es

incremento ()

{

static int n;

n++;

printf ("n=%d", n);

}

se visualiza, sucesivamente, n=1, n=2, ...

Cuando se aplica la clase static a una variable global, esta se convierte en global sólo del archivo en que está declarada. Así, en el ejemplo de la página anterior, si en PROG1.C en lugar de la línea declaramos x de la forma

static int x;

se produciría un error en el enlazado, incluso aunque en PROG2.C x esté declarada como extern.

Clase registro (register)

La clase registro es idéntica a la clase auto, por tanto sólo se puede aplicar a variables locales. Sólo se diferencian en el lugar en que se almacenan.

Cualquier variable se almacena, por defecto, en la memoria. Si se declaran de clase register, Turbo C intentará mantenerlas en un registro de la CPU, en cuyo caso se acelerarán los procesos en los que intervengan. Puesto que el número de registros de la CPU es limitado, Turbo C mantendrá las variables en un registro, si es posible. En caso contrario la convertirá en auto.

Una variable de clase registro debe ser de los tipos char o int, y son ideales para contadores de bucles.

A estas variables no se les puede aplicar el operador & (dirección de).

Inicialización de variables

Al declarar una variable se le puede asignar un valor inicial, independientemente de que lo mantenga o no a lo largo de todo el programa. Así, son válidas sentencias como:

unsigned int x = 40000;

char letra = 'F';

register int b = 35;

char cadena[12] = "Buenos días";

Las variables globales o estáticas se inicializan a 0 si no se especifica ningún valor. Ambas deben inicializarse con expresiones constantes.

Las variables estáticas son inicializadas por el compilador una sola vez, al comienzo del programa.

Las variables automáticas y de registro tienen valores desconocidos hasta que se les asigne uno. Si tienen valores iniciales, se asignan cada vez que se ejecuta el bloque donde se definen.

Ejercicios

1. Indica el tipo de dato más adecuado para declarar variables que almacenen los valores cuyos rangos se muestran a continuación:

Números enteros del 0 al 70.000

Números enteros del 1 al 100

Números reales del 1 al 100

Números enteros del -100 al +100

Números reales del -100 al +100

Números enteros del 0 al 10.000

Cualquier letra mayúscula

Números enteros del 0 al 5.000.000.000

Números del -10.5 al 90.125

2. ¿Qué hace el siguiente programa?

#include <stdio.h>

void main ()

{

unsigned char caracter;

scanf ("%c", &caracter);

caracter > 127 ? caracter++ : caracter--;

printf ("%c", caracter);

}

3. Indica el tipo de variable (local/global), ámbito y tiempo de vida de las variables a, b, c y d de un programa que tenga la estructura que se muestra a continuación:

int a;

void main ()

{

int b;

...

}

MiFuncion ()

{

int c;

static int d;

...

}