Cuando una función tiene un parámetro de matriz de tamaño específico, ¿por qué se reemplaza con un puntero?

Dado el siguiente progtwig,

#include  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; } 

salidas

 main() 100 foo() 4 
  1. ¿Por qué se pasa la matriz como un puntero al primer elemento?
  2. ¿Es un patrimonio de C?
  3. ¿Qué dice el estándar?
  4. ¿Por qué se descarta la estricta seguridad de tipo de C ++?

Sí, es heredado de C. La función:

 void foo ( char a[100] ); 

Tendrá el parámetro ajustado para ser un puntero, y así se convierte en:

 void foo ( char * a ); 

Si desea que el tipo de matriz se conserve, debe pasar una referencia a la matriz:

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

C ++ ’03 8.3.5 / 3:

… El tipo de una función se determina usando las siguientes reglas. El tipo de cada parámetro se determina a partir de su propio decl-specifier-seq y declarator. Después de determinar el tipo de cada parámetro, cualquier parámetro de tipo “array of T” o “function returning T” se ajusta para que sea “puntero a T” o “puntero a función que devuelve T”, respectivamente ….

Para explicar la syntax:

Verifique la regla “derecha-izquierda” en google; Encontré una descripción aquí .

Se aplicaría a este ejemplo aproximadamente de la siguiente manera:

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

Comience en el identificador ‘a’

‘a’ es un

Mover a la derecha – encontramos a ) así que invertimos la dirección buscando el ( . A medida que avanzamos hacia la izquierda pasamos &

‘a’ es una referencia

Después de que & llegamos a la apertura ( entonces volvemos atrás y miramos a la derecha. Ahora vemos [100]

‘a’ es una referencia a una matriz de 100

Y volvemos a invertir la dirección hasta que lleguemos a char :

‘a’ es una referencia a una matriz de 100 caracteres

Sí. En C y C ++ no puede pasar matrices a las funciones. Esa es la forma como es.

¿Por qué estás haciendo matrices simples de todos modos? ¿Has mirado en boost / std::tr1::array / std::array o std::vector ?

Sin embargo, tenga en cuenta que puede pasar una referencia a una matriz de longitud arbitraria a una plantilla de función. La parte superior de mi cabeza:

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

Hay una palabra magnífica en la terminología C / C ++ que se usa para matrices estáticas y punteros a funciones: decaimiento . Considera el siguiente código:

 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