02 - Conceptos fundamentales sobre el tratamiento de datos Diego Andrés Alvarez Marín Profesor Asociado Universidad Nacional de Colombia Sede Manizales 1 Temario ● Tipos de datos ● Lógica binaria y álgebra de Boole ● Variables y constantes ● Cadenas de texto ● Asignaciones, operadores y precedencia de operadores, expresiones 2 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 Alerta (audible) \a Backspace \b Tabulador horizontal \t Escape (solo GNU) \e Número octal (ej: \o32)\o Backslash \\ Nulo \0 Retorno de carro Formfeed Comillas Cambio de linea=\r\f Número hex (ej: \xF3) Apóstrofe Pregunta \r \f \” \n \x \' \? Números enteros (int) Tipos de entero Ver: http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html#Integer-Types bits signed char char unsigned char short short int signed short signed short int unsigned short unsigned short int int signed signed int unsigned unsigned int long int unsigned long int long long int unsigned long long int MIN MAX MIN MAX 8 -128 127 8 0 255 16 -32768 32767 16 0 65535 32 32 32 32 64 64 Número real: float, double, long double float double long double Tipos booleanos Definido en C99 Cualquier expresión diferente de 0 es true, si es igual a cero es false NOTA: stdbool.h define las palabras bool, false, true (definido en C99) http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/stdbool.h.html Modificadores de tipos ● Son: signed, unsigned, short, long ● Se aplican a char, int, float, double ● ● No se usan con los tipos enum, struct, union, void signed y unsigned solo se aplican a char e int Bit de signo signed unsigned char char ● 0111 1111 127 127 ● 1111 1111 -128 255 sinónimos 32 bits 64 bits 80, 128 bits (depende del compilador y del PC... en mi casa 96 bits) Tipos de dato numéricos ● signed y unsigned solo se aplican a char y a int 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 bytes sizeof(char) < sizeof(short) <= sizeof(int) <= sizeof(long) sizeof(char) < sizeof(short) <= sizeof(float) <= sizeof(double) ● ● Se puede escribir sizeof('m'), etc. también sizeof(3.123), Ver en http://en.wikipedia.org/wiki/sizeof los otros usos de sizeof Big endian vs Little endian ● ● ● Se requiere tener en cuenta para aquellos tipos de datos 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 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 En resumen, para un PC de escritorio: http://code.google.com/p/cpp-principiantes/wiki/Capitulo2 Bits no bytes MAX/MIN numérico (overflow) 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 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). Variable ● Una variable es un nombre o referencia a un valor guardado de la memoria del sistema 28 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 Declaración de variables Las variables se deben declarar antes de usar, de lo contrario los programas pueden tener comportamientos inesperados. tipo nombre_de_variable = [valor_inicial][,][...]; (lo que está en corchetes es opcional) 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 {pequeno=1, mediano, grande, gigante=10} 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; 0x2f, 0x88, 0xAB43, 0xAbCd, 0x1 Si el primer dígito es 0 y el siguiente no es x o 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, f; 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): – ● Se separan 10 bytes de memoria, pero la cadena solo ocupa 5 bytes – ● char cad[] = "hola"; 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 Operaciones aritméticas binarias con asignacion x += y ● x-y x -= y x *= y x %= y x /= y Asignaciones (variable = expresión): y = x + 4*y/(x - 2) + y; La división de valores positivos enteros se trunca siempre hacia cero. De este modo 5/3 es 1. Sin embargo, si alguno de los operandos es negativo, la dirección del redondeo es desconocida y depende de compilador a compilador. Operadores relacionales El resultado de esta operación es 1 o 0, lo que se entiende como verdadero o falso Esto es demasiado, porque solo se guardan 15 dígitos significativos para un double Igualdad de dos números reales Operadores de asignación Operaciones aritméticas binarias con asignación 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 entiende como verdadero o falso Lógica binaria y álgebra de Boole AND NOT XOR OR ● ● Cualquier expresión diferente de cero es verdadero en C, mientras que si es cero se considera falsa. Con &&: si la 1ra expresión es falsa, la 2da no se evalúa: if ((x == 5) && (y == 10)) printf (“x=5 y y=10''); ● Con ||: si la 1ra expresión es verdadera, la 2da 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 enteros unsigned. Bit shifting Precedencia de operadores (C/C++) ● Los paréntesis como tal tiene el orden de precedencia más alto. Precedencia de operadores (C/C++) Constantes ● ● Las constantes no pueden ser modificadas. Su valor no cambia durante la ejecución del programa preprocesador compilador 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 – int → float – float → double Ejemplos: – 3 + 3.13 → 6.13 esto es: (int) + (float) → (float) – 'a' + 300 → (char) + (int) → (int) Moldeo (Casting) ● Para convertir de un tipo de dato a otro (casting), haga lo siguiente: 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 funciones 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í existe tmp Aquí existe tmp y tmp2 Aquí ya no existe tmp2 Aquí no existe ni tmp ni tmp2 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 un error de compilación Librerías de precisión aritmética arbitraría En caso que usted tenga 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. Material basado en: ● http://www.slideshare.net/amraldo/introduction-to-c-programming-78 ● http://www.slideshare.net/petdance/just-enough-c-for-open-source-p ● http://www.gnu.org/software/gnu-c-manual/gnu-c-manual.html ● Wikipedia