C++: la taille de la ligne d'un tableau multidimensionnel passés à une fonction
Je suis en train d'écrire une fonction qui permet d'imprimer le contenu d'un tableau multidimensionnel. Je sais que la taille des colonnes, mais pas la taille des lignes.
EDIT: Depuis que je ne l'ai pas claires, les tableaux passés à cette fonction ne sont PAS alloués dynamiquement. Les tailles sont connus au moment de la compilation.
Je suis en train de tester à l'aide d'une 3x2 tableau. Ici est la fonction qu'il représente:
void printArrays(int array1[][2], int array2[][2]) {
for (int i = 0; i < 3; i++) {
for (int j = 0; j < 2; j++) {
cout << "\narray1[" << i << "][" << j << "] = "
<< setfill('0') << setw(2) << array1[i][j]
<< "\tarray2[" << i << "][" << j << "] = "
<< setfill('0') << setw(2) << array2[i][j];
}
}
}
Évidemment, cela ne fonctionne que si je sais que la taille du "je" est de 3 (il est dans ce cas). Idéalement, toutefois, je voudrais que la fonction de travail quelle que soit la taille de la première dimension.
Je pensais que je serais en mesure de le faire à l'aide de la sizeof() de la fonction, par exemple,
int size = sizeof(array1);
... et de faire quelques calculs à partir de là.
Voici l'étrange partie. Si j'utilise le sizeof() la fonction à l'intérieur de la matrice, il renvoie une valeur de 4. Je peux utiliser la notation pointeur à déréférencer le tableau:
int size = sizeof(*array1);
... mais en fait, cela renvoie une valeur de 8. C'est étrange, parce que la taille totale devrait être de lignes (= 3) * colonnes(= 2) * sizeof(int)(= 4), ou 24. Et, en effet, c'est le résultat, quand j'ai utiliser sizeof(*tableau array1) à l'extérieur de la fonction.
Personne ne sait ce qui se passe ici? Plus important encore, quelqu'un aurait-il une solution?
OriginalL'auteur Karl Giesing | 2011-08-04
Vous devez vous connecter pour publier un commentaire.
La réponse est que vous ne pouvez pas faire cela. Vous devez passer le nombre de lignes comme argument à la fonction, ou l'utilisation d'un conteneur STL comme
std::vector
oustd::array
.sizeof
est calculé au moment de la compilation;sizeof
n'est jamais utile dans la détermination de la dynamique de la taille d'objets en C/C++. Vous (vous-même, le programmeur) peut toujours calculersizeof(x)
seulement de regarder le code et les fichiers d'en-tête depuissizeof
compte le nombre d'octets utilisés pour représenter l'objet.sizeof(*array1)
sera toujours 8 depuisarray1[i]
est un tableau de deuxints
et4==sizeof(int)
. Lorsque vous déclarezint array1[][2]
c'est l'équivalent deint *array1[2]
. C'est,array1
est un pointeur sur des tableaux de deux nombres entiers.sizeof(array1)
est donc 4 octets, depuis qu'il en prend 4 octets sur votre machine pour représenter un pointeur.Soyez prudent lorsque vous dites "la mémoire allouée." sizeof ne sait rien sur l'allocation dynamique de la mémoire sur le tas, seulement de la pile et de l'objet global de l'allocation, qui est statique. Le type de
*array1
est un tableau d'entiers avec exactement deux éléments.array1[i]
est équivalent à*(array1+i)
.Des excuses. Je devrais l'avoir clairement expliqué dans le post original, mais la taille du tableau n'est PAS allouée dynamiquement. La fonction est simplement nécessaire pour manipuler des tableaux de tailles différentes, même si ces montants sont déterminés au moment de la compilation.
OriginalL'auteur Chris
Vous pouvez accomplir cela, à un certain degré, en utilisant basées sur des modèles de fonctions. Les mises en garde sont:
Je suis de travail forme le code sur ce blog par Kevin Heifner.
OriginalL'auteur Conspicuous Compiler
Vous pouvez obtenir la taille de deux tableaux avec quelques modèles de la magie:
Cela ne fonctionne que pour les tableaux dont les limites sont connues au moment de la compilation et non pas pour des tableaux alloués dynamiquement.
Dans tous les cas: Vous devez utiliser
std::vector
ouboost::multiarray
.Woah, il y, Ed, peu rude. Nous ne savons pas si les limites sont totalement inconnues. Il est possible que cela soit une fonction de la bibliothèque de l'OP est de construire et les modèles appropriés peuvent être inclus dans un fichier d'en-tête. Laissons OP commentaire sur la pertinence de la réponse pour son usage particulier. Si rien d'autre, instructif réponses peuvent être utiles pour d'autres lecteurs.
En fait, la taille de la matrice qui allait être connu au moment de la compilation (dans ce cas); il est destiné à être une fonction qui permet d'imprimer de taille différente (mais connu) des tableaux.
Mon spidey sens m'a dit cela.
OriginalL'auteur pmr
La taille est de 8 à l'extérieur de la fonction, car vous êtes un déréférencement le premier tableau, qui vous donne la taille de la colonne (2) fois la taille d'un
int
(4). Si vous vouliez 24, vous feriezsizeof(array)
(en dehors de la fonction). La réponse est 4 à l'intérieur de la fonction, car il traite lesarray
comme un pointeur, dont la taille est de 4 octets.Cependant, fiable pour obtenir la taille des tableaux qui ont été transférés à des fonctions, soit vous devez passer la taille ou utiliser quelque chose comme
vector
.OriginalL'auteur Seth Carnegie
Un moyen très simple de le faire, sans avoir besoin de vecteurs, des modèles, des classes, ou de passer la taille du tableau, c'est d'avoir une dernière ligne de données qui contient quelque chose d'unique comme dans l'exemple suivant, où la valeur -1 est utilisée dans la dernière ligne, première colonne:
Puis il suffit de sortir de la boucle(s) quand vous atteindrez la valeur unique:
OriginalL'auteur Captain Fantastic
Simplement une meilleure utilisation des tableaux!
Ce que je veux dire par là c'est que vous pouvez faire votre propre tableau de la classe qui encapsule un tableau, ou utiliser des bibliothèques communes avec de tels cours (p. ex. coup de pouce). C'est beaucoup plus fiable, et est probablement plus facile de raisonner sur que straight-up C++ tableaux.
Une raison pour cela est si vous écrivez la fonction
vous n'avez pas autant de garanties sur le tableau que vous pourriez le penser. Par exemple, il est pas garanti que la seconde dimension de la matrice est de deux éléments de large (j'ai peut-être tort sur ce point, que je n'ai pas les références sous la main, mais je suis plutôt confiant à ce sujet). C'est parce que la réalité de la signature de la fonction est
C'est parce que les tableaux de dégénérer à des pointeurs lorsque utilisé dans les déclarations de fonction (qui est pourquoi vous êtes
sizeof(array)
renvoie 4, depuis le 4 octets est de la taille d'un pointeur de type de votre machine). Aussi, vous clairement n'avons aucune garantie sur la taille de la première dimension, donc en supposant qu'il va être 3 est dangereux, et peut-être le résultat de la confusion des bugs dans l'avenir.C'est là une coutume
array
classe serait génial, surtout si elle était basée sur des modèles. Par exemple, un tableau à deux dimensions de la classe peut être déclarée commeEn utilisant une telle approche permet de maintenir tous les informations sur le tableau dans tout situation, par exemple en
Maintenant, vous pouvez décider de la taille de chaque dimension dans le tableau.
Un avantage supplémentaire est que vous pouvez ajouter de la vérification de limites à votre
Array2D
classe en C++ tableau ne sont pas. E. g. dans une 3x2 tableau, vous êtes en mesure d'accéder à la quatrième élément de la première ligne, même si elle n'est pas sur le plan conceptuel valide. Telle une source commune de bugs peuvent facilement être éliminé par l'utilisation d'un tableau de classe comme Array2D.Il y a quelques inconvénients, ce qui est normal lors de l'utilisation de modèles. Le grand est que, en raison de la façon dont les modèles sont instanciés, vous devez définir toutes basées sur des modèles de classes dans des fichiers d'en-tête, pas dans les fichiers sources distincts (techniquement, vous pouvez utiliser le bouton "exporter" mot clé pour faire diviser la classe comme à la normale, mais cela a un support limité sur les principaux compilateurs).
Comme une dernière remarque (si vous êtes intéressés, comme je le suis), la situation devient encore mieux dans C++0x (bientôt!) avec l'avènement de variadic templates:
Maintenant tous les types de tableau peut être défini par un seul modèle de classe. Jamais été aussi facile.
OriginalL'auteur Ken Wayne VanderLinde