9
votes

Tableaux C ++ en tant qu'arguments de la fonction

  • Puis-je passer des tableaux pour fonctionner comme je le ferais avec des primitives telles que INT et BOOL?
  • Puis-je les transmettre par valeur?
  • Comment fonctionne la fonction de la taille de la matrice est passée?

0 commentaires

8 Réponses :


2
votes

Vous pouvez passer un std :: vecteur et un objet similaire bien conçu par la valeur (bien que cela soit plutôt rare). En règle générale, vous passez par référence ou en constante référence.

Un tableau C / C ++, comme dans xxx

est toujours transmis par référence. En outre, la fonction ne peut pas déterminer la taille réelle de l'argument transmis par l'appelant, vous devez assumer une taille (ou transmettre comme paramètre séparé).


1 commentaires

Pour être précis, la syntaxe par valeur pour les matrices décrit le tableau dans un pointeur sur le premier élément, puis transmet que le pointeur par valeur. Cela diffère de passer un tableau par référence: Void FOO (INT (& A) [10])



1
votes
  1. oui. Par exemple: void f (int A []); et l'appelez comme ceci: int myarr [taille]; f (myarr);
  2. Non, les tableaux sont automatiquement passés par référence. Vous devez envelopper votre matrice dans une structure ou une classe si vous souhaitez simuler le passage par la valeur.
  3. Ce n'est pas le cas. Vous devez transmettre la taille vous-même.

1 commentaires

Pour être précis, la syntaxe par valeur pour les matrices décrit le tableau dans un pointeur sur le premier élément, puis transmet que le pointeur par valeur. Cela diffère de passer un tableau par référence: Void FOO (int (& a) [10])



26
votes

puis-je passer des tableaux pour fonctionner comme Je ferais des primitives telles que INT et bool?

Oui, mais utilisez uniquement des pointeurs (c'est-à-dire: par référence).

Puis-je les transmettre par valeur?

Non. Vous pouvez créer des cours qui supportent cela, mais des tableaux simples ne le font pas.

Comment fonctionne la fonction de la taille de la matrice est passée?

Ce n'est pas le cas. C'est une raison d'utiliser des choses comme vecteur au lieu de t * .

clarification < p> Une fonction peut prendre une référence ou un pointeur sur un tableau d'une taille spécifique: xxx

Je suis à peu près sûr que ce n'est pas ce que l'OP cherchait, cependant.


8 commentaires

Évité parce que je tapais cette même réponse avant de devenir visible.


Les tableaux en C ++ peuvent être passés par référence auquel cas vous pouvez connaître la taille de la matrice. Bien sûr, cela ne s'applique pas aux tableaux créés au moment de l'exécution.


@Arak - Je ne sais pas ce que tu veux dire ici. Pouvez-vous ajouter un exemple à votre réponse?


@egrunin: Et il n'a pas besoin d'être modélisé: Void FOO (int (& a) [10]) recevra un tableau de 10 entièrement entiers par référence. Le problème avec des tableaux alloués dynamiquement est un peu plus complexe ... Le type de nouveau int [10] est int * , et pas int [10] < / Code>, mais vous pouvez créer dynamiquement un tableau de 10 entiers: int (* p) [10] = neuf int [1] [10]; puis appelez la fonction précédente: foo (* p) .


@Arak, @david: Je connais les permutations, n'était pas sûre de penser à la même chose. Ont annexé un exemple simple.


Votre ligne FUNC (B) compile et a un comportement non défini. p est un paramètre Pointer , pas un tableau. Le char p [13] dans la signature de Func est juste remplacé par char * p . Pour faire ce que vous voulez (et arrêtez la compilation de la ligne), vous pourriez avoir Void Func (Char (& P) [13]) , comme dit Dribesas.


@Steve - Correction. Coupure et pâte de survie.


@Steve: corrigé. Cela démontre [1] que les cas de bord prennent le plus de temps [2] pourquoi cette syntaxe est rarement rencontrée :)



14
votes

Vous pouvez passer des matrices à la manière habituelle C (des matrices décrites aux pointeurs), ou vous pouvez les transmettre par référence, mais ils ne peuvent pas être adoptés par la valeur. Pour la deuxième méthode, ils portent leur taille avec eux: xxx

la plupart du temps, en utilisant std :: vecteur ou une autre séquence dans la bibliothèque standard est tout simplement plus Élégant sauf si vous avez besoin de tableaux natifs spécifiquement.


3 commentaires

C'est à peine qu'ils portent leur taille avec eux;) La taille est disponible sous forme d'argument de modèle (ou vous pouvez avoir une version non modèles avec un const défini quelque part). Vous ne pouvez pas obtenir la taille de ARR qui est l'endroit où je pense que votre libellé actuel est un peu trompeur.


@Troubadour: En C ++, la taille ne fait pas partie de la matrice, mais une partie du type de matrice. Il n'est pas nécessaire d'ajouter un const si vous le rendez non modèles, la seule différence est qu'elle fonctionnerait dans les matrices de la taille définie dans la signature: Void FOO (INT ( & a) [3]) n'acceptera que des tableaux de 3 entiers.


@Dribeas: Je n'ai pas réalisé le peu d'exécution du nombre d'éléments corrects. C'est bien, merci de me faire savoir, mais cela ne rend toujours pas ce nombre d'éléments disponibles dans la fonction qui était mon point. En outre, je ne peux pas obtenir int n = 10; VOID FUN (INT (& ARR) [N]) {} Pour compiler. Est-ce que je fais quelque chose de mal ou sommes-nous à des fins croisées?



1
votes

Oui, vous pouvez les transmettre de la même manière que des types primitifs. Oui, vous pouvez passer de valeur si vous le souhaitez vraiment avec du code de l'emballage, mais vous ne devriez probablement pas. Il prendra la taille du prototype de fonction comme une longueur - qui peut ne pas correspondre ou non aux données entrantes - donc non, cela ne sait pas vraiment.

ou!

transmettez une référence ou une référence constante à un vecteur et soyez plus en sécurité et avoir les informations de taille à vos pointes.


0 commentaires

3
votes

Vous pouvez transmettre un tableau, mais vous devez passer la taille avec elle si vous voulez le savoir à coup sûr: xxx

sont toujours passés par référence et la fonction peut être écrite. une des deux manières: xxx

ou xxx

lorsque vous passez une matrice à une fonction la fonction d'essence reçoit une Pointeur sur ce tableau, comme on le voit dans le deuxième exemple ci-dessus. Les deux exemples accompliront la même chose.


0 commentaires

4
votes

puis-je passer des tableaux pour fonctionner comme Je ferais des primitives telles que INT et bool?

Oui, vous pouvez. Passer un nom de matrice sous forme d'argument à une fonction transmet l'adresse du premier élément.

en bref: xxx

est équivalent à xxx

Puis-je les transmettre par valeur?

Pas vraiment. La "valeur" qui est passée avec un nom de matrice est l'adresse du premier élément.

Le seul moyen de passer une copie d'une matrice de style C consiste à envelopper dans une classe ou struct qui implémente une sémantique de copie approfondie.

Comment fonctionne la fonction de la taille de la matrice est passée?

Ce n'est pas le cas, à moins que votre fonction n'entre pas dans un paramètre supplémentaire qui correspond à la taille de la matrice.


5 commentaires

RE: équivalence entre int A [] et int * b : il y a une différence, cependant: le premier formulaire ne vous permet pas de jouer avec le pointeur (par exemple, A ++ est illégal).


@RAPHAELSP, Nope Il n'y a pas de différence comme ça. Le premier formulaire autorise a ++ de même - ils sont complètement équivalents. @John, "Il n'y a aucun moyen d'accepter ou de passer une copie d'un tableau de style C" est erroné lorsque de pédancières, cependant. Si vous enveloppez le tableau dans une structure et prenez la structure par valeur, la matrice enveloppée est copiée et la fonction reçoit une copie de la matrice de style C.


@RAPHAELSP: Barre de void (int A []) {++ A; * a = 7; } compile à la fois dans g ++ et comeau.


Juste - j'ai essayé cela aussi - j'allais dire Int * const A, puis l'a essayé et a vu que vous pourriez modifier le pointeur. Je vais clarifier "aucun moyen" de quelque chose de moins absolu.


@Johannes, @Dribeas: OH WOW, je ne connaissais pas les variables de tableau et les paramètres de tableau étaient différents. Voilà pour mes connaissances infaillibles.



2
votes

Les tableaux de style C comportent très étrangement lorsqu'ils sont passés dans des fonctions. Pour les tableaux de taille fixe, je recommanderais std :: array à la place, qui peut être transmis par une valeur comme des types intégrés. Pour les tableaux de taille variable, je recommande std :: vecteur , comme suggéré dans d'autres réponses.


0 commentaires