web-dev-qa-db-fra.com

Quand une fonction a un paramètre tableau de taille spécifique, pourquoi est-il remplacé par un pointeur?

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
  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?
62
CsTamas

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

void foo ( char a[100] );

Le paramètre sera ajusté pour être un pointeur, et devient ainsi:

void foo ( char * a );

Si vous voulez que le type de tableau soit préservé, vous devez transmettre 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é à l'aide des règles suivantes. Le type de chaque paramètre est déterminé à partir de ses propres déclarations et déclarateurs decl-specifier-seq. Après avoir déterminé le type de chaque paramètre, tout paramètre de type "tableau de T" ou "fonction renvoyant T" est réglé pour être "pointeur sur T" ou "pointeur sur fonction renvoyant T," ....

Pour expliquer la syntaxe:

Vérifiez la règle "droite-gauche" dans google; J'en ai trouvé une description ici .

Il serait appliqué à cet exemple approximativement comme suit:

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

Commencer à l'identifiant 'a'

'a' est un 

Déplacez-vous à droite - nous trouvons un ) donc nous inversons la direction à la recherche du (. En passant à gauche, nous passons &

'a' est une référence

Après le &, nous atteignons le ( d'ouverture. Nous inversons de nouveau et regardons à droite. Nous voyons maintenant [100]

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

Et nous inversons à nouveau la direction jusqu'à atteindre char:

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

74
Richard Corden

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 consulté boost/std::tr1::array/std::array ou std::vector

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

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

Il existe une magnifique terminologie Word en C/C++ qui est utilisée pour les tableaux statiques et les pointeurs de fonction - decay . Considérez 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
0
DaddyM