¿Cómo encuentro la longitud de una matriz?

¿Hay alguna manera de encontrar cuántos valores tiene una matriz? Detectar si he llegado al final de una matriz también funcionaría.

Si te refieres a una matriz estilo C, entonces puedes hacer algo como:

int a[7]; std::cout < < "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl; 

Sin embargo, esto no funciona en los punteros, es decir , no funcionará para ninguno de los siguientes:

 int *p = new int[7]; std::cout < < "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl; 

o:

 void func(int *p) { std::cout < < "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl; } int a[7]; func(a); 

En C ++, si quieres este tipo de comportamiento, entonces deberías estar usando una clase contenedor; Probablemente std::vector .

Como se ha dicho, puede usar el sizeof(arr)/sizeof(*arr) pero esto le dará la respuesta incorrecta para los tipos de puntero que no son arrays.

 template constexpr size_t size(T (&)[N]) { return N; } 

Esto tiene la buena propiedad de no comstackr para tipos que no son de matriz (visual studio tiene _countof que hace esto). constexpr hace de esto una expresión de tiempo de comstackción para que no tenga ningún inconveniente sobre la macro (al menos ninguno que yo sepa).

También puede considerar usar std::array desde C ++ 11, que expone su longitud sin sobrecarga en una matriz C nativa.

C ++ 17 tiene std::size() en el encabezado que hace lo mismo y también funciona para contenedores STL (gracias a @Jon C ).

Al hacer sizeof( myArray ) obtendrá la cantidad total de bytes asignados para esa matriz. A continuación, puede averiguar la cantidad de elementos en la matriz dividiendo por el tamaño de un elemento en la matriz: sizeof( myArray[0] )

¿Hay alguna manera de encontrar cuántos valores tiene una matriz?

¡Sí!

Pruebe sizeof(array)/sizeof(array[0])

Detectar si he llegado al final de una matriz también funcionaría.

No veo ninguna forma de hacerlo a menos que tu matriz sea una matriz de caracteres (es decir, una cadena).

PD: en C ++ siempre use std::vector . Hay varias funciones incorporadas y una funcionalidad extendida.

Si bien esta es una pregunta antigua, vale la pena actualizar la respuesta a C ++ 17. En la biblioteca estándar ahora existe la función de plantilla std::size() , que devuelve la cantidad de elementos tanto en un contenedor estándar como en un array de estilo C. Por ejemplo:

 #include  uint32_t data[] = {10, 20, 30, 40}; auto dataSize = std::size(data); // dataSize == 4 

std::vector tiene un size() método size() que devuelve la cantidad de elementos en el vector.

(Sí, esta es una respuesta irónica)

 #include  int main () { using namespace std; int arr[] = {2, 7, 1, 111}; auto array_length = end(arr) - begin(arr); cout < < "Length of array: " << array_length << endl; } 

Desde C ++ 11, se introducen algunas plantillas nuevas para ayudar a reducir el dolor cuando se trata de la longitud de la matriz. Todos ellos están definidos en el encabezado .

  • std::rank::value

    Si T es un tipo de matriz, proporciona al miembro un valor constante igual al número de dimensiones de la matriz. Para cualquier otro tipo, el valor es 0.

  • std::extent::value

    Si T es un tipo de matriz, proporciona al miembro un valor constante igual al número de elementos a lo largo de la dimensión N de la matriz, si N está en [0, std::rank::value ]. Para cualquier otro tipo, o si T es una matriz de límite desconocido a lo largo de su primera dimensión y N es 0, el valor es 0.

  • std::remove_extent::type

    Si T es una matriz de algún tipo X , proporciona al miembro typedef type igual a X ; de lo contrario, type es T Tenga en cuenta que si T es una matriz multidimensional, solo se elimina la primera dimensión.

  • std::remove_all_extents::type

    Si T es una matriz multidimensional de algún tipo X , proporciona al miembro typedef type igual a X ; de lo contrario, type es T

Para obtener la longitud de cualquier dimensión de una matriz multidimensional, decltype podría usar para combinar con std::extent . Por ejemplo:

 #include  #include  // std::remove_extent std::remove_all_extents std::rank std::extent template constexpr size_t length(T(&)[N]) { return N; } template constexpr size_t length2(T(&arr)[N]) { return sizeof(arr) / sizeof(*arr); } int main() { int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}}; // New way constexpr auto l1 = std::extent::value; // 5 constexpr auto l2 = std::extent::value; // 4 constexpr auto l3 = std::extent::value; // 3 constexpr auto l4 = std::extent::value; // 0 // Mixed way constexpr auto la = length(a); //constexpr auto lpa = length(*a); // compile error //auto lpa = length(*a); // get at runtime std::remove_extent::type pa; // get at compile time //std::remove_reference::type pa; // same as above constexpr auto lpa = length(pa); std::cout < < la << ' ' << lpa << '\n'; // Old way constexpr auto la2 = sizeof(a) / sizeof(*a); constexpr auto lpa2 = sizeof(*a) / sizeof(**a); std::cout << la2 << ' ' << lpa2 << '\n'; return 0; } 

BTY, para obtener la cantidad total de elementos en una matriz multidimensional:

 constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents::type); 

O póngalo en una plantilla de función:

 #include  #include  template constexpr size_t len(T &a) { return sizeof(a) / sizeof(typename std::remove_all_extents::type); } int main() { int a[5][4][3]{{{1,2,3}, {4,5,6}}, { }, {{7,8,9}}}; constexpr auto ttt = len(a); int i; std::cout < < ttt << ' ' << len(i) << '\n'; return 0; } 

Se pueden encontrar más ejemplos de cómo usarlos siguiendo los enlaces.

También está el modo TR1 / C ++ 11 / C ++ 17 (verlo en vivo en Coliru ):

 const std::string s[3] = { "1"s, "2"s, "3"s }; constexpr auto n = std::extent< decltype(s) >::value; // From  constexpr auto n2 = std::extent_v< decltype(s) >; // C++17 shorthand const auto a = std::array{ "1"s, "2"s, "3"s }; // C++17 class template arg deduction -- http://en.cppreference.com/w/cpp/language/class_template_argument_deduction constexpr auto size = std::tuple_size_v< decltype(a) >; std::cout < < n << " " << n2 << " " << size << "\n"; // Prints 3 3 3 

En lugar de usar la función incorporada en la matriz, también conocida como:

  int x[2] = {0,1,2}; 

deberías usar la clase de matriz y la plantilla de matriz. Tratar:

 #include  array Name_of_Array = {}; 

Entonces, si quiere encontrar la longitud de la matriz, todo lo que tiene que hacer es usar la función de tamaño en la clase de matriz.

 Name_of_Array.size(); 

y eso debería devolver la longitud de los elementos en la matriz.

En C ++, al usar la clase std :: array para declarar una matriz, uno puede encontrar fácilmente el tamaño de una matriz y también el último elemento.

 #include #include int main() { std::array arr; //To find the size of the array std::cout<  

De hecho, la clase de matriz tiene muchas otras funciones que nos permiten usar una matriz en un contenedor estándar.
Referencia 1 a C ++ std :: clase de matriz
Referencia 2 a la clase std :: array
Los ejemplos en las referencias son útiles.

Aquí hay una implementación de ArraySize de Google Protobuf .

 #define GOOGLE_ARRAYSIZE(a) \ ((sizeof(a) / sizeof(*(a))) / static_cast(!(sizeof(a) % sizeof(*(a))))) // test codes... char* ptr[] = { "you", "are", "here" }; int testarr[] = {1, 2, 3, 4}; cout < < GOOGLE_ARRAYSIZE(testarr) << endl; cout << GOOGLE_ARRAYSIZE(ptr) << endl; 

ARRAYSIZE (arr) funciona inspeccionando sizeof (arr) (el n. ° de bytes en el array) y sizeof (* (arr)) (el n. ° de bytes en un elemento del array). Si el primero es divisible por el segundo, quizás arr sea de hecho un conjunto, en cuyo caso el resultado de la división es el número de elementos del conjunto. De lo contrario, arr no puede ser una matriz y generamos un error de comstackción para evitar que el código se compile.

Dado que el tamaño de bool está definido por implementación, necesitamos convertir! (Sizeof (a) & sizeof (* (a))) a size_t para garantizar que el resultado final tenga el tipo size_t.

Esta macro no es perfecta, ya que acepta erróneamente ciertos punteros, es decir, donde el tamaño del puntero es divisible por el tamaño del punto. Como todo nuestro código tiene que ir a través de un comstackdor de 32 bits, donde un puntero es de 4 bytes, esto significa que todos los punteros a un tipo cuyo tamaño sea 3 o superior a 4 serán (justamente) rechazados.

Para C ++ / CX (al escribir, por ejemplo, aplicaciones UWP usando C ++ en Visual Studio) podemos encontrar el número de valores en una matriz simplemente usando la función size() .

Código fuente:

 string myArray[] = { "Example1", "Example2", "Example3", "Example4" }; int size_of_array=size(myArray); 

Si menciona el size_of_array la salida será:

 >>> 4 

Una buena solución que usa generics:

 template  inline unsigned arraysize(const T (&v)[S]) { return S; } 

Entonces simplemente llame a arraysize(_Array); para obtener la longitud de la matriz.

Fuente

  length = sizeof(array_name)/sizeof(int); 

Solo un pensamiento, pero solo decidí crear una variable de contador y almacenar el tamaño de la matriz en la posición [0]. Eliminé la mayor parte del código que tenía en la función, pero verá que después de salir del ciclo, a la prioridad [0] se le asigna el valor final de ‘a’. Intenté usar vectores, pero a VS Express 2013 no le gustó mucho. También tenga en cuenta que ‘a’ comienza en uno para evitar sobrescribir [0] y se inicializa al principio para evitar errores. No soy un experto, solo pensé en compartir.

 int prime[] = {0}; int primes(int x, int y){ using namespace std; int a = 1; for (int i = x; i < = y; i++){prime[a] = i; a++; } prime[0] = a; return 0; } 

Una de las razones más comunes por las que terminaría buscando esto es porque quiere pasar una matriz a una función y no tener que pasar otro argumento por su tamaño. En general, también te gustaría que el tamaño de la matriz sea dynamic. Esa matriz puede contener objetos, no primitivos, y los objetos pueden ser complejos, de modo que size_of () es una opción no segura para calcular el recuento.

Como otros han sugerido, considere usar un std :: vector o lista, etc. en lugar de una matriz primitiva. En los viejos comstackdores, sin embargo, todavía no tendrías la solución final que probablemente quieras, simplemente haciendo eso, porque llenar el contenedor requiere un montón de feas líneas push_back (). Si eres como yo, quieres una solución de línea única con objetos anónimos involucrados.

Si opta por el contenedor STL alternativo a una matriz primitiva, esta publicación SO puede ser útil para las formas de inicializarla: ¿Cuál es la forma más fácil de inicializar un std :: vector con elementos codificados?

Aquí hay un método que estoy usando para esto que funcionará universalmente en comstackdores y plataformas:

Crea una estructura o clase como contenedor para tu colección de objetos. Definir una función de sobrecarga del operador para < <.

 class MyObject; struct MyObjectList { std::list objects; MyObjectList& operator< <( const MyObject o ) { objects.push_back( o ); return *this; } }; 

Puede crear funciones que toman su estructura como un parámetro, por ejemplo:

 someFunc( MyObjectList &objects ); 

Entonces, puedes llamar a esa función, así:

 someFunc( MyObjectList() < < MyObject(1) << MyObject(2) << MyObject(3) ); 

¡De esta forma, puedes construir y pasar una colección de objetos de tamaño dynamic a una función en una sola línea limpia!

Evite usar el tipo junto con sizeof, ya que sizeof(array)/sizeof(char) , de repente se corrompe si cambia el tipo de la matriz.

En Visual Studio, tienes el equivalente de sizeof(array)/sizeof(*array) . Simplemente puede escribir _countof(array)

Para el viejo comstackdor g ++, puedes hacer esto

 template  char (&helper(T (&)[N]))[N]; #define arraysize(array) (sizeof(helper(array))) int main() { int a[10]; std::cout < < arraysize(a) << std::endl; return 0; } 

Personalmente, sugeriría (si no puede trabajar con funciones especializadas por cualquier motivo) expandir primero las matrices, escriba la compatibilidad más allá de lo que normalmente usaría (si estaba almacenando valores ≥ 0):

 unsigned int x[] -> int x[] 

de lo que harías el elemento de la matriz 1 más grande de lo que necesitas para hacerlo. Para el último elemento pondría algún tipo que se incluye en el especificador de tipo expandido pero que normalmente no usaría, por ejemplo, utilizando el ejemplo anterior, el último elemento sería -1. Esto le permite (al usar un bucle for) encontrar el último elemento de una matriz.

Proporciono una solución difícil aquí:

Siempre puede almacenar length en el primer elemento:

 // malloc/new arr[0] = length; arr++; // do anything. int len = *(arr-1); free(--arr); 

El costo es usted debe --arr cuando invoque free

Digamos que tienes una matriz global declarada en la parte superior de la página

 int global[] = { 1, 2, 3, 4 }; 

Para saber cuántos elementos hay (en c ++) en la matriz, escriba el siguiente código:

 sizeof(global) / 4; 

El tamaño de (NAME_OF_ARRAY) / 4 le devolverá la cantidad de elementos para el nombre de la matriz dada.