Arrays Numéricos o Vectores en C
Un vector se considera una secuencia de datos en memoria. Todos los elementos de un array deben ser del mismo tipo y tener el mismo tipo de almacenamiento.
Declaración de Arrays Unidimensionales
Para declarar un array unidimensional, se especifica el tamaño con una expresión entera positiva entre corchetes:
Sintaxis:
tipo-de-almacenamiento tipo-dato nombre_array[expresión];
Ejemplo:
int vector[3]; //Declara un array unidimensional de 3 elementos enteros.
Referencia a Elementos de un Array
Se utiliza un índice para referenciar un elemento específico. El índice debe ser un entero positivo (constante, variable o expresión).
Inicialización de un Vector
Asignación de valores iniciales a los elementos del vector.
Ejemplos:
- Sin indicar tamaño:
int vector[]={10,20,30,40};
- Indicando tamaño:
int vector[5]={10,20,30,40,50};
- Tamaño mayor que valores asignados:
int vector[10]={10,20,30,40,50,60,70};
(Los elementos restantes se inicializan a cero).
Dirección de Comienzo de un Vector
El nombre del array y la dirección del primer elemento tienen el mismo valor (la dirección de memoria del primer elemento).
Tamaño de un Array
C asigna automáticamente el espacio necesario según el tipo de datos. Los elementos se almacenan de forma contigua en memoria.
Declaración Local y Global
Los vectores globales se inicializan a cero por defecto, los locales no.
Asignación de Valores con scanf()
Se pueden introducir valores usando scanf()
.
Inicialización con Valores Nulos
Se puede usar un bucle para asignar cero a cada elemento y evitar valores aleatorios.
Procesamiento de Arrays Unidimensionales
En C, las operaciones entre arrays se realizan elemento por elemento, generalmente dentro de un bucle.
- Recorrido: Acceder a todos los elementos para conocer su contenido.
- Búsqueda: Comprobar si un valor específico existe en el array.
- Modificación: Localizar y cambiar el valor de uno o varios elementos.
- Borrado: Eliminar un elemento y desplazar los siguientes una posición a la izquierda.
- Inserción: Añadir un elemento, localizando la posición y desplazando los elementos necesarios.
Arrays Bidimensionales (Matrices) en C
Son vectores con dos dimensiones.
Declaración e Inicialización
Se indica el nombre seguido de los índices entre corchetes. Los índices deben ser enteros positivos.
Ejemplo:
static int matriz[2][3] = {
{95, 34, 87},
{57, 35, 86}
};
Almacenamiento en Memoria
En C, las matrices se almacenan por filas. Los elementos de la última dimensión (que forman un vector) se almacenan consecutivamente.
Arrays Multidimensionales en C
Tienen tres o más dimensiones. El límite lo determina el compilador.
Sintaxis:
tipo nombre_array [exp1][exp2]...[expN];
Importante: Usan mucha memoria.
Cadenas de Caracteres en C
Un vector de caracteres, con elementos en posiciones consecutivas de memoria.
Ejemplo:
Cadena: ‘S’ ‘o’ ‘f’ ‘t’ ‘w’ ‘a’ ‘r’ ‘e’ ‘\0’
Posición: 0 1 2 3 4 5 6 7 8
El último carácter es el carácter nulo (‘\0’), que indica el final de la cadena. C lo añade automáticamente.
Declaración de una Cadena
Se usan corchetes []
después del identificador.
%s
: Especificador de formato para cadenas.%c
: Especificador de formato para caracteres individuales.
Ejemplo:
char cadena[] = "Aula";
// Reserva espacio para «Aula» y el carácter nulo.
La variable cadena
es el nombre y la dirección de memoria de la cadena. Los elementos se numeran desde 0.
Inicialización de Cadenas de Caracteres
- Asignación completa:
char cadena[] = "Software";
(Reserva espacio automáticamente, incluyendo ‘\0’). - Asignación individual:
char cadena[] = {'S', 'o', 'f', 't', 'w', 'a', 'r', 'e', '\0'};
(Se debe incluir ‘\0’). - Indicando longitud:
char cadena[4] = "Aula";
(El carácter nulo no cuenta en la longitud, se añade automáticamente). - Cadena vacía:
char cadena[0] = '\0';
Diferencia: Comillas simples (‘x’) definen un carácter, comillas dobles («x») definen una cadena (incluye ‘x’ y ‘\0’).
Entrada de Cadenas
- Usando
scanf()
:char cadena[20]; printf("Introduzca una cadena de caracteres: "); scanf("%s", cadena);
scanf()
lee hasta el primer espacio en blanco. - Usando
gets()
:char cadena[30]; printf("Escribe una cadena de caracteres: "); gets(cadena);
gets()
lee la línea completa hasta el retorno de carro.
Dirección de Comienzo de una Cadena
Al usar scanf()
, no se usa &
delante de la variable cadena porque el nombre ya representa la dirección de comienzo.
Funciones para el Manejo de Caracteres y Cadenas
Funciones de Entrada/Salida para Caracteres
getchar()
: Lee un carácter de la entrada.putchar()
: Escribe un carácter en la salida.getch()
ygetche()
: Leen un carácter del teclado sin esperar retorno de carro (getche()
muestra el carácter,getch()
no).puts()
: Escribe una cadena en la salida, incluyendo un salto de línea.
Funciones de Tratamiento de Caracteres (<ctype.h>
)
isalnum()
: Alfanumérico.isalpha()
: Alfabético.isascii()
: Carácter ASCII.iscntrl()
: Carácter de control.isprint()
: Carácter imprimible.ispunct()
: Carácter de puntuación.isspace()
: Espacio en blanco.isupper()
: Mayúscula.islower()
: Minúscula.tolower()
: Convierte a minúscula.toupper()
: Convierte a mayúscula.isxdigit()
: Dígito hexadecimal.isdigit()
: Dígito decimal.
Funciones de Conversión de Cadenas a Números
atoi()
: Cadena a entero.atof()
: Cadena a real (double
).atol()
: Cadena a entero largo.
Funciones de Manejo de Cadenas (<string.h>
)
strlen()
: Calcula la longitud (sin contar ‘\0’).strcat(str1, str2)
: Concatenastr2
al final destr1
.strncat(str1, str2, n)
: Concatena los primerosn
caracteres destr2
astr1
.strcmp(cad1, cad2)
: Compara cadenas (devuelve 0 si son iguales, >0 sicad2
precede alfabéticamente acad1
, <0 en caso contrario).strncmp(cad1, cad2, n)
: Compara los primerosn
caracteres.strcasecmp()
: Compara ignorando mayúsculas/minúsculas.strchr(cadena, caracter)
: Busca la primera ocurrencia decaracter
encadena
(devuelve un puntero oNULL
).strrchr(cadena, caracter)
: Busca la última ocurrencia.strstr(cadena, subcadena)
: Busca la primera ocurrencia desubcadena
encadena
.strpbrk()
: Busca la primera aparición de cualquier carácter de una subcadena en otra.strtod()
,strtol()
,strtoul()
: Convierten cadenas adouble
,long
, yunsigned long
, respectivamente.
Arrays Bidimensionales para Cadenas
Se pueden declarar arrays bidimensionales de caracteres para almacenar múltiples cadenas. Cada cadena se almacena en una fila.
Definición de Tipos con typedef
Permite definir un nombre (alias) para un tipo de datos existente en C.
Sintaxis:
typedef tipo nuevo_tipo;
nuevo_tipo
se puede usar como cualquier otro tipo de datos. No crea un nuevo tipo, solo un sinónimo.
Estructuras (struct
) en C
Agrupan elementos (miembros) de tipos diferentes o iguales bajo un mismo nombre.
Declaración
Se define el nombre de la estructura y sus miembros.
Sintaxis:
struct {
tipo identificador_1;
tipo identificador_2;
...
tipo identificador_N;
} identificador_de_estructura;
Operador Miembro (.
)
Se usa para acceder a los miembros individuales: variable_estructura.miembro
.
Etiqueta de la Estructura
Definir la estructura antes de main()
la hace global (una plantilla utilizable por cualquier función).
Estructuras como Tipo de Datos (typedef
)
Se puede usar typedef
para definir un nuevo tipo de datos que sea una estructura.
typedef struct {
char nombre[30];
char direccion[40];
int curso;
int edad;
} alumnos;
Asignación de Valores Iniciales a una Estructura
Solo para variables globales o estáticas. Los valores se asignan en orden, entre llaves y separados por comas.
typedef struct {
char nombre[30];
char direccion[40];
int curso;
int edad;
} alumnos;
int main() {
static alumnos alumno1 = {"Manuel", "Ronda 56", 1, 19};
static alumnos alumno2 = {"Javier", "Calatrava 35", 2, 20};
return 0;
}
Vectores de Estructuras
Cada elemento del vector es una estructura del mismo tipo.
typedef struct {
char nombre[30];
char direccion[40];
int curso;
int edad;
} alumnos;
int main() {
static alumnos vector_alumnos[tam]; // tam debe ser una constante definida
return 0;
}
Estructuras Anidadas
Una estructura puede contener otras estructuras. La estructura anidada debe definirse antes.
Vectores y Matrices dentro de Estructuras
Se pueden declarar vectores o matrices como miembros de una estructura.
Uniones (union
) en C
Similar a struct
, pero almacena diferentes tipos de datos en la *misma* zona de memoria.
Tipos Enumerados (enum
) en C
Los miembros son constantes con identificadores que tienen valores enteros asignados.
Ejemplo:
enum dias_semana {
LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO
};
Equivalente a:
const int LUNES=0;
const int MARTES=1;
...
const int DOMINGO=6;
El compilador asigna valores en progresión (0, 1, 2…).
Referencia a los Elementos
Se usa el nombre de la constante.
enum dias_semana dia;
for (dia = LUNES; dia <= DOMINGO; dia = dia + 1) {
printf("%d ", dia);
}
Asignación de Valores a Tipos Enumerados
Se pueden asignar valores enteros. El objetivo es mejorar la legibilidad y facilitar cambios.
Visualización de las Constantes
Una variable enum
es un entero. Para mostrar las cadenas, se puede usar switch()
:
enum dias_semana {LUNES, MARTES, MIERCOLES, JUEVES, VIERNES, SABADO, DOMINGO} dia;
switch(dia) {
case LUNES: printf("Lunes"); break;
case MARTES: printf("Martes"); break;
...
case DOMINGO: printf("Domingo"); break;
}
Punteros en C
Variable que contiene la dirección de memoria de otro dato (variable, elemento de array, etc.).
Dirección de Memoria
Cada posición de memoria almacena un octeto. Las direcciones se enumeran secuencialmente.
Declaración de Punteros
El nombre de la variable puntero va precedido por un asterisco (*
).
int var;
var = 47;
puntero = &var; // puntero contiene la dirección de memoria de var
*puntero; // Contiene el valor de var (47)
Inicialización de un Puntero
Es crucial dar un valor inicial (indicar a dónde apunta) antes de usarlo.
Modificación de Variables con Punteros
Se puede modificar el valor de una variable usando punteros.
Verificación de Tipos
C requiere que los punteros apunten a variables del mismo tipo.
Punteros null
y void
- Puntero nulo: No apunta a ningún dato válido (
NULL
o0
). - Puntero
void
: Apunta a cualquier tipo de dato (void *ptr;
).
#define NULL 0
char *p = NULL;
int *ptr = 0;
Punteros a Punteros
Un puntero puede apuntar a otro puntero (**
).
int var = 100;
int *pint1 = &var;
int **pint2 = &pint1;
var = 47;
*pint1 = 84; // Asigna 84 a var
**pint2 = 64; // Asigna 64 a var
Punteros y Cadenas de Caracteres
Se puede usar un puntero para acceder a los elementos de una cadena.
*pchar = cadena[0];
*(pchar + 1) = cadena[1];
*(pchar + 2) = cadena[2];
...
Punteros y Vectores Numéricos Unidimensionales
Similar a las cadenas.
vector[0] = *pint;
vector[1] = *(pint + 1);
vector[2] = *(pint + 2);
...
Arrays Bidimensionales y Punteros
Un array bidimensional se puede ver como una colección de arrays unidimensionales. Se pueden usar punteros para recorrerlo.
Arrays de Punteros
Un array multidimensional se puede expresar como un array de punteros. Los elementos son direcciones de memoria. Uso común: arrays de punteros a cadenas.
Declaración:
tipo_dato *array[expresión 1];
Punteros y Estructuras
Se usa el operador &
para obtener la dirección de una estructura.
tipo_de_dato *ptvar;
ptvar = &var; // var es una variable de tipo estructura
ptvar->miembro; // Accede a un miembro. Equivalente a var.miembro
El operador ->
tiene alta precedencia y asociatividad de izquierda a derecha. Puede combinarse con .
para acceder a submiembros.
typedef struct {
char nombre[30];
char direccion[40];
int curso;
int edad;
} alumnos;
int main() {
alumnos alumno;
alumnos *palumno;
palumno = &alumno;
printf("\nEscribe el nombre: ");
gets(palumno->nombre); // Se usa -> en lugar de . para acceder al miembro
return 0;
}
Nota: El operador flecha (->
) sustituye a *
y ()
.