Borland C CARLOS ROA ROMERO C • CAPITULO 2 VARIABLES, CONSTANTES, OPERADORES Y EXPRESIONES TIPO DE DATOS: char int float double void MODIFICADORES: (p17) signed unsigned long sort MODIFICADORES DE ACCESO: const -para crear constantes volatile ESPECIFICACIONES DE CLASE DE ALMACENAMIENTO: extern -define (no reserva memoria) una variable, ya que esta variable se encuentra en otro modulo. static -declara una variable estatica (solo se inicializa una vez y permanece en memoria). register -peticion de almacenar una variable en un registro libre de la CPU. auto -si no se especifica nada este es el tipo por defecto. Nota: pueden declararse variables locales en cualquier bloque del programa. ASIGNACION: nombrevariable=expresion; Se puede asignar un mismo valor a varias variables a la vez: a=b=c=valor; CODIGOS DE BARRA INVERTIDA: (p34) Estos codigos se utilizan para representar caracteres especiales. \b retroceso \t tabulador \n salto de linea \f salto de pagina \r retorno de carro \a alarma (pitido) \” comilla doble \0 nulo OPERADORES: ARITMETICOS: -, +, *, /, %, --, ++ RELACIONALES: <, <=, >, >=, ==, != LOGICOS: &&, ||, ! (and, or , not). NIVEL BIT: ^, &, |, ~, >>, << (o exclusivo, y a nivel bit, o a nivel bit, complemento a 1, corrimiento a derecha e izquierda de bits). DE PUNTERO: & devuelve la direccion de su operando &variable (“la direccion de”). * ademas de servir para declarar variables de tipo puntero devuelve el valor de la variable situada en la direccion de su operando (“lo almacenado en la direccion”). OTROS: ? para simplificar algunas expresiones de tipo if-then-else Exp1?Exp2:Exp3. sizeof (nombrevariable) devuelve (en tiempo de compilacion) el tamaño de esa variable o tipo de dato. . y -> para referenciar elementos individuales de estructuras y uniones. [ ] indexacion de arrays /punteros. ( ) para aumentar la precedencia de las operaciones contenidas. { } para crear bloques de codigo. +=, -=, *=, /=, etc operadores compuestos. CONVERSION DE TIPO DEVUELTO: (tipo)expresion obliga a que el resultado de esa expresion se evalue como tipo. • CAPITULO 3 INSTRUCCIONES DE CONTROL Nota: en C cualquier espresion distinta de 0 es cierta. IF if (expresion) instruccion; (p54) else instruccion; Nota: en el caso de los if anidados cada else esta asociado al if precedente mas cercano a menos que se cambie el orden logico por medio de { }. ? Exp1?Exp2:Exp3 Se evalua Exp1, y si es cierta (!=0) se devuelve Exp2, de lo contrario se devuelve Exp3 SWITCH switch (expresion){ case constante1: [secuencia de instrucciones;] [break;] case constante2: ..... [default:] [secuencia de instrucciones;] } Nota1: Solo se puede evaluar por igualdad. Nota2: si se utilizan constantes tipo caracter estas se convertiran automaticamente a sus valores enteros. Nota3: la clausula break es opcional. FOR for (inicializacion;condicion;incremento) instruccion; Esta es una estructura muy fexible, ya que cualquier seccion puede contener una expresion valida de C que no tenga que ver con la seccion, incluso pueden aparecer vacias o con varias inicializaciones, condiciones o incrementos separados por comas. Borland C CARLOS ROA ROMERO WHILE while (condicion) instruccion; DO WHILE do{ secuencia de instrucciones; } while (condicion); GOTO ETIQUETA goto etiqueta ... etiqueta: Nota: solo se recomienda usar este tipo de control para salir de varios bucles anidados para el codigo. Por lo general esta estrucctura va en detrimento de la programacion estructurada. simplificar NOTA: instruccion se puede sustituir por un bloque de codigo { instruciones;}. NOTA: la instruccion break fuerza la terminacion de un bucle o case. NOTA: la funcion exit(valordevueltoalSO) fuerza la salida del programa. NOTA: la instruccion continue fuerza la ejecucion de la siguiente iteracion (hace que se salte el resto del codigo contenido en un bucle volviendo a la linea donde se evalua la condicion repetitiva.) • CAPITULO 4 FUNCIONES especificador_de_tipo_devuelto nombre_funcion (lista_de_parametros){ cuerpo de la funcion; } El especificador de tipo devuelto especifica de que tipo es el valor devuelto por la instruccion return. Si no se especifica nada se devuelve un entero. Se puede devolver cualquier tipo de dato o vacio (void) En C todas las funciones estan al mismo nivel de ambito (unas no pueden declararse dentro de otras). LLAMADA POR VALOR: La llamada por valor es la llamada estandard, cada vez que se llama a una funcion con unos argumentos (parametros) se crea una copia del valor de los mismos, de forma que si estos se modifican en el cuerpo de la funcion el valor de estos no varia en el programa desde donde se ha llamado a la funcion. LLAMADA POR REFERENCIA: Esta se realiza pasando como argumento un puntero (void func(int *a)) PASO DE ARRAYS: Cuando se pasa un array en realidad lo que se pasa es la direccion del array (un puntero al primer elemento del mismo, o lo que es lo mismo el nombre del array sin indices) y no la copia del mismo. ARGUMENTOS DE MAIN(): int main (int argc, char *argv[ ]) argc es un entero que contiene el nº de argumentos que se han pasado desde la linea de comandos. Como minimo este valdra 1 ya que el nombre del programa se considera como parametro. argv es un puntero a un array de punteros de caracteres (cadenas de caracteres) NOTA: todas las funciones implementadas deben tener un prototipo, esto es una declaracion antes de la funcion main() para que el compiladro sepa que tipo devuelve. especificador_tipo_devuelto nombre_funcion (lista_de_parametros); • CAPITULO 5 ARRAYS tipo nombre_array[tamaño 1ªdim][tamaño 2ªdim]....[={lista valores}] Nota: un array multidimensional es un array de punteros a otros arrays. Nota: todos los arrays en C comienzan con el indice 0 Nota: en C no se comprueban los limites de un array. Nota: el nombre de un array sin indice contiene la direccion de su primer elemento (puntero) CADENAS: En C una cadena es un array unidimensional de caracteres que finaliza con el caracter nulo \0 (se corresponde con 0) Las funciones mas utilizadas para el tratamiento de cadenas son: strcpy(), strcat(), strlen() y strcmp() que se encuentran en el fichero de cabezera string.h ASIGNACION DINAMICA DE MEMORIA: Esta se realiza en la zona de memoria dinamica (heap) mediante las funciones: void *malloc(size_t numero-bytes); void free(void *p); que estan contenidas en stdlib.h. size_t es un tipo definido como entero sin signo. Mediante la funcion malloc() se reserva memoria y se devuelve un puntero de tipo void que apunta a la primera posicion de memoria asignada, si es que se ha asignado, en caso contrario (no hay memoria suficiente) se devuelve un puntero nulo (¡cuidado!). Posteriormente se puede librerar esta memoria con la funcion free(). • CAPITULO 6 PUNTEROS Un puntero contiene una direccion de memoria donde se ubica otra variable. tipo_base *nombrepuntero; Borland C CARLOS ROA ROMERO ARITMETICA DE PUNTEROS: Solo admiten suma, resta y operaciones relacionales. Siempre que se incremente o decremente un puntero este apuntara a la porcion de memoria del elemento siguiente o anterior de su tipo base. Los punteros const se utilizan para asegurar que una variable que es pasada a una funcion mediante un puntero no pueda ser modificada en la funcion. • CAPITULO 7 ESTRUCTURAS, UNIONES Y TIPOS DEFINIDOS POR EL USUARIO ESTRUCTURAS Conjunto de variables a las que se hace referencia con el mismo nombre. Cuando se declara una estructura se esta definiendo un tipo de variable compuesta, por tanto no existe realmente una variable de este tipo (de esta esctructura) hasta que no se declara. struct [etiqueta]{ tipo nombrevar1; tipo nombrevar2; ...... } [lista_de_variables]; Nota: con esta declaracion no se declara una variable llamada etiqueta sino un tipo de variable llamado struct etiqueta, siendo estiqueta opcional si se pone un/varios nombres de variables en lista_de_variables, ya que se asume que este tipo solo es valido para esas variables y no se volvera a referenciar. Nota: para hacer referencia a cada miembro de la estructura se una un punto (.) nombre_de_la_estructura.miembro o por medio de -> si se referencia mediante punteros puntero_a_la_estructura->miembro CAMPOS DE BITS struct nombre_estructura{ tipo nombre1:longitud_en_bits; tipo nombre2:longitud_en_bits; ...... } Donde tipo puede ser int, unsigned (1 bit) o signed. Nota: cualquier programa que utilize campos de bits dependera de la maquina, ya que no hay forma de saber si los campos se distribuiran de derecha a izquierda o viceversa. UNIONES (p177) union nombre_union{ tipo nombre1; tipo nombre2; ..... } Es una posicion de memoria compartida por dos o mas variables, (generalmente de tipos distintos) de forma que se puede acceder a ella como si fuera un tipo u otro. Nota: cuando se declara una union se reserva espacio para el tipo de mayor tamaño. ENUMERACIONES Es un conjunto de constantes enteras que especifican todos los valores validos que puede tener una variable de ese tipo. enum [etiqueta]{lista_de_valores}[lista_de_variables]; Ej: enum monedas{penique,dolar,peseta,euro}; Nota: la lista de valores son solo nombres (sin comillas porque no son cadenas), pero realmente tienen un valor entero que, pudiendose inicializar, por defecto valen 0,1,2... (en nuestro ejemplo la condicion peseta=2 seria verdadera) TYPEDEF typedef tipo nombre; Permite definir nuevos nombres (no sustituirlos) a tipos validos de datos, de forma que no se crea un tipo de dato nuevo, sino que se define un nuevo nombre para un tipo ya existente (como un sinonimo) Ej: si declaramos typedef int entero; podriamos hacer otra declaracion del tipo: entero k; creandose el mismo resultado que si pusieramos int k; • CAPITULO 8 ENTRADA, SALIDA, FLUJOS Y ARCHIVOS Las funciones de entrada salida del standard ansi de C se encuentran en el archivo de cabezera stdio.h FLUJOS (streams) El sistema de E/S de C ofrece un nivel de abstraccion entre el programador y el hardware, transformando cada uno de los dispositivos de E/S en dispositivos logicos llamados flujos, teniendo estos un comportamiento similar independientemente del dispositivo. Flujo de texto: secuencia de caracteres, estos caracteres pueden sufrir modificaciones, por lo que no hay relacion entre caracteres enviados y recibidos (tanto en contenido como en numero). Flujo binario: secuencia de bytes que tiene una correspondencia 1 a 1 con el dispositivo externo. No se realizan conversiones. ARCHIVOS Concepto logico aplicable a cualquier cosa. Mediante la operacion de apertura se establece un flujo con este archivo. Nota: no todos los archivos tienen las mismas posibilidades. (unos permiten acceso directo, otros solo lectura...) Nota: los flujos de texto predefinidos se abren al ejecutar el programa, y son: stdin(teclado), stdout(pantalla), stderr(pantalla), stdaux(primer puerto serie), stdprn(impresora). Borland C CARLOS ROA ROMERO LECTURA Y ESCRITURA DE CARACTERES int getche(void) {conio.h} espera a que se pulse una tecla y devuelve su valor. int getch(void) {conio.h} funciona igual que getche pero no tiene echo en pantalla. int getchar(void) {stdio.h} funciona igual que getche pero hay que pulsar enter. int putchar(int c){stdio.h} escribe un caracter en pantalla en la posicion actual del cursor. Devuelve c si se ha escrito c y EOF si se produce un error. Nota: aunque c se declara como entero solo se usa el byte menos significativo. LECTURA Y ESCRITURA DE CADENAS char *gets(char *cad) {stdio.h} sirve para introducir una cadena por el teclado, que finaliza con el retorno de carro, colocando la cadena en la direccion apuntada por su argumento. Coloca el caracter nulo. Nota: no comprueba la longitud del array cuando lo escribe. int puts(const char *cad) {stdio.h} muestra en pantalla la cadena pasada como argumento, y a continuacion un salto de linea. Devuelve un valor no negativo si lo hace con exito y EOF si ocurre algun error. Nota: reconoce codigos de barra invertida ENTRADA/SALIDA FORMATEADA int printf(const char *cadena_formato,...) {stdio.h} (p295) el argumento cadena_formato especifica como se visualizaran todos los siguientes argumentos mediante codigos de formato. Nota: Debe haber el mismo numero de codigos de formato que de argumento detras de cadena_formato. Nota2: en cadena_formato pueden aparecer mas caracteres ademas de los codigos de formato. int scanf(const char*cadena_formato,dir...){stdio.h} (p201)Sirve para leer datos formateados. Cadena formato translada los datos leidos a su formato de almacenamiento. La funcion devuelve el numero de campos que constituyen la entrada y EOF si ocurre un error. Nota: se debe pasar las direcciones (&var) de todas las variables que se utilizan para recibir valores. es decir que todos los argumentos seran punteros a variables utilizadas como argumentos. CODIGOS DE FORMATO: (p296) %c caracter %s cadena %e,%E coma flotante en notacion cientifica (X,dddddE+/-yy) %f coma flotante %o octal sin signo %g,%G utiliza %e ó %f ó %E ó %F (el mas corto) %u decimal sin signo %p puntero %x,%X hexadecimales sin signo %d,%i decimal con signo [ ] examina un conjunto de caracteres permitidos (scanf) MODIFICADORES: %-n1.n2formato n1 longitud minima del campo 0n1 rellena con ceros o con blancos .n2 precision (nº de decimales) longitud maxima - justifica a la izquierda (derecha por omision) SISTEMA DE ARCHIVOS DE STANDARD ANSI DE C Las siguientes funciones utilizan stdio.h donde se definen tres tipos: size_t, fpos_t enteros sin signo, y FILE *p puntero a archivo, (puntero a informacion de un archivo como nombre, estado, posicion...). Tambien se definen macros como EOF, NULL (p209) APERTURA FILE *fopen(const char *nombre_archivo, const *char modo) abre devuelve un puntero a ese flujo. Modo es la forma en la r abre para lectura (texto) b binario w crea para escritura(texto) [+] + lectura/escritura a añade informacion (texto) t texto ESCRITURA DE UN CARACTER int putc(int c,FILE *pa) int fputc(int c,FILE *pa) un flujo para utilizarlo con un archivo y que se abre el archivo (p211) | rt+ abrir texto lectura | wt+ crear texto lectura/escritura | at+ abrir o crear texto lectura/escritur escriben caracteres en un archivo (previamente abierto). si se realiza con exito devuelven c, en caso contrario EOF. (ambas funciones son iguales) LECTURA DE UN CARACTER int getc(FILE *pa) (iguales) int fgetc(FILE *pa) CIERRE int fclose(FILE *pa) cierra un archivo y devuelve 0 si lo ha hecho y EOF si ha ocurrido algun error. OTRAS int feof(FILE *pa) sirve para saber si es final de fichero cuando se leen datos en modo binario, devuelve distinto de 0 di EOF y 0 si no. Nota: puede leerse un valor entero que coincida con EOF sin ser final de fichero. int putw(int c,FILE *pa) ambas funciones son iguales que getc() y putc() pero con bufer de linea, y leen int getw(FILE *pa) y escriben enteros. size_t fread(void *bufer,size_t num_bytes,size_t cantidad.FILE *pa) bufer es un puntero a la zona de memoria que contiene los datos leidos del archivo. size_t fwrite(const void *bufer,size_t num_bytes,size_t cantidad.FILE *pa) bufer es un puntero a la zona de memoria que contiene los datos que se van a escribir. Nota: la longitud de cada elemento se determina con num_bytes, y la cantidad de elementos con cantidad. Ambas funciones devuelven el numero de elementos leidos o escritos. Nota: pueden leer y escribir cualquier tipo de informacion sienpre que el archivo se haya abierto en modo binario. int fseek(FILE *pa,long num_bytes,int origen) permite el acceso directo al bufer. num_bytes es el numero de bytes desde origen, y origen puede ser 0 principio del archivo, 1 posicion actual y 2 fin de archivo. fseek() devuelve 0 si se ha realizado con exito. int fprintf(FILE *pa,const char *cadena_formato,...) funcionan igual que printf y scanf pero sobre un int fscanf(FILE *pa,const char *cadena_formato,...) archivo. int remove(const char *nombre_archivo) borra un fichero y devuelve 0 si se ha realizado con exito. Borland C CARLOS ROA ROMERO CADENAS: int fputs(const char *cad,FILE *pa) es equivalente a puts pero escribe la cadena en el flujo especificado. char *fgets(char *cad,int longitud,FILE *pa) lee una cadena hasta que se encuentra un caracter de nueva linea o se ha leido longitud-1 caracteres. • CAPITULO 9 EL PREPROCESADOR Y LOS COMENTARIOS #define nombre_macro cadena Sustituye en el fuente, cade vez que aparece nombre_macro por la cadena. #undef nombre_macro Anula la definicion del nombre_macro. #error cadena Obliga al compilador a que detenga la compilacion cuando encuentra esto, apareciendo cadena en el error. #include <nombre_archivo> o bien “nombre_archivo” Indica al compilador que incluya otro archivo fuente adicional. #if condicion constante Compila el codigo si la condicion constante se cumple. codigo #else codigo #endif #elif Igual que else if /* */ comentarios, hace que un fragmento no sea reconocido por el compilador. // comentario para la linea en curso #ifdef nombre_macro Si esta definida la macro... o bien #if defined codigo #endif #ifndef Si no esta definida la macro, o bien #if ¡defined