Un String, escrito como Hola, soy un string es en realidad un arreglo de caracteres. En la representación interna, el arreglo es terminado con el carácter nulo 0 (o bien '\0'); así lo sprogramas sabes cual es su final. Por lo tanto el tamaño ocupado en el almacenamiento es siempre un carácter más que el largo del string en sí.
Existe una gran diferencia entre las siguientes definiciones:
char astring [] = definitivamente soy string; /* un arreglo */
char pstring = definitivamente soy string; /* un puntero */
astring es un arreglo, del tamaño definido sólo por el mensaje y el '\0', estático e inamobible. Tal vez se puedan modificar algunos caracteres del mensaje, pero cada referencia a astring se referirá siempre a la misma dirección de memoria que tiene reservada la misma cantidad de espacio. Por otro lado pstring es un puntero, inicializado para apuntar a un arreglo de caracteres; como buen puntero uno lo puede mover a la dirección de memoria que desee, sin embargo no se pueden modificar los caracteres del string declarado estáticamente.
C posee una librería (string.h) con funciones para el tratamiento de los strings, las más comunes las veremos a continuación.
Esta función copia todos los caracteres del string fuente a la dirección de memoria destino (obviamente destino debe tener asignado un espacio en memoria donde quepa el string fuente) desde el primer carácter apuntado por destino hasta la primera aparición del carácter nulo (\0).
Implementado con arreglos se vería así:
{
int i=0;
while ((destino[i] = fuente[i]) != 0) i++;
}
Explicación:
Copia el carácter i-ésimo de destino en el espacio i-ésimo de fuente.
Mientras lo que ha copiado no sea el carácter nulo, aumenta el contador i en uno.
Por otro lado, la misma función implementada con aritmética de punteros es así:
{
while ((*destino = *fuente) !=0)
{
destino++;
fuente++;
};
};
La explicación es la misma. Ahora si quieren ver realmente si entendieron punteros, que les parece el siguiente código que hace lo mismo:
{
while (*(destino++) = *(fuente++));
};
Nota: El valor 0 es considerado como FALSO para una condición.
Esta función se utiliza para comparar dos strings, devolviendo el valor de comparar s1 y s2. Claramente si retorna 0 significa que los dos strings son iguales.
La implementación de esta función utilizando aritmética de arreglos es:
{
int i;
for (i=0; s1[i] == s2[i]; i++)
if (s1[i] == 0 && s2[i]==0) return 0;
return s1[i] - s2[i];
};
La explicación es simple:
Inicializo el contador en 0;
Comparo letra por letra los strings, si es el carácter nulo quiere decir que ambos son iguales.
Retorno la diferencia entre ellos al momento de salir del ciclo (cuando ambos caracteres son distintos).
Ahora la versión con punteros del mismo es:
{
for ( ; *s1 == *s2; s1++, s2++)
if (*s1 == 0 && *s2 == 0) return 0;
return *s1 - *s2;
}
Entrega el largo en caracteres de un string s.
Copia el string s2 al final del string s1.
Copia los primeros n caracteres de s2 a la dirección de memoria apuntada por s1.
Implementar las 3 funciones anteriores utilizando lógica de arreglos y lógica de punteros.
Por último, para leer sólo un carácter desde el teclado se utiliza la función getchar de la siguiente manera:
char c;
...
c=getchar();
Una estructura es una agrupación de un conjunto de campos. de igual o distinto tipo; su forma típica es:
struct nombre
{
tipo_1 variable_1;
tipo_2 variable_2;
...
tipo_n variable_n;
}
Los tipos utilizados pueden ser los básicos (char, int, float) o bien punteros u otras estructuras.
Ejemplo:
/* Definición de la estructura */
struct punto
{
float x;
float y;
};
/* Declaraciones de variables */
struct punto u, v;
struct punto z={1.0, -2.5};
/* Acceso a componentes */
z.x=2.0;
printf("z=(%f, %f)\n", z.x, z.y);
struct punto *p;
p=&z;
printf("%f\n", (*p).x);
printf("%f\n", p->x); /* notación alternativa más simple */
Haga un programa que reciba una palabra (string) y vea si es palíndrome (si la leen hacia adelante dice lo mismo que si la leen hacia atrás) o no.