Est-ce que quelqu'un sait comment puis-je utiliser des tableaux multi-dimensionnels à l'aide de C? Est-ce possible?
Merci beaucoup...
Est-ce que quelqu'un sait comment puis-je utiliser des tableaux multi-dimensionnels à l'aide de C? Est-ce possible?
Merci beaucoup...
Depuis C99, 13 ans maintenant, C a 2D tableaux avec des dynamiques de limites. Si vous voulez éviter qu'une telle bête sont allouées sur la pile (qui doit), vous pouvez attribuer facilement d'un seul coup comme suit
double (*A)[n] = malloc(sizeof(double[n][n]));
et c'est tout. Vous pouvez facilement l'utiliser comme vous sont utilisés pour la 2D tableaux avec quelque chose comme A[i][j]
. Et n'oubliez pas qu'un à la fin
free(A);
Randy Meyers a écrit une série d'articles expliquant à longueur variable tableaux (Blaise).
Avec l'allocation dynamique, à l'aide de malloc:
int** x;
x = (int**)malloc(dimension1_max * sizeof(int*));
for (int i = 0; i < dimension1_max; i++) {
x[i] = (int*)malloc(dimension2_max * sizeof(int));
}
[...]
for (int i = 0; i < dimension1_max; i++) {
free(x[i]);
}
free(x);
Il alloue un tableau 2D de taille dimension1_max
* dimension2_max
. Ainsi, par exemple, si vous voulez un 640*480 array (f.e. les pixels d'une image), utilisez dimension1_max
= 640, dimension2_max
= 480. Vous pouvez ensuite accéder au tableau à l'aide d' x[d1][d2]
où d1
= 0..639, d2
= 0..479.
Mais une recherche sur ou google révèle également d'autres possibilités, par exemple dans cette SORTE de question
Notez que votre tableau ne sera pas affecter une région contiguë de la mémoire (640*480 octets) dans ce cas, qui pourrait donner des problèmes avec les fonctions qu'assument cette. Donc, pour obtenir la matrice de satisfaire à la condition, remplacer le malloc bloc ci-dessus avec ceci:
int** x;
int* temp;
x = (int**)malloc(dimension1_max * sizeof(int*));
temp = (int*)malloc(dimension1_max * dimension2_max * sizeof(int));
for (int i = 0; i < dimension1_max; i++) {
x[i] = temp + (i * dimension2_max);
}
Les tableaux en c sont déclarées et accessible à l'aide de l' []
de l'opérateur. De sorte que
int ary1[5];
déclare un tableau de 5 entiers. Les éléments sont numérotés à partir de zéro, de sorte ary1[0]
est le premier élément, et ary1[4]
est le dernier élément. Note1: Il n'y a pas d'initialisation par défaut, de sorte que la mémoire occupée par le tableau peut initialement contenir quelque chose. Note2: ary1[5]
accède à la mémoire dans un état indéfini (qui peuvent même ne pas être accessibles pour vous), afin de ne pas le faire!
Multi-dimensions des tableaux sont mis en œuvre comme un tableau de tableaux (de tableaux (de ... ) ). Donc
float ary2[3][5];
déclare un tableau de 3 tableaux unidimensionnels de 5 nombres à virgule flottante chaque. Maintenant, ary2[0][0]
est le premier élément du premier tableau, ary2[0][4]
est le dernier élément de la première pile, et ary2[2][4]
est le dernier élément de la dernière rangée. Le '89 norme exige que ces données soient contigus (sec. A8.6.2 sur la page 216 de mon K&R 2e. ed.) mais semble être agnostique sur le rembourrage.
Si vous ne connaissez pas la taille du tableau au moment de la compilation, vous aurez envie d'allouer dynamiquement de la matrice. Il est tentant d'essayer
double *buf3;
buf3 = malloc(3*5*sizeof(double));
/* error checking goes here */
qui devrait fonctionner si le compilateur n'est pas pavé que de l'allocation (bâton de l'espace supplémentaire entre les tableaux unidimensionnels). Il pourrait être plus sûr de aller avec:
double *buf4;
buf4 = malloc(sizeof(double[3][5]));
/* error checking */
mais de toute façon, l'astuce consiste à déréférencement du temps. Vous ne pouvez pas écrire buf[i][j]
car buf
a le mauvais type. Et vous ne pouvez pas utiliser
double **hdl4 = (double**)buf;
hdl4[2][3] = 0; /* Wrong! */
parce que le compilateur s'attend hdl4
être l'adresse d'une adresse d'un double. De même, vous pouvez utiliser double incomplete_ary4[][];
parce que c'est une erreur;
Alors, que pouvez-vous faire?
Simplement calculer l'offset de mémoire pour chaque élément comme ceci:
for (i=0; i<3; ++i){
for(j=0; j<3; ++j){
buf3[i * 5 + j] = someValue(i,j); /* Don't need to worry about
padding in this case */
}
}
Définir une fonction qui prend la taille nécessaire comme argument et procéder comme normal
void dary(int x, int y){
double ary4[x][y];
ary4[2][3] = 5;
}
Réfléchissez à ceci:
double **hdl5 = malloc(3*sizeof(double*));
/* Error checking */
for (i=0; i<3; ++i){
hdl5[i] = malloc(5*sizeof(double))
/* Error checking */
}
Maintenant, hdl5
de points à un tableau de pointeurs, chacun de qui pointe vers un tableau de double. Le bit est cool c'est que vous pouvez utiliser le tableau à deux dimensions de notation pour accéder à cette structure---hdl5[0][2]
obtient au moyen de l'élément de la première ligne---mais c'est néanmoins un autre type d'objet que d'un tableau à deux dimensions déclarées par double ary[3][5];
.
Cette structure est plus souple alors un tableau à deux dimensions (parce que les lignes n'ont pas besoin d'être de la même longueur), mais l'accès sera généralement plus lent et nécessite plus de mémoire (vous avez besoin d'un endroit pour tenir l'intermédiaire de pointeurs).
Notez que puisque je n'ai pas tout de configuration des gardes que vous aurez à garder une trace de la taille de toutes les matrices de vous-même.
c fournit pas de support pour le vecteur, une matrice ou un tenseur mathématiques, vous aurez à mettre en œuvre vous-même, ou de les amener dans une bibliothèque.
La Multiplication par un scaler et de l'addition et de la soustraction de matrices de même rang sont facile: il suffit de boucler sur les éléments et effectuer l'opération que vous allez. Intérieure produits sont de même simple.
Extérieur de produits signifie plus de boucles.
Si vous connaissez le nombre de colonnes au moment de la compilation, c'est assez simple:
#define COLS ...
...
size_t rows;
// get number of rows
T (*ap)[COLS] = malloc(sizeof *ap * rows); // ap is a *pointer to an array* of T
Vous pouvez traiter l' ap
comme n'importe quel tableau 2D:
ap[i][j] = x;
Quand vous avez fini vous le désallouer comme
free(ap);
Si vous ne savez pas le nombre de colonnes au moment de la compilation, mais vous travaillez avec un compilateur C99 ou un C2011 compilateur qui prend en charge de longueur variable des tableaux, c'est encore assez simple:
size_t rows;
size_t cols;
// get rows and cols
T (*ap)[cols] = malloc(sizeof *ap * rows);
...
ap[i][j] = x;
...
free(ap);
Si vous ne savez pas le nombre de colonnes au moment de la compilation et vous travaillez avec une version de C qui ne supportent pas de longueur variable des tableaux, alors vous aurez besoin de faire quelque chose de différent. Si vous avez besoin de tous les éléments pour être affectés dans un espace contigu (comme un tableau), alors vous pouvez allouer de la mémoire comme un tableau 1D, et de calculer un 1D offset:
size_t rows, cols;
// get rows and columns
T *ap = malloc(sizeof *ap * rows * cols);
...
ap[i * rows + j] = x;
...
free(ap);
Si vous n'avez pas besoin de la mémoire pour être contiguë, vous pouvez suivre les deux étapes de la méthode de répartition:
size_t rows, cols;
// get rows and cols
T **ap = malloc(sizeof *ap * rows);
if (ap)
{
size_t i = 0;
for (i = 0; i < cols; i++)
{
ap[i] = malloc(sizeof *ap[i] * cols);
}
}
ap[i][j] = x;
Depuis que l'allocation a été un processus en deux étapes, de libération de la mémoire doit aussi être un processus en deux étapes:
for (i = 0; i < cols; i++)
free(ap[i]);
free(ap);
Malloc fera l'affaire.
int rows = 20;
int cols = 20;
int *array;
array = malloc(rows * cols * sizeof(int));
Reportez-vous à l'article ci-dessous pour obtenir de l'aide: -
http://courses.cs.vt.edu/~cs2704/spring00/mcquain/Notes/4up/Managing2DArrays.pdf
Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.