71 votes

La taille du tableau passé en paramètre

Compte tenu du programme suivant

 #include <iostream>

using namespace std;

void foo( char a[100] )
{
  cout << "foo() " << sizeof( a ) << endl;
}

int main()
{
  char bar[100] = { 0 };
  cout << "main() " << sizeof( bar ) << endl;
  foo( bar );
  return 0;
}
 

les sorties

 main() 100
foo() 4
 

Questions:

  1. Pourquoi le tableau est-il passé en tant que pointeur sur le premier élément?
  2. Est-ce un héritage de C?
  3. Que dit la norme?
  4. Pourquoi la stricte sécurité de type du C ++ est-elle abandonnée?

88voto

Richard Corden Points 12292

Oui c'est héritée de C. La fonction:

void foo ( char a[100] );

Aura le paramètre de décroissance à un pointeur, et devient ainsi:

void foo ( char * a );

Si vous voulez que le type de pile est préservée, vous devriez passer une référence au tableau:

void foo ( char (&a)[100] );

C++ 03 8.3.5/3:

...Le type d'une fonction est déterminée selon les règles suivantes. Le type de chaque paramètre est déterminé à partir de sa propre decl-spécificateur-seq et de demande de déclaration. Après avoir déterminé le type de chaque paramètre, tout paramètre de type "tableau de T" ou "fonction de retour T" est ajusté pour être "pointeur de T" ou "pointeur de fonction de retour T, respectivement....

Pour expliquer la syntaxe:

Case à cocher pour "droite-gauche" de la règle dans google, j'ai trouvé une description de celui-ci ici.

Il serait appliqué à cet exemple approximativement comme suit:

void foo (char (&a)[100]);

Commencer à identifier un"

'a' est un

Déplacer vers la droite - nous trouver un ) si on inverse la direction de la recherche de l' (. Comme nous déplacer à gauche, nous passons &

'a' est une référence

Après l' & nous arrivons à l'ouverture ( donc on inverse à nouveau et regarder à droite. Maintenant nous voyons [100]

'a' est une référence à un tableau de 100

Et nous le sens inverse à nouveau jusqu'à ce que nous atteignons char:

'a' est une référence à un tableau de 100 caractères

16voto

sbi Points 100828

Oui. En C et C ++, vous ne pouvez pas transmettre de tableaux à des fonctions. C'est comme ça.

Pourquoi faites-vous des tableaux simples de toute façon? Avez-vous regardé boost / std::tr1::array ou std::vector ?

Notez que vous pouvez toutefois transmettre une référence à un tableau de longueur arbitraire à un modèle de fonction. Du haut de ma tête:

 template< std::size_t N >
void f(char (&arr)[N])
{
  std::cout << sizeof(arr) << '\n';
}
 

0voto

DaddyM Points 590

Il existe un mot magnifique dans la terminologie C / C ++ qui est utilisé pour les tableaux statiques et les pointeurs de fonction - decay . Considérons le code suivant:

 int intArray[] = {1, 3, 5, 7, 11}; // static array of 5 ints
//...
void f(int a[]) {
  // ...
}
// ...
f(intArray); // only pointer to the first array element is passed
int length = sizeof intArray/sizeof(int); // calculate intArray elements quantity (equals 5)
int ptrToIntSize = sizeof(*intArray); // calculate int * size on your system
 

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X