Pregunta

¿Cómo determino el tamaño de mi matriz en C?

Es decir, ¿la cantidad de elementos que puede contener la matriz?

¿Fue útil?

Solución

Resumen ejecutivo:

int a[17];
size_t n = sizeof(a)/sizeof(a[0]);

Respuesta completa:

Para determinar el tamaño de su matriz en bytes, puede usar el sizeofoperador:

int a[17];
size_t n = sizeof(a);

En mi computadora, los enteros tienen 4 bytes de longitud, por lo que n es 68.

Para determinar el número de elementos en la matriz, podemos dividir el tamaño total de la matriz por el tamaño del elemento de matriz.Podrías hacer esto con el tipo, así:

int a[17];
size_t n = sizeof(a) / sizeof(int);

y obtener la respuesta adecuada (68/4 = 17), pero si el tipo dea Cambiado, tendrías un error desagradable si olvidaste cambiar el sizeof(int) también.

Entonces el divisor preferido es sizeof(a[0]), El tamaño del elemento Zeroeth de la matriz.

int a[17];
size_t n = sizeof(a) / sizeof(a[0]);

Otra ventaja es que ahora puede parametrizar fácilmente el nombre de la matriz en una macro y obtener:

#define NELEMS(x)  (sizeof(x) / sizeof((x)[0]))

int a[17];
size_t n = NELEMS(a);

Otros consejos

El sizeof el camino es el camino correcto si y si se trata de matrices que no se reciben como parámetros.Una matriz enviada como parámetro a una función se trata como un puntero, por lo que sizeof devolverá el tamaño del puntero, en lugar del de la matriz.

Por lo tanto, este método no funciona dentro de las funciones.En su lugar, pase siempre un parámetro adicional size_t size indicando el número de elementos de la matriz.

Prueba:

#include <stdio.h>
#include <stdlib.h>

void printSizeOf(int intArray[]);
void printLength(int intArray[]);

int main(int argc, char* argv[])
{
    int array[] = { 0, 1, 2, 3, 4, 5, 6 };

    printf("sizeof of array: %d\n", (int) sizeof(array));
    printSizeOf(array);

    printf("Length of array: %d\n", (int)( sizeof(array) / sizeof(array[0]) ));
    printLength(array);
}

void printSizeOf(int intArray[])
{
    printf("sizeof of parameter: %d\n", (int) sizeof(intArray));
}

void printLength(int intArray[])
{
    printf("Length of parameter: %d\n", (int)( sizeof(intArray) / sizeof(intArray[0]) ));
}

Salida (en un sistema operativo Linux de 64 bits):

sizeof of array: 28
sizeof of parameter: 8
Length of array: 7
Length of parameter: 2

Salida (en un sistema operativo Windows de 32 bits):

sizeof of array: 28
sizeof of parameter: 4
Length of array: 7
Length of parameter: 1

Cabe resaltar que sizeof no ayuda cuando se trata de un valor de matriz que se ha descompuesto a un puntero:aunque apunta al inicio de una matriz, para el compilador es lo mismo que un puntero a un solo elemento de esa matriz.Un puntero no "recuerda" nada más sobre la matriz que se utilizó para inicializarlo.

int a[10];
int* p = a;

assert(sizeof(a) / sizeof(a[0]) == 10);
assert(sizeof(p) == sizeof(int*));
assert(sizeof(*p) == sizeof(int));

El tamaño del "truco" es la mejor manera que conozco, con un cambio pequeño pero (para mí, esto es un gran motivo de preocupación) importante en el uso de paréntesis.

Como deja claro la entrada de Wikipedia, C's sizeof no es una función;se trata de un operador.Por lo tanto, no requiere paréntesis alrededor de su argumento, a menos que el argumento sea un nombre de tipo.Esto es fácil de recordar, ya que hace que el argumento parezca una expresión convertida, que también utiliza paréntesis.

Entonces:Si tienes lo siguiente:

int myArray[10];

Puede encontrar la cantidad de elementos con un código como este:

size_t n = sizeof myArray / sizeof *myArray;

Eso, para mí, se lee mucho más fácil que la alternativa entre paréntesis.También prefiero el uso del asterisco en la parte derecha de la división, ya que es más conciso que la indexación.

Por supuesto, todo esto también es tiempo de compilación, por lo que no hay necesidad de preocuparse de que la división afecte el rendimiento del programa.Utilice este formulario siempre que pueda.

Siempre es mejor usar sizeof en un objeto real cuando tenga uno, en lugar de en un tipo, ya que entonces no necesita preocuparse por cometer un error e indicar el tipo incorrecto.

Por ejemplo, supongamos que tiene una función que genera algunos datos como un flujo de bytes, por ejemplo a través de una red.Llamemos a la función send(), y haga que tome como argumentos un puntero al objeto a enviar y el número de bytes del objeto.Entonces el prototipo queda:

void send(const void *object, size_t size);

Y luego necesitas enviar un número entero, así que lo codificas así:

int foo = 4711;
send(&foo, sizeof (int));

Ahora, has introducido una forma sutil de dispararte en el pie, especificando el tipo de foo en dos lugares.Si uno cambia pero el otro no, el código se rompe.Por eso, hazlo siempre así:

send(&foo, sizeof foo);

Ahora estás protegido.Claro, duplicas el nombre de la variable, pero eso tiene una alta probabilidad de fallar de una manera que el compilador pueda detectar, si lo cambias.

int size = (&arr)[1] - arr;

Verificar este enlace para explicación

Puede usar el operador sizeOf, pero no funcionará para las funciones porque tomará la referencia del puntero que puede hacer lo siguiente para encontrar la longitud de una matriz:

len = sizeof(arr)/sizeof(arr[0])

Código encontrado originalmente aquí:Programa C para encontrar el número de elementos en una matriz.

Si conoce el tipo de datos de la matriz, puede usar algo como:

int arr[] = {23, 12, 423, 43, 21, 43, 65, 76, 22};

int noofele = sizeof(arr)/sizeof(int);

O si no conoce el tipo de datos de la matriz, puede usar algo como:

noofele = sizeof(arr)/sizeof(arr[0]);

Nota:Esto solo funciona si la matriz no está definida en tiempo de ejecución (como malloc) y la matriz no se pasa en una función.En ambos casos, arr (nombre de la matriz) es un puntero.

la macro ARRAYELEMENTCOUNT(x) que todo el mundo está haciendo uso de las evaluaciones incorrectamente.Esto, siendo realistas, es un asunto delicado, porque no se pueden tener expresiones que resulten en un tipo 'matriz'.

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x[0]))

ARRAYELEMENTCOUNT(p + 1);

De hecho se evalúa como:

(sizeof (p + 1) / sizeof (p + 1[0]));

Mientras

/* Compile as: CL /P "macro.c" */
# define ARRAYELEMENTCOUNT(x) (sizeof (x) / sizeof (x)[0])

ARRAYELEMENTCOUNT(p + 1);

Evalúa correctamente:

(sizeof (p + 1) / sizeof (p + 1)[0]);

Esto realmente no tiene mucho que ver explícitamente con el tamaño de las matrices.Acabo de notar muchos errores por no observar realmente cómo funciona el preprocesador de C.Siempre ajustas el parámetro de macro, no puede estar involucrada una expresión.


Esto es correcto;mi ejemplo fue malo.Pero eso es exactamente lo que debería suceder.Como mencioné anteriormente p + 1 terminará como un tipo de puntero e invalidará toda la macro (como si intentara usar la macro en una función con un parámetro de puntero).

Al final del día, en este particular Por ejemplo, la falla realmente no importa (así que solo estoy haciendo perder el tiempo a todos;¡Hurra!), porque no tienes expresiones con un tipo de 'matriz'.Pero realmente creo que el punto sobre las sutilezas de la evaluación del preprocesador es importante.

Para matrices multidimensionales es un pelín más complicado.A menudo la gente define macroconstantes explícitas, es decir

#define g_rgDialogRows   2
#define g_rgDialogCols   7

static char const* g_rgDialog[g_rgDialogRows][g_rgDialogCols] =
{
    { " ",  " ",    " ",    " 494", " 210", " Generic Sample Dialog", " " },
    { " 1", " 330", " 174", " 88",  " ",    " OK",        " " },
};

Pero estas constantes también se pueden evaluar en tiempo de compilación con tamaño de:

#define rows_of_array(name)       \
    (sizeof(name   ) / sizeof(name[0][0]) / columns_of_array(name))
#define columns_of_array(name)    \
    (sizeof(name[0]) / sizeof(name[0][0]))

static char* g_rgDialog[][7] = { /* ... */ };

assert(   rows_of_array(g_rgDialog) == 2);
assert(columns_of_array(g_rgDialog) == 7);

Tenga en cuenta que este código funciona en C y C++.Para matrices con más de dos dimensiones utilice

sizeof(name[0][0][0])
sizeof(name[0][0][0][0])

etc., hasta el infinito.

Tamaño de una matriz en C:

int a[10];
size_t size_of_array = sizeof(a);      // Size of array a
int n = sizeof (a) / sizeof (a[0]);    // Number of elements in array a
size_t size_of_element = sizeof(a[0]); // Size of each element in array a                                          
                                       // Size of each element = size of type
sizeof(array) / sizeof(array[0])
#define SIZE_OF_ARRAY(_array) (sizeof(_array) / sizeof(_array[0]))

"Has introducido una forma sutil de dispararte en el pie"

Las matrices C 'nativas' no almacenan su tamaño.Por lo tanto, se recomienda guardar la longitud de la matriz en una variable/const separada y pasarla cada vez que pase la matriz, es decir:

#define MY_ARRAY_LENGTH   15
int myArray[MY_ARRAY_LENGTH];

Siempre DEBE evitar las matrices nativas (a menos que no pueda, en cuyo caso, tenga cuidado con el pie).Si estás escribiendo C++, usa el STL's contenedor 'vector'."En comparación con los arrays, ofrecen casi el mismo rendimiento", ¡y son mucho más útiles!

// vector is a template, the <int> means it is a vector of ints
vector<int> numbers;  

// push_back() puts a new value at the end (or back) of the vector
for (int i = 0; i < 10; i++)
    numbers.push_back(i);

// Determine the size of the array
cout << numbers.size();

Ver:http://www.cplusplus.com/reference/stl/vector/

@ Magnus:El estándar define sizeof como que produce el número de bytes en el objeto y que sizeof (char) es siempre uno.El número de bits en un byte es específico de la implementación.

Editar:Estándar ANSI C++ sección 5.3.3 Tamaño de:

El operador sizeof produce el número de bytes en la representación del objeto de su operando.[...] sizeof (char), sizeof (char con signo) y sizeof (char sin firmar) son 1;el resultado de sizeof aplicado a cualquier otro tipo fundamental está definido por la implementación.

Sección 1.6 El modelo de memoria C++:

La unidad de almacenamiento fundamental en el modelo de memoria C++ es el byte.Un byte es al menos lo suficientemente grande como para contener cualquier miembro del conjunto de caracteres de ejecución básico y está compuesto por una secuencia contigua de bits, cuyo número está definido por la implementación.

@Skizz:Estoy bastante seguro de que tengo razón, aunque la mejor "fuente" que puedo darte en este momento es Wikipedia, del artículo sobre sizeof:

Wikipedia está equivocada, Skizz tiene razón.sizeof(char) es 1, por definición.

Quiero decir, solo lee atentamente la entrada de Wikipedia para ver que está mal."múltiplos de caracteres". sizeof(char) nunca puede ser nada otro que "1".Si fuera, digamos, 2, significaría que sizeof(char) ¡Era el doble del tamaño de carbonizado!

Si realmente desea hacer esto para pasar su matriz, le sugiero implementar una estructura para almacenar un puntero al tipo del que desea una matriz y un número entero que represente el tamaño de la matriz.Luego puedes pasar eso a tus funciones.Simplemente asigne el valor de la variable de matriz (puntero al primer elemento) a ese puntero.Entonces puedes ir Array.arr[i] para obtener el i-ésimo elemento y usar Array.size para obtener el número de elementos de la matriz.

Incluí un código para ti.No es muy útil pero podrías ampliarlo con más funciones.Para ser honesto, si estas son las cosas que desea, debería dejar de usar C y usar otro lenguaje con estas características integradas.

/* Absolutely no one should use this...
   By the time you're done implementing it you'll wish you just passed around
   an array and size to your functions */
/* This is a static implementation. You can get a dynamic implementation and 
   cut out the array in main by using the stdlib memory allocation methods,
   but it will work much slower since it will store your array on the heap */

#include <stdio.h>
#include <string.h>
/*
#include "MyTypeArray.h"
*/
/* MyTypeArray.h 
#ifndef MYTYPE_ARRAY
#define MYTYPE_ARRAY
*/
typedef struct MyType
{
   int age;
   char name[20];
} MyType;
typedef struct MyTypeArray
{
   int size;
   MyType *arr;
} MyTypeArray;

MyType new_MyType(int age, char *name);
MyTypeArray newMyTypeArray(int size, MyType *first);
/*
#endif
End MyTypeArray.h */

/* MyTypeArray.c */
MyType new_MyType(int age, char *name)
{
   MyType d;
   d.age = age;
   strcpy(d.name, name);
   return d;
}

MyTypeArray new_MyTypeArray(int size, MyType *first)
{
   MyTypeArray d;
   d.size = size;
   d.arr = first;
   return d;
}
/* End MyTypeArray.c */


void print_MyType_names(MyTypeArray d)
{
   int i;
   for (i = 0; i < d.size; i++)
   {
      printf("Name: %s, Age: %d\n", d.arr[i].name, d.arr[i].age);
   }
}

int main()
{
   /* First create an array on the stack to store our elements in.
      Note we could create an empty array with a size instead and
      set the elements later. */
   MyType arr[] = {new_MyType(10, "Sam"), new_MyType(3, "Baxter")};
   /* Now create a "MyTypeArray" which will use the array we just
      created internally. Really it will just store the value of the pointer
      "arr". Here we are manually setting the size. You can use the sizeof
      trick here instead if you're sure it will work with your compiler. */
   MyTypeArray array = new_MyTypeArray(2, arr);
   /* MyTypeArray array = new_MyTypeArray(sizeof(arr)/sizeof(arr[0]), arr); */
   print_MyType_names(array);
   return 0;
}

La mejor manera es guardar esta información, por ejemplo, en una estructura:

typedef struct {
     int *array;
     int elements;
} list_s;

Implemente todas las funciones necesarias, como crear, destruir, verificar la igualdad y todo lo que necesite.Es más fácil pasarlo como parámetro.

La función sizeof devuelve el número de bytes que utiliza su matriz en la memoria.Si desea calcular el número de elementos en su matriz, debe dividir ese número entre sizeof tipo de variable de la matriz.Digamos int array[10];, si el tipo de variable entero en su computadora es de 32 bits (o 4 bytes), para obtener el tamaño de su matriz, debe hacer lo siguiente:

int array[10];
int sizeOfArray = sizeof(array)/sizeof(int);

Puedes usar el & operador.Aquí está el código fuente:

#include<stdio.h>
#include<stdlib.h>
int main(){

    int a[10];

    int *p; 

    printf("%p\n", (void *)a); 
    printf("%p\n", (void *)(&a+1));
    printf("---- diff----\n");
    printf("%zu\n", sizeof(a[0]));
    printf("The size of array a is %zu\n", ((char *)(&a+1)-(char *)a)/(sizeof(a[0])));


    return 0;
};

Aquí está el resultado de muestra.

1549216672
1549216712
---- diff----
4
The size of array a is 10
int a[10];
int size = (*(&a+1)-a) ;

Para más detalles veraquíy también aquí.

Ejemplo

#include <stdio.h>

int main() {
    int size;
    scanf("%d", &size);
    int array[size];
    printf("%d\n", (int) (sizeof(array) / sizeof(int)));
    printf("%d\n", (int) (sizeof(array) / sizeof(array[0])));
    return 0;
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top