11
votes

Comment obtenir de manière fiable la taille de la matrice de style C?

Comment puis-je obtenir de manière fiable une matrice de style C? La méthode souvent recommandée semble être d'utiliser taille de , mais cela ne fonctionne pas dans la fonction foo , où x est transmis dans: < Pré> xxx

réponses à Cette question recommande tailleOf mais ils ne disent pas que cela (apparemment?) Ne fonctionne pas si vous passez le tableau. Alors, dois-je utiliser une sentinelle à la place? (Je ne pense pas que les utilisateurs de ma fonction FOO puissent toujours faire confiance pour mettre une sentinelle à la fin. Bien sûr, je pourrais utiliser std :: vecteur , mais Ensuite, je ne reçois pas la belle syntaxe sténographie {1,2,3,4,5} .)


4 commentaires

Stackoverflow .Com / Questions / 1810083 / ...


Si les utilisateurs de votre fonction ne font pas ce que les documents leur disent de faire, c'est leur problème, pas le vôtre. Il est impossible d'empêcher le désemparé d'une hameçon d'une API.


x dans foo est un pointeur plutôt qu'un tableau. Voir Stackoverflow.com/questions/232691/... , Stackoverflow.com/questions/1975128/... . Aussi, DUP: Stackoverflow.com/questions/37538/...


@Neil Butterworth: C'est ce que le modificateur privé fait.


10 Réponses :


15
votes

in c graadage des paramètres en C ne sont vraiment que des pointeurs, donc Taillef () ne fonctionnera pas. Vous devez soit passer la taille en tant que autre paramètre ou utiliser une sentinelle - celle qui est le plus approprié pour votre conception.

Quelques autres options:

Quelques autres informations:

  • pour C ++, au lieu de passer un pointeur de tableau brut, vous souhaiterez peut-être que le paramètre utilise quelque chose qui envoie la matrice dans un modèle de classe qui contient une trace de la taille de la matrice et fournit des méthodes pour copier des données dans la matrice. de manière sûre. Quelque chose comme Modèle Array_Proxy de stlsoft ou Boost's Boost :: Array pourrait aider. J'ai utilisé un modèle array_proxy à un effet agréable avant. Dans la fonction Utilisant le paramètre, vous obtenez std :: vecteur comme des opérations similaires, mais l'appelant de la fonction peut utiliser un tableau C simple. Il n'y a pas de copie de la matrice - le modèle array_proxy s'occupe de l'emballage du pointeur du tableau et de la taille de la matrice presque automatiquement.

  • une macro à utiliser en C pour déterminer le nombre d'éléments dans une matrice (pour la taille de la taille de () pourrait aider - c'est-à-dire., Vous ne faites pas affaire avec un pointeur simple): Y a-t-il une norme fonctionner en C qui retournerait la longueur d'un tableau?


0 commentaires

3
votes

Vous pouvez transmettre la taille, utiliser une sentinelle ou même mieux utiliser std :: vecteur. Même si STD :: vecteur manque de listes d'initialiszer, il est toujours facile de construire un vecteur avec un ensemble d'éléments (bien que pas aussi bien) xxx pré>

La classe STD :: vecteur fait également des erreurs beaucoup plus dur, qui vaut son poids en or. Un autre bonus est que tout C ++ devrait être familier avec elle et la plupart des applications C ++ devraient utiliser un std :: vecteur plutôt qu'un tableau Cra C. P>

comme une note rapide, C ++ 0x ajoute Initialisant répertorie P>

std::vector<int> v;
v += 1, 2, 3, 4;


0 commentaires

2
votes

c ne fournit aucun support natif pour cela. Une fois qu'un tableau est passé de sa portée déclarée, sa taille est perdue.

vous peut passer la taille avec le tableau. Vous pouvez même les regrouper dans une structure si vous devez toujours garder la taille, même si vous aurez des frais généraux avec cela.


0 commentaires

3
votes

Comment de cela? ..

template <int N>
void foo(int (&x)[N]) {
    std::cerr << N;
}


1 commentaires

@Brian: Cela peut être ou non une mauvaise idée, selon le contexte. Pourquoi pensez-vous que c'est horrible? C'est une bonne idée car il ne compilera pas si vous passez un pointeur. C'est mauvais si la fonction est grande et appelée avec de nombreuses tailles de matrice différentes - elle générera un tas de fonctions. Une alternative pourrait être pour cette foo à faire demi-tour et appelez une FOO_Internal privé / interne (int * x, taille_t); Cela dépend de l'utilisation. J'ai trouvé cette technique utile avec des fonctions de chaîne qui ont tendance à trop déborder en cas d'utilisation incorrecte. Un commentaire sans explication est une idée horrible.



0
votes

Vous devez passer la taille avec le tableau, comme il est fait dans de nombreuses fonctions de bibliothèque, par exemple strncpy () , strncmp () etc. Désolé C'est juste la façon dont il fonctionne dans C: -).

Vous pouvez également déployer votre propre structure comme: xxx

et transmettez-la autour de votre code. < / p>

Bien sûr, vous pouvez toujours utiliser std :: Liste ou std :: vecteur si vous voulez être plus en C ++. < / p>


0 commentaires

5
votes

A idiom commun mentionné dans gnu libstdc ++ documentation est le longueur de fonction: xxx

Vous pouvez l'utiliser comme xxx

avertissement: cela fonctionnera uniquement lorsque le tableau n'a pas est décrit dans un pointeur .


0 commentaires

1
votes

Une expression de tableau aura son type de convertir implicitement de "réseau N-Element de T" sur "Pointeur à T" et sa valeur sera l'adresse du premier élément de la matrice, à moins que l'expression de la matrice ne soit l'opérande de Soit le taille de ou adresse des ( et ), ou si l'expression de tableau est un littéral de chaîne utilisé pour initialiser un autre tableau dans une déclaration. En bref, vous ne pouvez pas transmettre un tableau à une fonction comme tableau ; Ce que la fonction reçoit est une valeur de pointeur, pas une valeur de matrice.

Vous devez transmettre la taille de la matrice sous forme de paramètre séparé.

Depuis que vous utilisez C ++, utilisez des vecteurs (ou un autre conteneur STL approprié) au lieu de tableaux de style C. Oui, vous perdez la syntaxe de sténographie pratique, mais le compromis en vaut plus que la peine. Sérieusement.


0 commentaires

2
votes

J'accepte également que la méthode de Corwin ci-dessus est très bonne. xxx

Je ne pense pas que personne ait donné une très bonne raison pour laquelle ce n'est pas une bonne idée .
En Java, par exemple, nous pouvons écrire des choses comme: xxx

in c ++, ce serait bien au lieu de dire xxx

Nous pourrions prendre une étape plus loin et aller xxx

ou si cela provoque des problèmes que je suppose que vous pouviez écrire explicitement: xxx P> Ensuite, nous devons juste aller dans la principale: xxx

a du sens pour moi: -)


0 commentaires

-1
votes

Depuis C ++ 11, il y a un moyen très pratique: xxx


1 commentaires

Pas besoin de "+1".



1
votes

Maintenant, vous pouvez utiliser C ++ 11's étendue et Rang .

Par exemple: P>

Rank:           : 2
Size: [_here_][]: 2
Size: [][_here_]: 3
Size: [][]_here_: 0


0 commentaires