Calcule la longitud de la matriz en C usando la función

7 minutos de lectura

avatar de usuario
Cisne y

Quiero hacer una FUNCIÓN que calcule el tamaño de la matriz pasada.

Pasaré un Array como entrada y debería devolver su longitud. quiero una funcion

int ArraySize(int * Array   /* Or int Array[] */)
{
   /* Calculate Length of Array and Return it */

}

void main()
{
  int MyArray[8]={1,2,3,0,5};
  int length;

  length=ArraySize(MyArray);

  printf("Size of Array: %d",length);

}

La longitud debe ser 5, ya que contiene 5 elementos, aunque su tamaño es 8 (incluso 8 servirán, pero 5 serían excelentes)

Intenté esto:

int ArraySize(int * Array)
{

  return (sizeof(Array)/sizeof(int));

}

Esto no funcionará como “sizeof(Array)” devolverá el tamaño de Int Pointer. Esto “sizeof“La cosa funciona solo si estás en la misma función.

En realidad, volví a C después de muchos días de C#, así que no puedo recordar (y falta Array.Length())

¡Saludos!

  • tu matriz MyArray contiene 8 elementos. 5 de ellos se han inicializado explícitamente con 1, 2, 3, 0 y 5 respectivamente; los otros 3 se han inicializado implícitamente con 0.

    – pmg

    12 de noviembre de 2010 a las 9:47

  • Sí, lo sé…. ¿Pero hay algún método para obtener el conteo de 5?

    – Cisne y

    12 de noviembre de 2010 a las 9:58

avatar de usuario
DevSolar

No puede calcular el tamaño de una matriz cuando todo lo que tiene es un puntero.

La única forma de hacer que esto sea “similar a una función” es definir una macro:

#define ARRAY_SIZE( array ) ( sizeof( array ) / sizeof( array[0] ) )

Esto viene con todas las advertencias habituales de las macros, por supuesto.

Editar: (Los comentarios a continuación realmente pertenecen a la respuesta …)

  1. no poder determinar el número de elementos inicializado dentro de una matriz, a menos que primero inicialice todos los elementos a un valor “no válido” y haga el conteo de valores “válidos” manualmente. Si su matriz se ha definido con 8 elementos, para el compilador tiene 8 elementos, sin importar si inicializó solo 5 de ellos.
  2. no poder determinar el tamaño de una matriz dentro de una función a la que se ha pasado esa matriz como parámetro. No directamente, no a través de una macro, de ninguna manera. Puede solamente determinar el tamaño de una matriz en el alcance que ha sido declarado en.

La imposibilidad de determinar el tamaño de la matriz en una función llamada se puede entender una vez que te das cuenta de que sizeof() es un tiempo de compilación operador. Que podría Mira como una llamada de función en tiempo de ejecución, pero no lo es: el compilador determina el tamaño de los operandos y los inserta como constantes.

En el alcance que se declara la matriz, el compilador tiene la información de que en realidad es una matriz y cuántos elementos tiene.

En una función a la que se pasa la matriz, todo lo que ve el compilador es un puntero. (Considere que la función podría llamarse con muchos diferente arreglos, y recuerda que sizeof() es un operador de tiempo de compilación.

Puedes cambiar a C++ y usar <vector>. Puede definir un struct vector además de funciones que manejan eso, pero no es realmente cómodo:

#include <stdlib.h>

typedef struct
{
    int *  _data;
    size_t _size;
} int_vector;

int_vector * create_int_vector( size_t size )
{
    int_vector * _vec = malloc( sizeof( int_vector ) );
    if ( _vec != NULL )
    {
        _vec._size = size;
        _vec._data = (int *)malloc( size * sizeof( int ) );
    }
    return _vec;
}

void destroy_int_vector( int_vector * _vec )
{
    free( _vec->_data );
    free( _vec );
}

int main()
{
    int_vector * myVector = create_int_vector( 8 );
    if ( myVector != NULL && myVector->_data != NULL )
    {
        myVector->_data[0] = ...;
        destroy_int_vector( myVector );
    }
    else if ( myVector != NULL )
    {
        free( myVector );
    }
    return 0;
}

En pocas palabras: las matrices C son limitadas. No puede calcular su longitud en una subfunción, punto. Tienes que codificar tu camino alrededor de esa limitación, o usar un lenguaje diferente (como C++).

  • ¡Gracias! ¡Esto es bueno, pero estaría más feliz con Function!

    – Cisne y

    12 de noviembre de 2010 a las 9:08

  • @Swanand Purankar: Puedo entender eso, pero es simplemente imposible de hacer en C.

    – DevSolar

    12 de noviembre de 2010 a las 12:07

  • @Swanand Purankar: Acabo de ver su comentario debajo de su pregunta… tenga en cuenta que esta macro no le daría un 5 en su ejemplo, pero 8. No hay forma de que C sepa qué / cuántos elementos de la matriz se han asignado realmente (a menos que inserte manualmente valores especiales para elementos no inicializados y haga lo mismo conteo manual de valores no especiales) . C en sí solo puede decirle el tamaño total de la matriz.

    – DevSolar

    12 de noviembre de 2010 a las 15:21


  • @DevSolar: ¡Probé esta macro pero el problema es que no puedo usar esta macro en funciones a las que se pasa una matriz por puntero! ¿¿Alguna ayuda??

    – Cisne y

    15 de noviembre de 2010 a las 5:03

  • @DevSolar: ¡¡Gracias de nuevo!! Tengo que usar C para mi aplicación, así que como dijiste, ¡tengo que codificar mi camino alrededor de las limitaciones! ¡¡Muchas gracias!!

    – Cisne y

    15 de noviembre de 2010 a las 11:05

avatar de usuario
paxdiablo

No puede hacer esto una vez que la matriz se ha reducido a un puntero; siempre obtendrá el tamaño del puntero.

Lo que tienes que hacer es:

  • use un valor centinela si es posible, como NULL para punteros o -1 para números positivos.
  • calcularlo cuando todavía es una matriz y pasar ese tamaño a cualquier función.
  • Lo mismo que arriba pero usando magia macro funky, algo como:
    #define arrSz(a) (sizeof(a)/sizeof(*a)).
  • cree su propio tipo de datos abstractos que mantenga la longitud como un elemento en una estructura, de modo que pueda tener una forma de conseguir tu Array.length().

  • No es obligatorio pasar el puntero… Cualquier método mediante Passing Array funcionaría.

    – Cisne y

    12 de noviembre de 2010 a las 9:08

  • @SwanandPurankar: No estoy seguro de a qué te refieres exactamente, pero en C, void foo(int[] arr) y void foo(int *ptr) son uno y lo mismo. Por lo tanto, una matriz pasada a una función siempre decae a un puntero (al primer elemento de la matriz).

    – mk12

    9 de agosto de 2012 a las 20:29


Lo que pides simplemente no se puede hacer.

En tiempo de ejecución, la única información disponible para el programa sobre una matriz es la dirección de su primer elemento. Incluso el tamaño de los elementos solo se deduce del contexto de tipo en el que se utiliza la matriz.

avatar de usuario
Prasoon Saurav

En C no puede porque la matriz se descompone en un puntero (al primer elemento) cuando se pasa a una función.

Sin embargo, en C ++ puede usar la deducción de argumentos de plantilla para lograr lo mismo.

Debe pasar la longitud como un parámetro adicional (como strncpy hace) o terminar en cero la matriz (como strcpy lo hace).

Existen pequeñas variaciones de estas técnicas, como agrupar la longitud con el puntero en su propia clase, o usar un marcador diferente para la longitud de la matriz, pero estas son básicamente sus únicas opciones.

  • Pero SABES la longitud, ¡tú lo escribiste!

    – Ciego

    12 de noviembre de 2010 a las 9:12

  • Okey…. Entendí lo que esperas que pase…. ¡Pero cómo ayudaría eso, no pude entender!

    – Cisne y

    12 de noviembre de 2010 a las 9:19

avatar de usuario
Mayuresh Sawant

int getArraySize(void *x)
{
    char *p = (char *)x;
    char i = 0;
    char dynamic_char = 0xfd;
    char static_char = 0xcc;

    while(1)
    {
        if(p[i]==dynamic_char || p[i]==static_char)
            break;
        i++;
    }
    return i;
}

int _tmain(int argc, _TCHAR* argv[])
{   
    void *ptr = NULL;
    int array[]={1,2,3,4,5,6,7,8,9,0};
    char *str;
    int totalBytes;

    ptr = (char *)malloc(sizeof(int)*3);
    str = (char *)malloc(10);

    totalBytes = getArraySize(ptr);
    printf("ptr = total bytes = %d and allocated count = %d\n",totalBytes,(totalBytes/sizeof(int)));

    totalBytes = getArraySize(array);
    printf("array = total bytes = %d and allocated count = %d\n",totalBytes,(totalBytes/sizeof(int)));

    totalBytes = getArraySize(str);
    printf("str = total bytes = %d and allocated count = %d\n",totalBytes,(totalBytes/sizeof(char)));
    return 0;
}

  • Pero SABES la longitud, ¡tú lo escribiste!

    – Ciego

    12 de noviembre de 2010 a las 9:12

  • Okey…. Entendí lo que esperas que pase…. ¡Pero cómo ayudaría eso, no pude entender!

    – Cisne y

    12 de noviembre de 2010 a las 9:19

avatar de usuario
ajay kumar

Imposible. Debe pasar el tamaño de la matriz desde la función desde la que está llamando a esta función. Cuando pasa la matriz a la función, solo se pasa la dirección de inicio, no el tamaño completo, y cuando calcula el tamaño de la matriz, el compilador no sabe cuánto tamaño/memoria, el compilador ha asignado este puntero. Entonces, la llamada final es que debe pasar el tamaño de la matriz mientras llama a esa función.

¿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