J'essaie de créer un tableau avec les exigences suivantes:
[] [] code> Syntaxe li>
- stocké sur le tas li>
ul>
J'ai utilisé le code suivant pour créer un VLA qui répond à presque mes besoins, mais ce tableau est limité à la portée actuelle plutôt qu'à avoir une liaison interne. P>
int (*array_name)[columns] = malloc( sizeof(int[rows][columns]) );
3 Réponses :
Vous pouvez définir le tableau comme suit: et l'allouer comme ceci: p>
Peut-il être accédé avec [] [] code> ou nécessite-t-il des mathématiques de pointeur manuel?
@Jshorthouse Vous pouvez utiliser cette syntaxe. Ce que vous avez techniquement, c'est un tableau de int * code>, chacun desquels pointe une matrice de int code>.
Personne n'est compétent ce «double pointeur» non-sens dans le code de production. À peu près, personne n'est compétent cela dans le code personnel / débogage / code de grattage. C'est mauvais pour la performance, le gaspillage et les inutiles. Alors que le désir de OP pour la longueur variable et la liaison externe n'est pas bien satisfait par c, bon code utilise l'indexation manuelle (I • Taille + j) ou des mises (publiez un pointeur de base à l'extérieur, convertir en int (*) [Taille ] code> partout il est utilisé). Bien que OP devrait être dissuadé d'utiliser des objets définis de manière externe du tout.
Vous devez d'abord utiliser l'argument CODE> Taille de l'argument pour vous assurer que taille_t code> arithmétique.
@Ericpostpischil Je pensais que ce serait une astuce courante utilisée pour au moins accomplir une notation 2D. Pas jolie, mais ça fait ce que ça devrait.
@ROBERTSSSUPPORTSMONICACELIO: Malheureusement, le débordement de la pile, qui est un testament triste, mais je ne l'ai jamais vu utilisé dans le code de production. Il ne fait pas de quoi il devrait: le code devrait être raisonnablement efficace et "doubles pointeurs" ne le sont pas. Ils forcent les recherches de pointeur, la lunette de surveillance du processeur, interfèrent avec les modèles de cache, la mémoire de déchets et le temps de perte de temps de déchets. Il n'y a aucune raison de les utiliser pour des tableaux réguliers, sauf la paresse ou l'ignorance.
@Ericpostpischil est que vous voulez dire que vous voulez personnellement n'utiliser pas le pointeur vers des pointeurs - j'utilise ce terme pour éviter toute confusion avec double * code> - du tout (à l'exception du paramètre pour modifier un pointeur dans un appelant de une fonction appelée)?
@ROBERTSSSUPORTSMONICACELIO: J'utilise un pointeur sur un pointeur où j'ai besoin d'un pointeur sur un pointeur, comme lorsqu'une routine doit modifier un pointeur, il a donc besoin d'une référence à ce pointeur. Je n'utilise pas de pointeurs vers des pointeurs pour mettre en œuvre des tableaux en deux dimensions.
@ERICPOSTPISCHIL Bon à savoir. Merci.
@ERICPOSTPISCHIL Traitement d'un INT * code> en tant que int (*) [Taille] code> semble poisson. Donné int A [3] [3] [3] code> accéder à a [1] [3] [3] code> est un comportement indéfini car vous passez au-delà des limites de l'une des tableaux intérieurs, même si vous 're toujours à l'intérieur du plus grand tableau. Un casting comme celui-ci semble être quelque chose qu'un optimiseur agressif pouvait faire des ravages.
Non, il n'est pas possible de créer un tableau comme ça. Vous ne pouvez pas créer de VLA: S dans l'espace mondial, car les globaux sont des objets statiques et statiques doivent avoir leurs tailles définies lors de la compilation.
Ce que vous pouvez faire est d'utiliser quelque chose comme ceci: P>
int **arr;
int foo() // Or main, or any function
{
arr = malloc(sizeof(*arr) * rows);
for(int i=0; i<rows; i++)
arr[i] = malloc(sizeof(*arr[0]) * cols);
Les propriétés demandées peuvent être accomplies comme décrit ci-dessous. (Ce n'est pas une recommandation de le faire.)
Définir un pointeur de base et une taille de matrice: p> lorsque la taille de la matrice est connue, les initialisez-les: p> Définissez une macro pour servir de tableau: p> une fois que ce qui précède est terminé, le tableau peut être accédé comme myarray [i] [J] code>. p> Notez que la prise en charge de la variable de longueur de longueur est facultative dans C. GCC et Clang prennent en charge. Compte tenu de l'exemple indiqué dans la question, nous supposons que la prise en charge de la variable de longueur de longueur est disponible. P> En outre, je serais tenté d'écrire le code code> MALLOC CODE>: P> MyArrayPointer = malloc(Rows * sizeof *MyArray);
Vous ne connaissez pas les lignes lorsque les globaux sont créés, donc non.
Ceci est généralement considéré comme une conception médiocre, et vous devriez l'éviter. S'il était nécessaire, vous pouvez obtenir l'effet souhaité en définissant
int * pointeur code>, initialisationle pointeur code> en allouant la mémoire lorsque la taille est connue et définissant une macro# Définir le pointeur Array_Name ((int (*) [lignes]) code>. Cela causeraarray_name code> pour être remplacé par une conversion du pointeur code> sur le type souhaité, accessible en tant quearray_name [i] [j] code> .Les lignes code> devront également être publiées à l'extérieur.@ERICPOSTPISCHIL Quelle partie est une mauvaise conception, les exigences de la matrice elle-même ou du fait que c'est global? Je suis nouveau à c et je pense que j'ai peut-être utilisé le mauvais mot, je pense que "statique" est ce que je voulais dire. Je ne veux pas être visible pour être visible pour l'ensemble du programme, juste visible dans un fichier source afin que plusieurs fonctions puissent l'utiliser.
@Ericpostpischil Je pense que je vais aller avec la solution que vous avez décrite ici. Seriez-vous capable de l'écrire comme une réponse pour que je puisse l'accepter?
Visible à l'ensemble du programme est la mauvaise partie. Les matrices de longueur variable vont bien. Statique (liaison interne, limitée à une unité de traduction) est meilleure que celle externe. Il devrait également être évité, mais il y a des utilisations plus raisonnables de statiques que les externes. Cependant, les mêmes statiques et externes présentent les mêmes problèmes de réglage du type de la matrice de longueur variable; Vous devrez utiliser l'indexation manuelle ou la coulée.
@Ericpostpischil bien, merci pour la clarification et les conseils
@Ericpostpischil " visible pour l'ensemble du programme est la mauvaise partie. I>" - mais cela maintient toujours une exigence. Pas d'endroit pour des opinions personnelles Si votre employeur le souhaite de cette façon ou que vous devez avoir la matrice visible dans un autre TLU.
@ROBERTSSSUPPORTSMONICACELIO: Les identificateurs étant visibles pour l'ensemble du programme sont objectivement mauvais, pas d'opinion personnelle, car elle augmente manifestement l'occasion d'erreurs, ainsi que pour les conflits de noms.
@Jshnosh j'ai remarqué que vous avez réitéré la quête de "Static Global". - "Global" désigne une liaison externe (portée globale) - visible tout au long du programme, "statique" signifie qu'il dispose d'un lien interne (périmètre de fichier) - visible uniquement dans le fichier où il a été défini. Vous ne pouvez pas utiliser les deux, ils se contredisent. Aucune variable ou fonction ne peut être statique et globale en même temps. C'est pourquoi beaucoup de confusion ont également répondu à cette question. Ne pas constamment intermixer ceux-ci.
@ROBERTSSSSUPORTSMONICACELIO est "LIENTION INTERNE" Le seul moyen de faire référence à ce type de variable alors? J'ai cherché "Static Global" et a trouvé de nombreuses questions et réponses sur ce site en utilisant ce phrasé exacte, donc j'ai supposé que c'était une chose commune. Je suppose que "statique" en soi n'est pas synonyme de "liaison interne" comme des variables statiques évidemment, ne peut être déclarée que dans une certaine fonction.
De plus, d'une perspective "de la recherche", en tant que nouvel utilisateur C, je ne saurais pas de rechercher "lien interne" pour trouver cette question. Je n'étais même pas au courant de ce terme avant de poser cette question. Je pense que "statique globale" permettra à d'autres d'autres de trouver cette question, comme ce sont les termes que j'ai utilisés pour trouver des questions existantes avant de créer celui-ci.
@Jshnosh je vois maintenant ce que tu veux dire. Eh bien, allons dans la profondeur. Ce qui est appelé par "statique global" est une variable ou une fonction statique - visible au fichier - seulement mais malheureusement - et maintenant, il est défini dans un endroit où nous appelons globalement la portée (hors de toute fonction) où les variables sont généralement avoir une liaison externe. Le terme "statique global" est imphomement totalement égaré et créé uniquement dans l'ambiguïté au sens de la portée mondiale (à l'intérieur d'un fichier). Mais pour le considérer à partir d'une partie technique, vous ne pouvez pas être à la fois global et statique (local) en même temps. Cela a du sens, n'est-ce pas?
" Je suppose" statique "par lui-même n'est pas synonyme de" liaison interne "comme des variables statiques évidemment que les variables statiques ne peuvent être déclarées que dans une certaine fonction. i>" - le mot clé i> "Static code> Utilisations dans C. Persistance de la variable locale (classe de stockage) - à l'intérieur d'une fonction - ou B> Clarifiez le lien (en fonction du cas d'utilisation). C'est un peu déroutant.
Jetez un coup d'œil ici aussi bien Stackoverflow.com / QUESTIONS / 572547 / WHER-SONT-STATIQUE-MOD-IN-C
@Jshorthouse: Autant que les novices puissent rechercher "statique global" plutôt que "liaison interne", il est faux. "Global" signifie visible tout au long du programme. "statique" a plusieurs significations à la fois en tant que Word anglais et comme terme technique informatique. Principalement, cela signifie immuable, persistant ou ne doit pas être rafraîchi, et cela fait allusion au fait qu'un objet code> statique code> dans une fonction maintient sa valeur entre les appels, tandis qu'un non-
statique < / code> objet n'est pas spécifié pour maintenir sa valeur ...... L'effet secondaire du mot-clé code> statique code> en tant que visibilité uniquement dans l'unité de traduction est un accident de l'historique, une conséquence de la façon dont la langue s'est développée. Étasidons-nous une langue fraîchement avec les connaissances d'aujourd'hui, nous utiliserions différents mots-clés pour des objets à l'intérieur des fonctions qui persistent (
statique code>) et des identifiants dans des unités de traduction qui ne sont pas publiés en dehors d'eux (peut-êtreinterne code>). Le terme "liaison interne" est défini dans la norme C. Il est donc préférable de préférer à la fois à cause de cela et, car il est plus précisément descriptif de la signification.@ROBERTSSSUPPORTSMONICACELIO @ ERICPOSTPISCHIL Merci à vous deux pour vos grandes explications, je comprends clairement maintenant. Je suis déchiré car autant que la correction technique est importante, je pense aussi qu'une question débutante est inutile si elle n'est pas formulée d'une manière qu'un débutant demanderait / rechercherait. J'ai donc laissé le phrasé incorrect dans le titre, mais j'ai ajouté quelques pointeurs au terme correct dans la question elle-même, je pense que c'est un bon compromis. Merci encore à nouveau.