forked from sergiotarxz/Blag
Añadiendo tutorial de tipos de datos.
This commit is contained in:
parent
7e4832bcbb
commit
2ef99b5774
261
content/posts/003-tipos-de-dato.md
Normal file
261
content/posts/003-tipos-de-dato.md
Normal 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;
|
||||
}
|
||||
```
|
@ -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"
|
||||
---
|
||||
|
Loading…
Reference in New Issue
Block a user