Last active
December 23, 2015 22:19
-
-
Save zeehio/6702824 to your computer and use it in GitHub Desktop.
Eina per utilitzar matrius bidimensionals en C de manera senzilla. Potser a algú que comenci amb C li resulta util.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** \file crea_matrius.c | |
* \copyright No copyright reserved (consider it Public Domain or CC0 as you wish) | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
typedef double* DVector; | |
typedef DVector* DMatrix; | |
/** \fn CreateDVector | |
* \param[in] num_components Length of the vector | |
* \returns Vector of length `num_components` | |
* \author Sergio Oller <[email protected]> | |
* \brief Crea un vector de doubles | |
*/ | |
DVector CreateDVector(size_t num_components) { | |
DVector vector = NULL; | |
vector = malloc(num_components*sizeof(double)); | |
if (vector == NULL) { | |
fprintf(stderr,"Error al reservar memoria per un vector de %zu components\n", num_components); | |
exit(-1); | |
} | |
return vector; | |
} | |
/** \fn DestroyDVector | |
* \author Sergio Oller <[email protected]> | |
* \brief Allibera la memòria prèviament reservada per CreateDVector | |
*/ | |
void DestroyDVector(DVector vector) { | |
free(vector); | |
return; | |
} | |
/** \fn CreateDMatrix | |
* \param[in] num_files Número de files de la matriu a crear | |
* \param[in] num_columnes Número de columnes de la matriu a crear | |
* \returns Matriu no inicialitzada de les mides demanades | |
* \author Sergio Oller <[email protected]> | |
* \brief Crea una matriu de doubles | |
* | |
* Crea una matriu de doubles fàcil d'utilitzar. | |
* Exemple: | |
* ======== | |
* | |
* // funció per saber si un element és positiu | |
* int es_positiu(DMatrix A, size_t fila, size_t columna) { | |
* if (A[fila][columna] > 0.0) return 1; | |
* return 0; | |
* } | |
* int main() { | |
* DMatrix matriu; | |
* int i,j; | |
* size_t num_files = 30; | |
* size_t num_columnes = 50; | |
* matriu = CreateDMatrix(num_files, num_columnes); | |
* for (i=0;i<num_files;++i) { | |
* for (j=0;j<num_columnes;++j) { | |
* matriu[i][j] = 3.14159265; | |
* } | |
* } | |
* if (es_positiu(matriu,0,0)) printf("Es positiu\n"); | |
* | |
* DestroyDMatrix(matriu); | |
* return 0; | |
* } | |
* | |
* Com funciona | |
* ============= | |
* El truc està en què la matriu en sí és un vector de | |
* longitud `num_files`. Cada element d'aquest vector és un punter | |
* que *apunta* a la zona de la matriu corresponent a cada fila. | |
* | |
* | |
*/ | |
DMatrix CreateDMatrix(size_t num_files, size_t num_columnes) { | |
size_t i; | |
double *rawdata = NULL; | |
/* Reservem espai per tota la matriu */ | |
rawdata = malloc(num_files*num_columnes*sizeof(double)); | |
/* Comprovem que la reserva hagi estat un èxit (si falla, seppuku)*/ | |
if (rawdata == NULL) { | |
fprintf(stderr,"Error al reservar memoria per una matriu de (%zu,%zu)\n", num_files, num_columnes); | |
exit(-1); | |
} | |
/* Reservem un vector de vectors */ | |
DMatrix matriu_final = malloc(num_files*sizeof(DVector)); | |
if (matriu_final == NULL) { | |
fprintf(stderr,"Error al reservar memoria per una matriu de (%zu,%zu)\n", num_files, num_columnes); | |
exit(-1); | |
} | |
/* Cada punter del vector reservat apunta a una fila del bloc reservat */ | |
for (i=0;i<num_files;++i) { | |
matriu_final[i] = rawdata + i*num_columnes; | |
} | |
return matriu_final; | |
} | |
/** \fn DestroyDMatrix | |
* \author Sergio Oller <[email protected]> | |
* \brief Allibera la memòria prèviament reservada per CreateDMatrix | |
*/ | |
void DestroyDMatrix(DMatrix matriu) { | |
free(matriu[0]); /* Les dades en cru rawdata */ | |
free(matriu); /* El vector de vectors */ | |
} | |
/** \fn ObtePunterDMatrix | |
* \author Sergio Oller <[email protected]> | |
* \brief Retorna un punter de tipus double* que apunta al primer element | |
* de la matriu. | |
* | |
* Aquesta funció existeix perquè moltes subrutines escrites per | |
* molta gent defineix les matrius com un double*. | |
*/ | |
double * ObtePunterDMatrix(DMatrix matriu) { | |
return matriu[0]; | |
} | |
//L'exemple de la funció CreateDMatrix: | |
/* | |
// funció per saber si un element és positiu | |
int es_positiu(DMatrix A, size_t fila, size_t columna) { | |
if (A[fila][columna] > 0.0) return 1; | |
return 0; | |
} | |
int main() { | |
DMatrix matriu; | |
int i,j; | |
size_t num_files = 30; | |
size_t num_columnes = 50; | |
matriu = CreateDMatrix(num_files, num_columnes); | |
for (i=0;i<num_files;++i) { | |
for (j=0;j<num_columnes;++j) { | |
matriu[i][j] = 3.14159265; | |
} | |
} | |
if (es_positiu(matriu,0,0)) printf("Es positiu\n"); | |
DestroyDMatrix(matriu); | |
DVector vector; | |
size_t llarg = 200; | |
vector = CreateDVector(llarg); | |
for (i=0;i<llarg;++i) { | |
vector[i] = 3.14159265; | |
} | |
DestroyDVector(vector); | |
return 0; | |
} | |
*/ | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment