Añadiendo tutorial de tipos de datos.

This commit is contained in:
sergiotarxz 2022-01-25 22:21:40 +01:00
parent 7e4832bcbb
commit 2ef99b5774
2 changed files with 262 additions and 3 deletions

View File

@ -0,0 +1,261 @@
---
title: "Tipos de dato."
date: 2022-01-24T20:32:57+01:00
draft: false
weight: 3
---
# Tipos de dato.
C es un lenguaje tipado, lo que implica que cada vez que quieras crear
una variable tienes que especificar su tipo de dato.
Aquí veremos unos cuantos útiles en el día a día programando en C.
## Tipos de datos básicos.
Considero tipos de datos básicos a aquellos que no se pueden usar
para crear estructuras de datos:
`int`: Almacena un número de 32 bits.
`long int`: Varía entre arquitecturas y sistemas operativos, en GNU/Linux de
64bits almacena un número de 64 bits, en GNU/Linux de 32 bits almacena un
número de 32 bits.
`long long int`: Almacena un número de 64 bits.
`unsigned int`: Almacena un número de 32 bits sin signo, lo que implica
que tiene un bit más para poder extenderse hacia el lado de los números
positivos.
`unsigned long int`: ...
`size_t`: Almacena un número tan grande como el tamaño máximo de las
estructuras de datos en el sistema operativo. (En GNU/Linux unsigned long int);
`char`: Almacena un carácter. (8 bits) Los carácteres utf-8 que conocemos pueden extenderse por más de un char de C.
## Tipos de datos compuestos.
`array`: Un array es una estructura de datos compuesta que te permite
tener varios datos del mismo tipo dentro del mismo. Ejemplo:
```c
#include <stdio.h>
int
main (int argc, char **argv) {
char hola[] = { 'h', 'o', 'l', 'a', '\0' };
printf ("%s\n", hola);
}
```
`struct`: Un struct te permite almacenar varios tipos de datos dentro
de una única variable. Ejemplo:
```c
#include <stdio.h>
struct prueba {
int numero;
char *string;
};
int
main (int argc, char **argv) {
char hola[] = { 'h', 'o', 'l', 'a', '\0' };
struct prueba prueba = {
42,
hola
};
printf ("%d %s\n", prueba.numero, prueba.string);
}
```
C nos otorga fácilidades para trabajar con structs por ejemplo si prueba fuese
un puntero `struct prueba *` podríamos acceder a los tipos de datos internos
con `prueba->numero` en lugar de tener que dereferenciar el puntero. Ejemplo:
```c
#include <stdio.h>
struct prueba {
int numero;
char *string;
};
int
main (int argc, char **argv) {
char hola[] = { 'h', 'o', 'l', 'a', '\0' };
struct prueba prueba = {
42,
hola
};
struct prueba *pruebaPtr = &prueba;
printf ("%d %s\n", (*pruebaPtr).numero, (*pruebaPtr).string);
}
```
```c
#include <stdio.h>
struct prueba {
int numero;
char *string;
};
int
main (int argc, char **argv) {
char hola[] = { 'h', 'o', 'l', 'a', '\0' };
struct prueba prueba = {
42,
hola
};
struct prueba *pruebaPtr = &prueba;
printf ("%d %s\n", pruebaPtr->numero, pruebaPtr->string);
}
```
## Punteros
Cuando un tipo de dato compuesto va a vivir más que la función es muy
conveniente que el mismo sea un puntero, veremos como alocar memoria
para un puntero y como trabajar con el. Ejemplo:
```c
#include <stdio.h>
#include <stdlib.h>
struct prueba {
int numero;
char *hola;
};
struct prueba *
create_struct_prueba_allocated (char *hola) {
struct prueba *prueba = malloc (sizeof *prueba);
prueba->numero = 42;
prueba->hola = hola;
return prueba;
}
char *
create_array_hola_allocated (size_t *hola_len) {
char hola[] = { 'h', 'o', 'l', 'a', '\0' };
size_t hola_to_return_len = sizeof hola;
char *hola_to_return = malloc (hola_to_return_len * sizeof *hola_to_return);
for (size_t i = 0; i < hola_to_return_len; i++) {
hola_to_return[i] = hola[i];
}
if (hola_len) {
*hola_len = hola_to_return_len;
}
return hola_to_return;
}
int
main (int argc, char **argv) {
size_t hola_len = 0;
char *hola = create_array_hola_allocated (&hola_len);
struct prueba *prueba = create_struct_prueba_allocated (hola);
printf ("%d %s\n", prueba->numero, prueba->hola);
free (hola);
hola = NULL;
free (prueba);
prueba = NULL;
}
```
Notas:
* `sizeof` solo se puede usar en un array en la función que ha sido creado,
por eso exportamos su tamaño como un puntero aunque en este caso no lo usemos.
* `&` Convierte una variable en un puntero.
* `*` Detras de un puntero lo dereferencia.
* `free` Para evitar malgastar memoria deallocamos la memoria tras usarla.
* `malloc` Al allocar un array multiplicamos su tamaño por el tamaño del tipo
de dato que contiene. Ejemplo:
```
char *array = malloc (42 * sizeof char);
```
O
```
char *array = malloc (42 * sizeof *array);
```
## Enums
Un enum te permite darles nombres a listas de numeros, por ejemplo:
```c
#include <stdio.h>
#include <stdlib.h>
typedef enum {
COLOR_CYAN = 1,
COLOR_VERDE = 2,
COLOR_AMARILLO = 4
} Color;
struct prueba {
int numero;
char *hola;
Color color;
};
struct prueba *
create_struct_prueba_allocated (char *hola) {
struct prueba *prueba = malloc (sizeof *prueba);
prueba->numero = 42;
prueba->hola = hola;
prueba->color = COLOR_CYAN;
return prueba;
}
char *
create_array_hola_allocated (size_t *hola_len) {
char hola[] = { 'h', 'o', 'l', 'a', '\0' };
size_t hola_to_return_len = sizeof hola;
char *hola_to_return = malloc (hola_to_return_len * sizeof *hola_to_return);
for (size_t i = 0; i < hola_to_return_len; i++) {
hola_to_return[i] = hola[i];
}
if (hola_len) {
*hola_len = hola_to_return_len;
}
return hola_to_return;
}
int
main (int argc, char **argv) {
size_t hola_len = 0;
char *hola = create_array_hola_allocated (&hola_len);
struct prueba *prueba = create_struct_prueba_allocated (hola);
printf ("%d %d %s\n", prueba->numero, prueba->color, prueba->hola);
free (hola);
hola = NULL;
free (prueba);
prueba = NULL;
}
```

View File

@ -9,7 +9,5 @@ menu:
weigth: 1
cascade:
- type: "docs"
header:
image: "images/c.png"
caption: "C programming tutorial"
social_image_path: "images/c.png"
---