No es un bug, es una característica no documentada

viernes, 31 de octubre de 2014

Programación. Estructuras de datos dinámicas en C (II)

0:29 Posted by Inazio , No comments
Cadenas de caracteres en C

Recordar que dijimos que una cadena de caracteres en C no es más que un vector de caracteres que guarda el caracter especial ‘\0’ en alguna de sus componentes, indicando que esa posición es en la que termina la cadena.

Podemos acceder a cada una de esas componentes como si fueran simples vectores, siempre y cuando respetemos que la cadena termine con ese caracter especial.

Las cadenas van entre comillas dobles
       char v[6]=”lunes”;
No es necesario añadir explícitamente el carácter nulo al final de las constantes de cadena, el compilador lo hace automáticamente.

Lectura de cadenas:

       char cadena[255]
       scanf(“%s”,cadena); /* No hay que usar & porque cadena ya es un puntero */

Escritura de cadenas:

       printf(“%s”,cadena);

Conversión de cadenas. stdlib.h

·         double atof(cadena) à Convierte una cadena
·         int atui (cadena) à Convierte una cadena de dígitos a internamente
·         long atol (cadena) à Convierte una cadena de texto a long int

Manipulación de cadenas. string.h

·         char *strcpy(s1,s2) à Copia la cadena s2 a s1. Devuelve s1
·         char *strncpy(s1,s2,n) à Copia si es posible n caracteres de s2 a s1. Devuelve s1.
·         char strcat(s1,s2,n) à Añade s2 a s1, machacando el valor final de s1 ‘\0’. Devuelve s1
·         char strncat(s1,s2,n) à Añade si es posible n caracteres de s2 a s1, machando el valor final de s1 ‘\0’. Devuelve s1
·         int srtomp(s1,s2) à Compara las cadenas s1 y s2. Devuelve negativo si s1<s2, cero si s1==s2 y positivo si s1>s2
·         int srtncpm(s1,s2,n) à Compara n caracteres de s2 en s1. Devuelve el número de caracteres iguales o NULL si no hay ninguno

Búsqueda en cadenas

·         Char *strchr(s1,c) à Buscar la primera aparición del carácter ‘c’ en s1. Devuelve un puntero a ese caracter en la cadena o NULL si no aparece el caracter en la cadena.
·         size_t strcspn(s1,s2) à Devuelve la longitud del segmento inicial de s1 formado por caracter no contenido en s2
·         size_t strspn(s1,s2) à Igual, pero con contenido en s2
·         char *strpbrk(s1,s2) à Localiza la primera ocurrencia en s1 de cualquier carácter s2. Si la encuentra, devuelve un puntero al caracter, y en caso contrario NULL
·         char *strrchr(s1,c) à Como strchr pero busca la última aparición del caracter
·         char *strstr(s1,s2) à Localiza la primera aparición de la cadena s2 en la cadena s1. Si encuentra, devuelve el correspondiente puntero, si no NULL
·         char *strtok(s1,s2) à Rompe s1 en segmentos según la secuencia de s2.

Caracteres

C hace normalmente un tratamiento muy sucio de los datos que almacena, mezclando representación interna y externa.

Una variable de tipo caracter almacena internamente el valor ASCII del caracter. Externamente está esperando que le introduzca exactamente ese valor.

Ejemplos
       char c=’a’; /* Valdrá el valor de ‘a’ y será tratado como entero */
       char c=47;
       char c=’\47’;
       char= a=’\t’, b=’|n’, c=’|v’;

Es al utilizar ciertas funciones de la librería para representar estos caracteres por pantalla cuando es interpretado ese valor, y se muestran los caracteres tal cual. Yo en el programa puedo usar indistintamente 65, ‘A’ o ‘\65’. Para el lenguaje de programación C todo ese tiene valor 65.

Al ser esto así, yo puedo sumar y restar enteros y caracteres entre sí, o sólo caracteres, compararlos, etc. Ejemplo, la condición para indicar si una letra es mayúscula sería:

       (letra>=’A’ && letra<=’Z’);

ctype.h

Existe un archivo de cabecera de la biblioteca estándar del lenguaje de programación c diseñado para operaciones básicas con caracteres. Contiene los prototipos de las funciones y macros para clasificar caracteres. Su uso no es necesario en absoluto ya que las cosas que hace son fácilmente programables.

Registros

Un registro es una agrupación o estructura de datos que me permite almacenar agrupados diferentes datos que pueden ser de diferentes tipos.

Cuando yo quiero guardar información sobre cualquier cosa, suelo tener que guardar informaciones de tipos muy diversos que entre todos definen como es esa cosa.

Por ejemplo, si quiero guardar información sobre diferentes coches que tengo guardados en un garaje procedentes de embargos de un banco, podría guardar modelo, marca, color, matricula, kilómetros, estado, etc.
Cada uno de estos caracteres sería de tipos diferentes, y además no existe un orden concreto en el que deban ser almacenados esos datos, aunque sí una asociación con lo que estoy guardando.

Para esto no podría utilizar un vector. Incluso en el caso de que todos fueran del mismo tipo, se refieran todos a una misma realidad y concretamente a diferentes subdatos de esa realidad, y me interesa guardar cada uno como una subcaracterística de la cosa de la que estoy guardando información.

Un claro ejemplo de esto es una fecha. Consta de día, mes y año, los tres datos son enteros, ahora bien, podría establecer limitaciones a los valores que pueden tener esos tres datos .Pero no se me ocurriría guardarlos en  un vector de tres campos, sino en un registro con tres campos que se llaman exactamente así: día, mes y año.

Al igual que con los vectores, primero hay que declarar el tipo, con los cambios que va a tener y posteriormente declarar las variable que serán de ese tipo.

Para acceder después a un campo concreto de un registro en el programa, se hará poniendo el nombre de la variable y el nombre del campo, separados por un punto.

Declaración y uso de registros

tipos
       <nombreTipo>   registros
                                               <nombreCampo1>:<tipo1>;
                                               <nombreCampo2>:<tipo2>;
                                               …
                                               <nombreCampoN>:<tipoN>;
                                   freg;

variables
       <nombreVariable1>,<nombreVariable2>:<nombreTipo>;
       <nombreVariable>:<nombreTipo>;

principio
       …
       <nombreVariable1>.<nombreCampo3>;
       …
fin

Ejemplo:

tipo
       cad20=cadena[20];
       tipoSexo(varon,hembra);
       tipoFecha=                     registro
                                                           dia 1..31;
                                                           mes 1..12;
                                                           anyo 0..3000;
                                               freg;
       tipoPersona=                  registro
                                                           nombre,apellido1,apellido2:cad[20];
                                                           sexo:tipoSexo;
                                                           fechaNacimiento:tipoFecha;
                                               freg;
       tipoComplejo1=              registro
                                                           parteReal,parteImaginaria:real;
                                               freg;
       tipoComplejo2=              registro
                                                           modulo,argumento:real;
                                               freg;

variables
            ayer,hoy:tipoFecha;
            yo,tu,el:tipoPersona;
            z:tipoComplejo1;
            w:tipoComplejo2;

principio
       …
       ayer.dia:=13;
       ayer.mes:=3;
       ayer.anyo:=1988;
       hoy.dia+1;
       el.sexo:=varon;
       el.fechaNacimiento:ayer;
       z.parteReal:=w.modulo*cos(w.argumento);
       z.parteImaginaria:=w.modulo*sin(w.argumento);

fin

0 comentarios:

Publicar un comentario