¿Hay alguna manera de encontrar cuántos valores tiene una matriz? Detectar si he llegado o no al final de una matriz también funcionaría.
¿Hay alguna manera de encontrar cuántos valores tiene una matriz? Detectar si he llegado o no al final de una matriz también funcionaría.
Respuestas:
Si te refieres a una matriz de estilo C, entonces puedes hacer algo como:
int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl;
Esto no funciona en 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 desea este tipo de comportamiento, debería usar una clase contenedor; Probablemente std::vector
.
Como otros han dicho, puede usar el sizeof(arr)/sizeof(*arr)
pero esto le dará la respuesta incorrecta para los tipos de puntero que no son matrices.
template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }
Esto tiene la buena propiedad de no compilar para tipos que no son de matriz (Visual Studio tiene _countof
qué hace esto). Esto constexpr
hace que esta sea una expresión de tiempo de compilación para que no tenga inconvenientes sobre la macro (al menos ninguna que conozca).
También puede considerar el uso std::array
de C ++ 11 que expone su longitud sin sobrecarga en una matriz C nativa.
C ++ 17 tiene std::size()
en el <iterator>
encabezado lo que hace lo mismo y también funciona para contenedores STL (gracias a @Jon C ).
T(arg&)[N]
.
extent
, al verlo ahora hay dos características que lo hacen menos útil que la función anterior (para este caso de uso). (1) Devuelve cero para punteros (en lugar de un error de compilación). (2) Requiere un parámetro de tipo, por lo que para verificar una variable que tendría que hacerdecltype
Al hacerlo sizeof( myArray )
, obtendrá el número total de bytes asignados para esa matriz. Luego puede encontrar el número de elementos en la matriz dividiendo por el tamaño de un elemento en la matriz:sizeof( myArray[0] )
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 el número de elementos tanto en un contenedor estándar como en una matriz de estilo C. Por ejemplo:
#include <iterator>
uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
¿Hay alguna manera de encontrar cuántos valores tiene una matriz?
¡Si!
Tratar sizeof(array)/sizeof(array[0])
Detectar si he llegado o no al final de una matriz también funcionaría.
No veo ninguna manera de esto a menos que su matriz sea una matriz de caracteres (es decir, cadena).
PD: En C ++ siempre use std::vector
. Hay varias funciones incorporadas y una funcionalidad extendida.
std::vector
tiene un método size()
que devuelve el número de elementos en el vector.
(Sí, esta es una respuesta irónica)
#include <iostream>
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 <type_traits>
.
Si T
es un tipo de matriz, proporciona el valor constante del miembro igual al número de dimensiones de la matriz. Para cualquier otro tipo, el valor es 0.
Si T
es un tipo de matriz, proporciona el valor constante del miembro igual al número de elementos a lo largo de la N
dimensión th de la matriz, si N
está en [0, std::rank<T>::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.
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 se T
trata de una matriz multidimensional, solo se elimina la primera dimensión.
std::remove_all_extents<T>::type
Si T
es una matriz multidimensional de algún tipo X
, proporciona el miembro typedef type igual a X
, de lo contrario, type es T
.
Para obtener la longitud en cualquier dimensión de una matriz multidimensional, decltype
podría usarse para combinar con std::extent
. Por ejemplo:
#include <iostream>
#include <type_traits> // std::remove_extent std::remove_all_extents std::rank std::extent
template<class T, size_t N>
constexpr size_t length(T(&)[N]) { return N; }
template<class T, size_t N>
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<decltype(a)>::value; // 5
constexpr auto l2 = std::extent<decltype(a), 1>::value; // 4
constexpr auto l3 = std::extent<decltype(a), 2>::value; // 3
constexpr auto l4 = std::extent<decltype(a), 3>::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<decltype(a)>::type pa; // get at compile time
//std::remove_reference<decltype(*a)>::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 el número total de elementos en una matriz multidimensional:
constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);
O póngalo en una plantilla de función:
#include <iostream>
#include <type_traits>
template<class T>
constexpr size_t len(T &a)
{
return sizeof(a) / sizeof(typename std::remove_all_extents<T>::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 existe la forma TR1 / C ++ 11 / C ++ 17 (verlo Live on Coliru):
const std::string s[3] = { "1"s, "2"s, "3"s };
constexpr auto n = std::extent< decltype(s) >::value; // From <type_traits>
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 utilizar la función de matriz integrada, también conocida como:
int x[3] = {0, 1, 2};
debe usar la clase de matriz y la plantilla de matriz. Tratar:
#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};
Entonces, si desea 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 ++, utilizando la clase std :: array para declarar una matriz, se puede encontrar fácilmente el tamaño de una matriz y también el último elemento.
#include<iostream>
#include<array>
int main()
{
std::array<int,3> arr;
//To find the size of the array
std::cout<<arr.size()<<std::endl;
//Accessing the last element
auto it=arr.end();
std::cout<<arr.back()<<"\t"<<arr[arr.size()-1]<<"\t"<<*(--it);
return 0;
}
De hecho, la clase array tiene muchas otras funciones que nos permiten usar un contenedor estándar.
Referencia 1 a la clase std :: array de C ++
Referencia 2 a la clase std :: array de C ++
Los ejemplos en las referencias son útiles.
Esta es una pregunta bastante antigua y legendaria y ya hay muchas respuestas sorprendentes por ahí. Pero con el tiempo se agregan nuevas funcionalidades a los idiomas, por lo que debemos seguir actualizando las cosas según las nuevas funciones disponibles.
Acabo de notar que nadie ha mencionado aún sobre C ++ 20. Así que pensé en escribir la respuesta.
En C ++ 20, hay una nueva forma mejor agregada a la biblioteca estándar para encontrar la longitud de la matriz, es decir std:ssize()
. Esta función devuelve a signed value
.
#include <iostream>
int main() {
int arr[] = {1, 2, 3};
std::cout << std::ssize(arr);
return 0;
}
En C ++ 17 había una mejor manera (en ese momento) para la misma que se std::size()
define en iterator
.
#include <iostream>
#include <iterator> // required for std::size
int main(){
int arr[] = {1, 2, 3};
std::cout << "Size is " << std::size(arr);
return 0;
}
PD Este método funciona para vector
.
Este enfoque tradicional ya se menciona en muchas otras respuestas.
#include <iostream>
int main() {
int array[] = { 1, 2, 3 };
std::cout << sizeof(array) / sizeof(array[0]);
return 0;
}
Solo para su información, si se pregunta por qué este enfoque no funciona cuando la matriz se pasa a otra función . La razón es,
Una matriz no se pasa por valor en C ++, sino que se pasa el puntero a la matriz. Como en algunos casos, pasar los arreglos completos puede ser una operación costosa. Puede probar esto pasando la matriz a alguna función y hacer algunos cambios en la matriz allí y luego imprimir la matriz en main nuevamente. Obtendrás resultados actualizados.
Y como ya sabría, la sizeof()
función proporciona el número de bytes, por lo que en otra función devolverá el número de bytes asignados para el puntero en lugar de la matriz completa. Entonces este enfoque no funciona.
Pero estoy seguro de que puede encontrar una buena manera de hacerlo, según sus requisitos.
Feliz codificación.
Tiene un montón de opciones para usar para obtener un tamaño de matriz C.
int myArray [] = {0, 1, 2, 3, 4, 5, 7};
1) sizeof(<array>) / sizeof(<type>):
std::cout << "Size:" << sizeof(myArray) / sizeof(int) << std::endl;
2) sizeof(<array>) / sizeof(*<array>):
std::cout << "Size:" << sizeof(myArray) / sizeof(*myArray) << std::endl;
3) sizeof(<array>) / sizeof(<array>[<element>]):
std::cout << "Size:" << sizeof(myArray) / sizeof(myArray[0]) << std::endl;
Aquí es una implementación de ArraySize
de Google Protobuf .
#define GOOGLE_ARRAYSIZE(a) \
((sizeof(a) / sizeof(*(a))) / static_cast<size_t>(!(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úmero de bytes en la matriz) y sizeof (* (arr)) (el número de bytes en un elemento de la matriz). Si el primero es divisible por el segundo, quizás arr sea de hecho una matriz, en cuyo caso el resultado de la división es el número de elementos en la matriz. De lo contrario, arr no puede ser una matriz, y generamos un error de compilación para evitar que el código se compile.
Dado que el tamaño de bool está definido por la implementación, necesitamos convertir! (Sizeof (a) y 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 puntero. Dado que todo nuestro código tiene que pasar por un compilador 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 mayor que 4 serán (correctamente) rechazados.
int nombres[5] = { 9, 3 };
esta función regresa en 5
lugar de 2
.
Para C ++ / CX (al escribir, por ejemplo, aplicaciones UWP que usan C ++ en Visual Studio), podemos encontrar el número de valores en una matriz simplemente usando la size()
función.
Código fuente:
string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);
Si usted cout
la size_of_array
salida será:
>>> 4
sizeof(array_name)
da el tamaño de toda la matriz y sizeof(int)
da el tamaño del tipo de datos de cada elemento de la matriz.
Entonces, dividir el tamaño de toda la matriz por el tamaño de un solo elemento de la matriz da la longitud de la matriz.
int array_name[] = {1, 2, 3, 4, 5, 6};
int length = sizeof(array_name)/sizeof(int);
RESPUESTA :
int number_of_elements = sizeof(array)/sizeof(array[0])
EXPLICACIÓN :
Como el compilador establece un tamaño específico de memoria a un lado para cada tipo de datos, y una matriz es simplemente un grupo de esos, simplemente divide el tamaño de la matriz por el tamaño del tipo de datos. Si tengo una matriz de 30 cadenas, mi sistema reserva 24 bytes para cada elemento (cadena) de la matriz. Con 30 elementos, eso es un total de 720 bytes. 720/24 == 30 elementos. El algoritmo pequeño y ajustado para eso es:
int number_of_elements = sizeof(array)/sizeof(array[0])
lo que equivale a
number_of_elements = 720/24
Tenga en cuenta que no necesita saber qué tipo de datos es la matriz, incluso si se trata de un tipo de datos personalizado.
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ás que después de salir del bucle, a prime [0] se le asigna el valor final de 'a'. Intenté usar vectores, pero VS Express 2013 no me 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 buena solución que usa genéricos:
template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }
Luego simplemente llame arraysize(_Array);
para obtener la longitud de la matriz.
constexpr
es la solución. inline
no es. constexpr
aunque es bastante moderno. ¿Está seguro de que su programa de prueba no está utilizando otra característica moderna, donde puede declarar una matriz local cuya longitud está dada por una variable? Pruébelo con dos matrices globales.
Para el antiguo compilador de g ++, puede hacer esto
template <class T, size_t N>
char (&helper(T (&)[N]))[N];
#define arraysize(array) (sizeof(helper(array)))
int main() {
int a[10];
std::cout << arraysize(a) << std::endl;
return 0;
}
Proporciono una solución difícil aquí:
Siempre puedes almacenar length
en el primer elemento:
// malloc/new
arr[0] = length;
arr++;
// do anything.
int len = *(arr-1);
free(--arr);
El costo es obligatorio --arr
al invocarfree
arr
es de un tipo compatible int
y la matriz no es más larga que el valor máximo del tipo. Por ejemplo, las cadenas de Pascal son en realidad conjuntos de bytes que utilizan este truco; La longitud máxima de las cadenas en Pascal es de 255 caracteres.
Puede encontrar la longitud de una matriz de la siguiente manera:
int arr[] = {1, 2, 3, 4, 5, 6};
int size = *(&arr + 1) - arr;
cout << "Number of elements in arr[] is "<< size;
return 0;
Simplemente puede usar este fragmento:
#include <iostream>
#include <string>
#include <array>
using namespace std;
int main()
{
array<int,3> values;
cout << "No. elements in valuea array: " << values.size() << " elements." << endl;
cout << "sizeof(myints): " << sizeof(values) << endl;
}
y aquí está la referencia: http://www.cplusplus.com/reference/array/array/size/
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 si sizeof(array)/sizeof(*array)
. Puedes simplemente escribir_countof(array)
Yo personalmente sugeriría (si no puede trabajar con funciones especializadas por cualquier motivo) primero expandir la compatibilidad de tipo de matrices más allá de lo que normalmente usaría (si estuviera almacenando valores ≥ 0:
unsigned int x[] -> int x[]
de lo que haría que el elemento de matriz 1 sea más grande de lo que necesita para hacerlo. Para el último elemento, colocaría algún tipo que se incluye en el especificador de tipo expandido pero que normalmente no usaría, por ejemplo, usando el ejemplo anterior, el último elemento sería -1. Esto le permite (mediante el uso de un bucle for) encontrar el último elemento de una matriz.
Una de las razones más comunes por las que terminaría buscando esto es porque desea pasar una matriz a una función y no tener que pasar otro argumento para su tamaño. En general, también le gustaría que el tamaño de la matriz sea dinámico. Esa matriz puede contener objetos, no primitivos, y los objetos pueden ser complejos, de modo que size_of () no es una opción segura para calcular el recuento.
Como otros han sugerido, considere usar un std :: vector o una lista, etc. en lugar de una matriz primitiva. Sin embargo, en los compiladores antiguos, aún no tendría la solución final que probablemente desea simplemente haciendo eso, porque llenar el contenedor requiere un montón de líneas feo 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 serle útil para encontrar 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 compiladores y plataformas:
Cree una estructura o clase como contenedor para su colección de objetos. Defina una función de sobrecarga del operador para <<.
class MyObject;
struct MyObjectList
{
std::list<MyObject> objects;
MyObjectList& operator<<( const MyObject o )
{
objects.push_back( o );
return *this;
}
};
Puede crear funciones que tomen su estructura como parámetro, por ejemplo:
someFunc( MyObjectList &objects );
Entonces, puedes llamar a esa función, así:
someFunc( MyObjectList() << MyObject(1) << MyObject(2) << MyObject(3) );
¡De esa manera, puede construir y pasar una colección de objetos de tamaño dinámico a una función en una sola línea limpia!
Digamos que tiene una matriz global declarada en la parte superior de la página
int global[] = { 1, 2, 3, 4 };
Para averiguar 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á el número de elementos para el nombre de matriz dado.