¿Por qué el tamaño de un parámetro de matriz no es el mismo que dentro de main?

3 minutos de lectura

avatar de usuario
cris_45

¿Por qué el tamaño de una matriz enviada como parámetro no es el mismo que dentro de main?

#include <stdio.h>

void PrintSize(int p_someArray[10]);

int main () {
    int myArray[10];
    printf("%d\n", sizeof(myArray)); /* As expected, 40 */
    PrintSize(myArray);/* Prints 4, not 40 */
}

void PrintSize(int p_someArray[10]){
    printf("%d\n", sizeof(p_someArray));
}

avatar de usuario
usuario240312

Es un puntero, por eso es una implementación común pasar el tamaño de la matriz como segundo parámetro a la función.

  • ¿Cómo ayudaría esto con una pregunta C?

    – alk

    30 de diciembre de 2017 a las 18:12

No puede pasar matrices a funciones.

Si realmente desea imprimir el tamaño, puede pasar un puntero a una matriz, pero no será genérico en absoluto, ya que también debe definir el tamaño de la matriz para la función.

#include <stdio.h>

void PrintSize(int (*p_anArray)[10]);

int main(void) {
    int myArray[10];
    printf("%d\n", sizeof(myArray)); /* as expected 40 */
    PrintSize(&myArray);/* prints 40 */
}

void PrintSize(int (*p_anArray)[10]){
    printf("%d\n", (int) sizeof(*p_anArray));
}

avatar de usuario
walter

El comportamiento que encontró es en realidad una gran verruga en el lenguaje C. Cada vez que declara una función que toma un parámetro de matriz, el compilador lo ignora y cambia el parámetro a un puntero. Así que todas estas declaraciones se comportan como la primera:

void func(int *a)
void func(int a[])
void func(int a
typedef int array_plz[5];
void func(array_plz a)

a será un puntero a int en los cuatro casos. Si pasa una matriz a func, decaerá inmediatamente en un puntero a su primer elemento. (En un sistema de 64 bits, un puntero de 64 bits es el doble de grande que un int de 32 bits, por lo que su proporción de tamaño devuelve 2).

El único propósito de esta regla es mantener la compatibilidad con compiladores históricos que no permitían pasar valores agregados como argumentos de función.

Esto no significa que sea imposible pasar una matriz a una función. Puede sortear esta verruga incrustando la matriz en una estructura (este es básicamente el propósito de std::array de C++ 11):

struct array_rly {
int a[5];
};
void func(struct array_rly a)
{
printf("%zd\n", sizeof(a.a)/sizeof(a.a[0]));  /* prints 5 */
}

o pasando un puntero a la matriz:

void func(const int (*a)[5])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0]));  /* prints 5 */
}

En caso de que el tamaño de la matriz no sea una constante de tiempo de compilación, puede usar la técnica de puntero a matriz con matrices de longitud variable C99:

void func(int n, const int (*a)[n])
{
printf("%zd\n", sizeof(*a)/sizeof((*a)[0]));  /* prints n */
}

avatar de usuario
Pete Kirkham

Como han dicho otros, las matrices se descomponen en punteros a su primer elemento cuando se usan como parámetros de función. También vale la pena señalar que sizeof no evalúa la expresión y no requiere paréntesis cuando se usa con una expresión, por lo que su parámetro en realidad no se usa en absoluto, por lo que también puede escribir sizeof con el tipo en lugar del valor.

#include <stdio.h>

void PrintSize1 ( int someArray[][10] );
void PrintSize2 ( int someArray[10] );

int main ()
{
    int myArray[10];
    printf ( "%d\n", sizeof myArray ); /* as expected 40 */
    printf ( "%d\n", sizeof ( int[10] ) ); /* requires parens */
    PrintSize1 ( 0 ); /* prints 40, does not evaluate 0[0] */
    PrintSize2 ( 0 ); /* prints 40, someArray unused */
}

void PrintSize1 ( int someArray[][10] )
{
    printf ( "%d\n", sizeof someArray[0] );
}

void PrintSize2 ( int someArray[10] )
{
    printf ( "%d\n", sizeof ( int[10] ) );
}

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad