02 - Conceptos fundamentales sobre tipos de datos en lenguaje C

Post on 13-Jun-2015

194 views 1 download

description

Si quiere descargar la presentación y los códigos fuente, dirijase a: http://programaciondecomputadoresunalmzl.wikispaces.com/codigos_y_diapositivas Le agradecería si me reporta los errores que encuentre en la diapositiva (daalvarez arroba unal punto edu punto co)

Transcript of 02 - Conceptos fundamentales sobre tipos de datos en lenguaje C

1

02 - Conceptos fundamentales sobre el tratamiento de datos

Diego Andrés Alvarez MarínProfesor Asociado

Universidad Nacional de ColombiaSede Manizales

2

Temario

● Tipos de datos● Lógica binaria y álgebra de Boole● Variables y constantes● Cadenas de texto● Asignaciones, operadores y precedencia de

operadores, expresiones

Tipos de datos● Los tipos de datos determinan el conjunto de

valores que un objeto puede tomar y las operaciones que se pueden realizar con ellas.

● Existen datos:– caracteres: char

– numéricos: int, float, double

– booleanos (definidos en C99) _Bool

– definidos por el usuario: struct, union, enum (los veremos más tarde)

– punteros

– complejos (definidos en C99) _Complex

Caracter (char)

● Representa un conjunto de 8 bits de datos que varían entre 0 y 255 (256 números=28), es decir, tiene el tamaño de un byte

Algunos caracteres especiales

\a \rBackspace \b \f

\t \”Escape (solo GNU) \e \n

\o \xBackslash \\ \'

\0 \?

Alerta (audible) Retorno de carroFormfeed

Tabulador horizontal ComillasCambio de linea=\r\f

Número octal (ej: \o32) Número hex (ej: \xF3)Apóstrofe

Nulo Pregunta

Tipos booleanos

NOTA: stdbool.h define las palabrasbool, false, true (definido en C99)

Definido en C99

http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdbool.h.html

Cualquier expresión diferente de 0 es true, si es igual a cero es false

Númerosenteros

(int)

Número real:float, double, long double

float

double

long double

Representación de números reales en el PC

Ver:● David Goldberg (1991). What Every Computer

Scientist Should Know About Floating-Point Arithmetic. Computing Surveys, March 1991.

– https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Double/paper.pdf

● http://en.wikipedia.org/wiki/Floating_point● http://en.wikipedia.org/wiki/IEEE_floating_point● http://en.wikipedia.org/wiki/Single-precision_floating-point_format

● http://en.wikipedia.org/wiki/Double-precision_floating-point_format

● http://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format

Modificadores de tipos

● Son: signed, unsigned, short, long● signed y unsigned sólo se aplican a char e int● long se aplica a double● No se usan con los tipos enum, struct, union,

void, float

signed unsigned

char char

0111 1111 127 127

1111 1111 -128 255

Bit de signo

32 bits

64 bits

80, 128 bits (depende del compilador y del PC... en mi casa 96 bits)

sinónimos

Tamaño de los datos(la palabra clave sizeof)

● Los tamaños de los datos dependen de la máquina y el compilador utilizado. Estos se miden en bytessizeof(char) < sizeof(short) <= sizeof(int) <= sizeof(long)

sizeof(char) < sizeof(short) <= sizeof(float) <= sizeof(double)

● Se puede escribir también sizeof(3.123), sizeof('m'), etc.

● Ver en http://en.wikipedia.org/wiki/sizeof los otros usos de sizeof

MAX/MIN numérico

● Dependen de la plataforma

● Los máximos y los mínimos están definidos en limits.h (enteros) y float.h (reales)

● Ver el archivo /usr/include/limits.h ● Ver el archivo /usr/include/float.h

unsigned char

unsigned char

Ver: http://www.gnu.org/software/libc/manual/html_node/Floating-Point-Parameters.html

Tipos de entero(nota: estas constantes dependen del computador y pueden variar)

Ver: http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Integer-Types

bits MIN MAX MIN MAX

signed char -128 127

8 0 UCHAR_MAX 0 255

16 SHRT_MIN SHRT_MAX -32768 32767

16 0 USHRT_MAX 0 65535

32 INT_MIN INT_MAX -2147483648 2147483647long int 32 LONG_MIN LONG_MAX

32 0 UINT_MAX 4294967295Uunsigned long int 0 ULONG_MAXlong long int 64 LLONG_MIN LLONG_MAX -9223372036854 775808LL 9223372036854 775807LL

CHAR_BIT8

SCHAR_MINCHAR_MIN

SCHAR_MAXCHAR_MAX

charunsigned charshortshort intsigned shortsigned short intunsigned shortunsigned short intintsignedsigned int

unsignedunsigned int

Evite usar float

MAX/MIN numérico

(overflow)

Por lo tanto la próxima vez declare la variable contar_ovejas como

unsigned long int o unsigned long long int

Fuente: https://xkcd.com/571/

DBL_EPSILON representa el número más pequeño posible que puede sumársele a 1.0 para que (1.0 + DBL_EPSILON) > 1.0. En MATLAB esta constante se llama "eps". DBL_EPSILON representa la exactitud relativa de la aritmética del computador. Observe que un double tiene 52 bits en su parte de fracción, por lo que 2-52 = DBL_EPSILON = 2.22044604925031e-16 es la mayor precisión posible.

Ver: http://en.wikipedia.org/wiki/Machine_epsilon

Como obtener DBL_EPSILON

Recuerde que:DBL_EPSILON=2-52

=2.22044604925031e-16

Big endian vs Little endian

● Se requiere tener en cuenta para aquellos tipos de datos que ocupan varios bytes, ya que el orden en el que se organizan los bytes es importante

● Tiene que ver con el orden de como se representan los bytes en memoria y en disco. Es muy importante tenerlo en cuenta cuando se van a trabajar con supercomputadoras.

● Ver: http://en.wikipedia.org/wiki/Endianness

Big endian vs Little endian

El término endianness designa el formato en el que se almacenan los datos de más de un byte en un computador. El problema es similar a los idiomas en los que se escriben de derecha a izquierda, como el árabe, o el hebreo, frente a los que se escriben de izquierda a derecha, pero trasladado de la escritura al almacenamiento en memoria de los bytes.

El sistema big-endian adoptado por Motorola entre otros, consiste en representar los bytes en el orden "natural": así el valor hexadecimal 0x4A3B2C1D se codificaría en memoria en la secuencia {4A, 3B, 2C, 1D}. En el sistema little-endian adoptado por Intel, entre otros, el mismo valor se codificaría como {1D, 2C, 3B, 4A}, de manera que de este modo se hace más intuitivo el acceso a datos, porque se efectúa fácilmente de manera incremental de menos relevante a más relevante (siempre se opera con incrementos de contador en la memoria).

Big endian vs Little endian

El sistema big-endian consiste en representar los bytes en el orden "natural": así el valor hexadecimal 0x4A3B2C1D se codificaría en memoria en la secuencia {4A, 3B, 2C, 1D}. En el sistema little-endian el mismo valor se codificaría como {1D, 2C, 3B, 4A}.

La librería stdint.hEl tamaño de una variable entera varía de sistema operativo a sistema operativo y de computador a computador. En C99 se incluyen las librerías inttypes.h y stdint.h con el ánimo de mejorar la portabilidad de los programas con respecto a las variables enteras.

stdint.h define los siguientes tipos de entero:

La librería stdint.h

Se pueden definir variables enteras de N = 8, 16, 32 y 64 bits. Adicionalmente, los tipos de entero se pueden clasificar en:

● Enteros de ancho exacto (exact-width integer): se garantiza que ocuparán N bits.

● Enteros del mínimo ancho (least-width integer): son el tipo de enteros más pequeño en la implementación.

● Enteros más veloces (fastest integer): son el tipo de entero más rápido en la implementación.

● Punteros a entero (pointer integer): se garantiza que contendrán un puntero.

● Enteros del máximo ancho (maximum-width integer): son el tipo de enteros más grandes en la implementación.

Ejemplo de stdint.h

int64_t es:● un long int en 32 bits (%ld) ● un long long int en 64 bits (%lld)

Finalmente, tenga en cuenta que el C99 define en math.h los tipos float_t y double_t.

Números complejos● Introducidos en el C99. Existen tres tipos:

– float _Complex

– double _Complex

– long double _Complex

● El C99 introduce la librería complex.h que hace que utilizar números complejos sea fácil– Define el tipo complex que es lo mismo que double

_Complex

– Define la constante I (i mayúscula) ... es un const float _Complex

– http://en.wikipedia.org/wiki/Complex.h

– http://pubs.opengroup.org/onlinepubs/009604499/basedefs/complex.h.html

Punteros

● Los punteros son un tipo de dato que guarda direcciones de memoria (de variables, constantes, funciones, etc)

int* x; // se puede escribir tambien int * x o int *x

int *x, *y; // dos punteros enteros

int *x, y; // un puntero a entero y una variable entera

● Si no se inicializa un puntero a una dirección de memoria, este apunta a cualquier lugar de memoria y por lo tanto si se usa, usted podría hacer que el programa falle (crash).

35

Variable

● Una variable es un nombre o referencia a un valor guardado de la memoria del sistema

Reglas para la creación de los nombres de las variables/identificadores/nombres de

funciones/estructuras, etc...

● Pueden contener letras (A-Z, a-z), dígitos (0-9) y el guión bajo _ . Ejemplo Radio_2 es válido

● El nombre debe comenzar con letras o con el guión bajo: radio y _radio son válidos, 2radio no lo es.

● Las palabras clave (while, for, int, long, etc.) no se pueden utilizar como nombres de variables

● Los nombre de variables son sensitivos a las mayúsculas: area, Area, AREA y aREA son variables diferentes

Palabras clave

Las variables se deben declarar antes de usar, de lo contrario los programas pueden tener comportamientos inesperados.

Declaración de variables

tipo nombre_de_variable = [valor_inicial][,][...];(lo que está en corchetes es opcional)

Declaración de variables

En el C89 se requería que las variables se declararan antes de cualquier comando al principio de un bloque. En el C99 (y de forma similar al C++), las variables se pueden declarar en cualquier lugar de un bloque.

En C89 double d; tenía que haber estado junto a int c;

Constantes●Son valores literales y fijos que se asignan a las variables o que se utilizan para utilizar directamente en las expresiones:●Enteros: 3, 3UL, 0x12, 012●Punto flotante (float, double): 3.1415, 3.1415F●Caracteres: 'V', '\x4A', '\o101'●Cadenas: "Pepito Perez", "Una cadena\n"●Enumeración:

– enum dias {lun, mar, mie, jue, vie, sab, dom}

– enum color {negro=1, gris, azul, rojo=10, verde, blanco}

Constantes enteras

● Si una secuencia de dígitos está precedida por 0x ó o 0X (cero equis), entonces la constante se considera hexadecimal (0..9, A..F). Ejemplos; 0xab2f, 0x88, 0xAB43, 0xaBcD, 0x1

● Si el primer dígito es 0 y el siguiente no es x ó X, entonces la constante se considera octal (0..7). Ejemplos; 057, 012, 03, 0241

● En el resto de los casos se considera decimal (0..9). Ejemplo: 459, 23901, 8, 12

Existen varios tipos de datos enteros: enteros cortos, largos, con signo y sin signo. Las constantes enteras se clasifican en estas categorías agregando una secuencia de una o más letras al final de la constante:

u, U: Unsigned integer type: sin signo.

l, L: Long integer type: entero largo.

Por ejemplo 45U es una contante unsigned int. 45UL es una constante unsigned long int (las letras se pueden poner en cualquier órden).

El ISO C99 considera los tipos long long int y unsigned long long int. Uno puede utizar entonces dos "L"s para obtener una constante long long int; agregue un "U" a dicha constante para obtener una constante unsigned long long int, como por ejemplo: 45ULL.

Constantes reales

● La parte entera o la parte decimal se puede omitir, pero no ambas. Por ejemplo:

double a, b, c, d, e;

a = 4.7; b = 4.; c = 4; d = .7; e = 0.7;

● Se puede agregar una letra al final de una constante numérica real para forzarla a que sea de un tipo determinado. "f" o "F" significa constante float; "l" o "L" significa constante long double. Si no agrega letras, es una constante double.

Cadenas de texto● Se representan como arrays de caracteres

● C no limita la longitud de la cadena

● El final de la cadena está dado por un 0(cero) ó '\0', el cual no se indica explícitamente.

● Se separan 5 bytes de memoria (el \0 se cuenta):

– char cad[] = "hola";

● Se separan 10 bytes de memoria, pero la cadena solo ocupa 5 bytes

– char cad[10] = "hola";

● Se separan 5 bytes de memoria. Se indica el final de la cadena.

– char cad[] = {'h','o','l','a','\0'};

Esta es una cadena constante:

"tutti frutti ice cream"

Estas cadenas se concatenan:

"tutti " "frutti" " ice " "cream"

Esta cadena tiene dos secuencias con códigos de escape (comienzan por \):

"\"hello, world!\""

Si una cadena es muy larga como para hacerla caber en una sola línea, se puede utilizar el backslash \ para escribirla en líneas diferentes:

"Today's special is a pastrami sandwich on rye bread with \

a potato knish and a cherry soda."

Las cadenas adyacentes se concatenan automáticamente, de modo tal que se pueden tener constantes cadena que ocupan varias líneas. Por ejemplo:

"Tomorrow's special is a corned beef sandwich on "

"pumpernickel bread with a kasha knish and seltzer water."

es lo mismo que:

"Tomorrow's special is a corned beef sandwich on \

pumpernickel bread with a kasha knish and seltzer water."

Operadores

● Los operadores especifican como se puede manipular un objeto/variable– Aritméticos: + - * / %

– Relacionales: > < >= <= == !=

– Lógicos: && || !

– De incremento/decremento: x++ y-- ++x --y

– Bit a bit: & | ^ ~ >> <<

– De asignación: = += -= *= /= %= &= |=

– Especiales: ? : , . -> & * sizeof

Operaciones aritméticas, asignaciones

● Operaciones aritméticas binarias

x+y x-y x*y x/y x%y● Operaciones aritméticas binarias con

asignación

x += y x -= y x *= y x /= y x %= y

● Asignaciones (variable = expresión):

y = x + 4*y/(x - 2) + y;

En C99, la división de valores positivos enteros se trunca siempre hacia cero. De este modo 5/3 es 1. y -5/3 = -1. Tenga en cuenta que esto no era verdad en C89, ya que el redondeo podía ser hacia cero o hacia menos infinito. Todo dependía del compilador

Operadores relacionales

El resultado de esta operación es 1 o 0, lo que se entiendecomo verdadero o falso

Igualdad de dos números

reales

Esto es demasiado, porque solo se guardan 15 dígitos significativos para un double

Operadores de asignación

Operaciones de incremento

Tenga en cuenta que incrementar un puntero solo tiene sentido si el nuevo puntero apunta a una dirección de memoria válida.

Operadores lógicos

El resultado de esta operación es 1 o 0, lo que se entiendecomo verdadero o falso

Lógica binaria y álgebra de Boole

NOT AND

OR

XOR

● Cualquier expresión diferente de cero es verdadero en C, mientras que si es cero se considera falsa.

● Con &&: si la primera expresión es falsa, la segunda no se evalúa:

if ((x == 5) && (y == 10)) printf ("x=5 y y=10");

● Con ||: si la primera expresión es verdadera, la segunda no se evalúa:

if ((x == 5) || (y == 10)) printf ("x=5 o y=10");

● Negación:

if (!(x == 5)) printf ("x es diferente de 5");

Uno puede escribir código como (no recomendable):

if (foo && x++) bar();

Si foo es cero, entonces x no se incrementará y bar() no se evaluará.

Operadores bit a bit

Bitwise Logical Operators

Los operadores & | ^ ~ se pueden utilizar únicamente con char o unsigned int.

Bit shifting

Comentarios

() de izquierda a derecha paréntesis (para cambiar prioridades)

1

() de izquierda a derecha llamado a función

[] de izquierda a derecha elemento de vector

-> . de izquierda a derecha

++ -- de izquierda a derecha Post-incremento y decremento

++ -- de derecha a izquierda Pre-incremento y decremento

+ - de derecha a izquierda Signo + o -

! ~ de derecha a izquierda NOT lógico y NOT binario

(tipo) de derecha a izquierda

* de derecha a izquierda operador “contenido de” en punteros

& de derecha a izquierda dirección de memoria de una variable

sizeof de derecha a izquierda tamaño de

Prece-dencia

Grupo deoperadores

Orden de evaluación

0mayor

Prioridad

selección de elemento de estructura de forma directa (.) o con unPuntero (->)

2operadores

unarios

conversión de tipo. Ejemplo (int), (char)

Precedencia de operadores

3 * / %

4 + -

5 << >>

6 < <= > >=

7 == !=

8 & ^ |

9 && ||

10 ?:

11

,

Prece-dencia

Grupo deoperadores

Orden de evaluación Comentarios

de izquierda a derecha multiplicación, división, módulo

de izquierda a derecha suma y resta

de izquierda a derecha operadores de desplazamiento bit a bit

de izquierda a derecha menor que, menor o igual que, mayor que, mayor o igual que

de izquierda a derecha igual a, diferente de

de izquierda a derecha AND binario, XOR binario, OR binario

de izquierda a derecha AND lógico, OR lógico

de derecha a izquierda operador si?entonces:de lo contrario

= += -= *= /= %= &= ^= |=

<<= >>=de derecha a izquierda asignaciones

12prioridad

másbaja

de izquierda a derecha coma (se usa en el for)

Precedencia de operadores

Constantes

● Las constantes no pueden ser modificadas.● Su valor no cambia durante la ejecución del

programa

compilador

preprocesador

Expresiones

● Una expresión es una combinación de valores, variables, operadores y funciones

Conversión entre tipos de datos

● Cuando se mezclan expresiones de una precisión baja con unas de precisión alta, C prefiere utilizar la precisión alta:

char → int → long int→ float → double → long double

● Ejemplos:– 3 + 3.13 → 6.13 esto es: (int) + (float) → (float)

– 'a' + 300 → 397 esto es: (char) + (int) → (int)

Moldeo (Casting)

● Para convertir de un tipo de dato a otro (casting), haga lo siguiente:

Por la forma como el PC almacena los reales, no es posible representar 3.3 y 3.4 exactamente

Convertir cadenas a números y números a cadenas

#include <stdlib.h>

#include <stdio.h>

Ambito de las variables

● Las variables se dividen en: globales y locales.● Las variables locales sólo existen en el bloque

en el cual se definieron { } y se deben declarar antes de utilizarlas:

Aquí ya no existe tmp2

Aquí existe tmp y tmp2

Aquí no existe ni tmp ni tmp2

Aquí existe tmp

Ambito de variables por bloques

Las variables (locales) sólo existen en el bloque en el cual se definieron. Los bloques se definen por { }

Si aquí se hace una referencia a b, aparecería unerror de compilación

Librerías de precisión aritmética arbitraría

En caso que usted tenga que utilizar muchos más decimales que los que se pueden almacenar en un long double, se sugiere utilizar una librería como:

● GNU Multiple Precision Arithmetic Library http://gmplib.org/● GNU MPFR Library http://www.mpfr.org/

ambas librerías soportan tantos decimales como la memoria del computador pueda almacenar.

Wide characters (wchar)

Material basado en:

● http://www.slideshare.net/amraldo/introduction-to-c-programming-7898353

● http://www.slideshare.net/petdance/just-enough-c-for-open-source-programmers

● http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html

● Wikipedia