9
votes

Quand devons-nous passer la taille de la matrice comme paramètre

Je suis un peu confus pour passer un tableau en C / C ++. J'ai vu des cas dans lesquels la signature est comme celle-ci xxx

certains est comme celle-ci xxx

que quelqu'un pourrait élaborer quelle est la différence et quand et quand et Comment l'utiliser?


1 commentaires

8 Réponses :


2
votes

Lorsqu'un tableau est transmis en C ou C ++, seule son adresse est passée. C'est pourquoi le deuxième cas est assez courant, où le deuxième paramètre est le nombre d'éléments de la matrice. La fonction n'a aucune idée, uniquement en regardant l'adresse du tableau, combien d'éléments il est censé contenir.


0 commentaires

2
votes

Vous pouvez écrire

void f( int *arr, int size )


0 commentaires

1
votes

La première signature passe simplement la matrice sans aucun moyen de raconter la taille de la taille de la matrice et peut entraîner des problèmes avec des erreurs hors limites et / ou des défauts de sécurité. \

La deuxième signature est une version plus sécurisée car elle permet à la fonction de vérifier la taille de la matrice pour empêcher les premières réductions de versions.

Sauf si ceci est des devoirs, les matrices brutes sont un peu sorties. Utilisez STD :: Vecteur à la place. Il permet de passer le vecteur autour sans avoir à passer manuellement la taille que cela pour vous.


0 commentaires

1
votes

La taille d'un tableau n'est pas transmise avec la matrice elle-même. Par conséquent, si l'autre fonction a besoin la taille, elle l'aura comme un paramètre.

La chose est que certaines fonctions comprennent implicitement que la matrice soit d'une certaine taille. Donc, ils n'auront pas besoin de l'avoir spécifié explicitement. Par exemple, si votre fonction fonctionne sur une matrice de 3 flotteurs, vous n'avez pas besoin de l'utilisateur pour vous dire qu'il s'agit d'un tableau de 3 flotteurs. Il suffit de prendre un tableau.

et ensuite il y a ces fonctions (appelons-les "terribles" car elles sont) qui rempliront un tableau dans des données arbitraires jusqu'à un point défini par ces données. sprintf est probablement le "meilleur" exemple. Il continuera à mettre des caractères dans cette matrice jusqu'à ce qu'il soit terminé les écrire. C'est très mauvais, car il n'y a pas d'accord explicite ou implicite entre l'utilisateur et la fonction quant à la taille de ce tableau. sprintf écrira un certain nombre de caractères, mais il n'y a aucun moyen que l'utilisateur sache exactement combien d'être écrit (dans le cas général).

C'est pourquoi vous devriez NE JAMAIS UTILISER SPRINF ; Utilisez snprintf ou _snprintf , en fonction de votre compilateur.


0 commentaires

1
votes

Chaque fois que vous devez connaître la taille de la matrice, il doit être fourni. Il n'y a rien de spécial sur les deux formes de passage de la matrice elle-même; Le premier paramètre est de la même manière. La deuxième méthode fournit simplement les informations nécessaires pour connaître la taille de la matrice pendant que le premier ne le fait pas.

Parfois, le tableau lui-même détient cependant les informations sur sa taille. Dans votre premier exemple, par exemple, peut-être arr [0] est défini sur la taille de la matrice et que les données réelles commencent à arr [1] . Ou considérons le cas des chaînes C ... Vous fournissez juste un char [] , et le tableau est supposé mettre fin au premier élément égal à \ 0 . Dans votre exemple, une valeur négative peut agir comme une sentinelle similaire. Ou peut-être que la fonction ne se soucie tout simplement pas de la taille de la matrice et de supposer simplement qu'il est assez grand.

Ces méthodes sont intrinsèquement dangereuses, bien que ... il est facile d'oublier de définir arr [0] ou pour écraser accidentellement le terminateur null. Ensuite, f soudainement n'a aucun moyen de savoir combien d'espace qu'il dispose. toujours préférez fournir la taille explicitement, via un paramètre de taille tel que vous affichez, ou avec un deuxième pointeur à la fin de la matrice. Ce dernier est la méthode généralement prise par les fonctions de la bibliothèque standard en C ++. Vous avez toujours la question de fournir une taille incorrecte, ce qui est pourquoi, en C ++, il n'est pas recommandé d'utiliser un tel tableau en premier lieu ... Utilisez un conteneur réel qui gardera une trace de cette information pour vous.


0 commentaires

10
votes

Premièrement, un tableau transmis à une fonction passe en fait un pointeur sur le premier élément du tableau, par exemple, si vous avez xxx

puis, f () obtient & a [0] transmis à celui-ci. Ainsi, lors de la rédaction de vos prototypes de fonction, les éléments suivants sont équivalents: xxx

ceci signifie que la taille du tableau est perdue et f () , en général, vous ne pouvez pas déterminer la taille. (C'est la raison pour laquelle je préfère void f (int *r) formulaire sur VOID F (int Arr []) .)

Il y a deux cas où f () n'a pas besoin d'informations, et dans ces deux cas, il est correct de ne pas avoir de paramètre supplémentaire à celui-ci.

Premier, il y a une spéciale , Valeur convenue dans Art que l'appelant et f () prend pour signifier "la fin". Par exemple, on peut convenir qu'une valeur 0 signifie "fait".

puis on pourrait écrire: xxx

et définir f () quelque chose comme: xxx

évidemment, le schéma ci-dessus ne fonctionne que si l'appelant et la callee accepter une convention et le suivre. Un exemple est strallen () fonction dans la bibliothèque C. Il calcule la longueur d'une chaîne en trouvant un 0 . Si vous passez quelque chose qui n'a pas de 0 à la fin, tous les paris sont éteints et que vous êtes dans le territoire de comportement non défini.

Le second cas est lorsque vous N'a pas vraiment de tableau. Dans ce cas, f () prend un pointeur sur un objet ( int dans votre exemple). Donc: xxx

avec xxx

est bien: f () ne fonctionne pas sur un tableau quand même.


1 commentaires

Une autre situation serait si l'appelant et la callee s'accordent sur une longueur définie de la matrice, auquel cas la longueur n'aurait pas besoin d'être transmise.



0
votes

La différence est que la seconde inclut un paramètre indiquant la taille de la matrice. La conclusion logique est que si vous n'utilisez pas un tel paramètre, la fonction ne sait pas quelle est la taille de la matrice. Et cela s'avère en effet être le cas. En fait, cela ne sait pas que vous avez un tableau. En fait, vous ne devez pas avoir un tableau d'appeler la fonction.

La syntaxe de la matrice ici, sans une taille spécifiée à l'intérieur des crochets, est une fausse sortie. Le paramètre est en réalité un pointeur. Pour plus d'informations, veuillez consulter http://c-faq.com/aryptr/index.htmlle a>, en particulier section 4.


0 commentaires

1
votes

C et C ++ ne sont pas la même chose. Ils ont un peu de sous-ensemble commun, cependant. Ce que vous avez observé ici, c'est que la "première" dimension de tableau lorsqu'elle est transmise à une fonction des résultats toujours dans un pointeur étant passé. La "signature" (C n'utilise pas ce terme) d'une fonction déclarée comme xxx pré>

est toujours juste juste p> xxx pré>

c'est que c'est que Le 23 code> ci-dessus est quelque peu redondant et non utilisé par le compilateur. Moderne C (AKA C99) a une extension ici qui vous permet de déclarer que A a toujours 28 éléments: p> xxx pré>

ou que le pointeur est const code> est qualifié p> xxx pré>

Si vous ajoutez d'autres dimensions, la taille de l'image modifie la taille de la matrice est em> utilisé: p>

void toto(size_t n, size_t m, double A[n][m]);


0 commentaires