2009-07-05 6 views
23

Existe-t-il un tableau irrégulier en C ou C++?Est-ce que les tableaux dentelés existent en C/C++?

Quand je compile ceci:

int jagged[][] = { {0,1}, {1,2,3} }; 

Je reçois cette erreur:

error: declaration of `jagged' as multidimensional array must have bounds for all dimensions except the first

Répondre

14

Si vous voulez juste l'initialiser, vous pouvez dire:

int jagged[][3] = { {0,1}, {1,2,3} }; 

mais le tableau aura toujours la forme [2] [3]. Si vous voulez un vrai tableau déchiqueté, vous devrez le créer dynamiquement. Et si vous faites cela, et que vous utilisez C++, vous devez utiliser un std::vector, comme le suggère friol.

12

Dans C++ (non compilé, et probablement il y a une syntaxe plus compacte):

std::vector<std::vector<int> > myArray; 

myArray.push_back(std::vector<int>()); 
myArray.push_back(std::vector<int>()); 

myArray[0].push_back(0); 
myArray[0].push_back(1); 

myArray[1].push_back(1); 
myArray[1].push_back(2); 
myArray[1].push_back(3); 

Vous pouvez maintenant accéder aux éléments avec, par exemple, myArray [0] [0], etc.

+1

Euh vous poussez un pointeur dans un vecteur qui ne contient pas de pointeurs ... – Goz

21

Dans CI utiliserait un tableau de pointeurs.

Par exemple:

int *jagged[5]; 

jagged[0] = malloc(sizeof(int) * 10); 
jagged[1] = malloc(sizeof(int) * 3); 

etc etc

+0

Dans cet exemple, quelle est la bonne façon de libérer la mémoire? – papgeo

15

Il y a un tas de façons de le faire. Voici une autre façon:

int jagged_row0[] = {0,1}; 
int jagged_row1[] = {1,2,3}; 
int *jagged[] = { jagged_row0, jagged_row1 }; 
+3

+1. C'est là que les littéraux composés de C99 montrent: 'int * jagged [] = {(int []) {0,1}, (int []) {1, 2, 3}};' n'est-ce pas aussi bien? –

+2

Le problème avec cette solution est que les sous-matrices se désintègrent immédiatement en pointeurs, donc vous n'avez aucun moyen de dire quelles sont les limites. –

+0

@Neil, je n'y ai pas pensé du tout. Bien sûr, vous avez raison. Bon point :) –

2

En C99 vous pouvez effectuer les opérations suivantes:

int jagged_row0[] = {0,1}; 
int jagged_row1[] = {1,2,3}; 

int (*jagged[])[] = { &jagged_row0, &jagged_row1 }; // note the ampersand 

// also since compound literals are lvalues ... 
int (*jagged2[])[] = { &(int[]){0,1}, &(int[]){1,2,3} }; 

La seule différence ici (par rapport à la réponse de la raiponce) est que les tableaux ne se décomposent pas aux pointeurs et on a pour accéder aux tableaux individuels via un autre niveau d'indirection - (par exemple *jagged[0] - et la taille de chaque ligne doit être enregistrée - ie sizeof(*jagged[0]) ne compilera pas) - mais ils sont irréguliers - apparaissant à l'os;)

+0

Je pensais que vous ne pouviez pas faire des tableaux de type incomplet ... oh, vous faites un tableau de pointeurs vers un type incomplet, c'est possible mais cela ne vous achète rien par rapport à la réponse de rampion. –

3

raison pour laquelle vous avez l'erreur est que vous m préciser les limites pour au moins la dimension extérieure; à savoir

int jagged[][3] = {{0,1},{1,2,3}}; 

On ne peut pas en dents de scie [0] un groupement 2-élément d'int et déchiquetée [1] un groupement 3-élément d'int; un tableau d'éléments N est un type différent d'un tableau d'éléments M (où N! = M), et tous les éléments d'un tableau doivent être du même type.

Ce que vous peut faire est ce que les autres ont suggéré ci-dessus et créer jagged comme un tableau de pointeurs à int; de cette façon chaque élément peut pointer vers entier matrices de tailles différentes:

int row0[] = {0,1}; 
int row1[] = {1,2,3}; 
int *jagged[] = {row0, row1}; 

Même si row0 et row1 existe différents types (2-éléments par rapport à matrices 3 d'éléments d'int), dans le contexte de l'initialiseur ils sont les deux sont implicitement convertis au même type (int *).

1

Avec C++ 11 listes de initialiseur this peut être écrit de manière plus compacte:

#include <vector> 
#include <iostream> 

int main() { 
    // declare and initialize array 
    std::vector<std::vector<int>> arr = {{1,2,3}, {4,5}}; 
    // print content of array 
    for (auto row : arr) { 
     for (auto col : row) 
      std::cout << col << " "; 
     std::cout << "\n"; 
    } 
} 

La sortie est:

$ g++ test.cc -std=c++11 && ./a.out 
1 2 3 
4 5 

Pour référence:

Questions connexes