Longitud de la matriz en el argumento de la función

4 minutos de lectura

avatar de usuario
Jan Turoň

Este es un código bien conocido para calcular la longitud de la matriz en C:

sizeof(array)/sizeof(type)

Pero parece que no puedo averiguar la longitud de la matriz pasada como argumento a una función:

#include <stdio.h>

int length(const char* array[]) {
  return sizeof(array)/sizeof(char*);
}

int main() {
  const char* friends[] = { "John", "Jack", "Jim" };
  printf("%d %d", sizeof(friends)/sizeof(char*), length(friends)); // 3 1
}

Supongo que la matriz se copia por valor en el argumento de la función como puntero constante y la referencia debería resolver esto, pero esta declaración no es válida:

int length(const char**& array);

Considero que pasar la longitud de la matriz como segundo argumento es información redundante, pero ¿por qué la declaración estándar de main Me gusta esto:

int main(int argc, char** argv);

Explique si es posible averiguar la longitud de la matriz en el argumento de la función y, de ser así, ¿por qué existe la redundancia en main.


  • Las matrices son ciudadanos C de segunda clase. En la mayoría de los contextos se descomponen en un puntero a su primer elemento. Eso sucede en las llamadas a funciones (y prototipos). En tu ejemplo, el friends matriz decae a un puntero que se pasa a la función (dentro de la función sigue siendo un puntero)

    – pmg

    25 de noviembre de 2011 a las 12:23


  • func(tipo* matriz[]) == func(tipo** matriz), Información como matriz, la pila se puede perder.

    – PIXY AZUL

    25 de noviembre de 2011 a las 13:18


  • El posible duplicado está relacionado, pero no tan estrechamente relacionado como todo eso.

    –Jonathan Leffler

    3 de marzo de 2015 a las 7:40

  • Tenga en cuenta que la solución de puntero nulo no es una solución general al problema de determinar el tamaño de una matriz que se pasa a una función desde dentro de la función. De hecho, en general, no puede determinar el tamaño de una matriz que se pasa a la función desde dentro de una función y el tamaño se suele pasar como otro parámetro (considere, entre otros, fgets(), qsort(), fread(), fwrite() en la biblioteca C estándar).

    –Jonathan Leffler

    3 de marzo de 2015 a las 7:42


avatar de usuario
Será

la matriz decae a un puntero cuando se pasa.

Sección 6.4 de las Preguntas Frecuentes C cubre esto muy bien y proporciona las referencias de K&R, etc.


Aparte de eso, imagine que fuera posible que la función supiera el tamaño de la memoria asignada en un puntero. Podría llamar a la función dos o más veces, cada vez con diferentes matrices de entrada que tenían longitudes potencialmente diferentes; por lo tanto, la longitud tendría que pasarse como una variable oculta secreta de alguna manera. Y luego considere si pasó un desplazamiento a otra matriz, o una matriz asignada en el montón (malloc y todas son funciones de biblioteca, algo a lo que el compilador se vincula, en lugar de ver y razonar sobre el cuerpo de).

Se está volviendo difícil imaginar cómo podría funcionar esto sin algunos objetos de corte detrás de escena y demás, ¿verdad?


Symbian tenía un AllocSize() función que devolvió el tamaño de una asignación con malloc(); esto solo funcionó para el puntero literal devuelto por el malloc, y obtendría un galimatías o un bloqueo si le pidiera saber el tamaño de un puntero no válido o un puntero desplazado de uno.

No querrás creer que no es posible, pero realmente no lo es. La única forma de saber la longitud de algo pasado a una función es realizar un seguimiento de la longitud y pasarla como un parámetro explícito separado.

  • Lo sé, pero ¿puedo resolverlo con referencias? ¿O hay alguna otra actitud? ¡No puedo creer que no sea posible averiguar la longitud del bloque de memoria asignada pasado como puntero en un nivel tan bajo de programación!

    – Jan Turoň

    25 de noviembre de 2011 a las 12:27

avatar de usuario
Ravisankar Reddy

El mejor ejemplo está aquí

gracias #define TALLA 10

void size(int arr[SIZE])
{
    printf("size of array is:%d\n",sizeof(arr));
}

int main()
{
    int arr[SIZE];
    size(arr);
    return 0;
}

avatar de usuario
mike kwan

Como dijo @Will, el decaimiento ocurre durante el paso de parámetros. Una forma de evitarlo es pasar el número de elementos. Para agregar a esto, usted puede encontrar el _countof() macro útil: hace el equivalente de lo que has hecho;)

avatar de usuario
barís

int arsize(int st1[]) {
    int i = 0;
    for (i; !(st1[i] & (1 << 30)); i++);
    return i;
}

Esto funciona para mí 🙂

  • se necesita más descripción.

    – KARTHIKEYAN.A

    22 de octubre de 2017 a las 7:03

  • Sin saber cómo la memoria señalada por st1había sido inicializado/configurado por la persona que llamó, esta respuesta no tiene ningún sentido.

    – alk

    30 de diciembre de 2017 a las 17:49

¿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