Existe uma maneira de descobrir quantos valores uma matriz possui? Detectar se cheguei ou não ao final de uma matriz também funcionaria.
Existe uma maneira de descobrir quantos valores uma matriz possui? Detectar se cheguei ou não ao final de uma matriz também funcionaria.
Respostas:
Se você quer dizer uma matriz no estilo C, pode fazer algo como:
int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl;
Isso não funciona em ponteiros (ou seja , não funciona em nenhum dos seguintes):
int *p = new int[7];
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
ou:
void func(int *p)
{
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
}
int a[7];
func(a);
No C ++, se você deseja esse tipo de comportamento, deve estar usando uma classe de contêiner; provavelmente std::vector
.
Como já foi dito, você pode usar o, sizeof(arr)/sizeof(*arr)
mas isso fornecerá a resposta errada para os tipos de ponteiro que não são matrizes.
template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }
Isso tem a boa propriedade de não compilar para tipos que não são de matriz (o visual studio possui o _countof
que faz isso). O constexpr
torna uma expressão de tempo de compilação, para que não tenha desvantagens sobre a macro (pelo menos nenhuma que eu conheça).
Você também pode considerar o uso std::array
do C ++ 11, que expõe seu comprimento sem sobrecarga sobre uma matriz C nativa.
O C ++ 17 tem std::size()
no <iterator>
cabeçalho o mesmo e funciona para contêineres STL (graças a @Jon C ).
T(arg&)[N]
.
extent
, olhando para ele agora existem duas características que o tornam menos útil do que a função acima (para este caso de uso). (1) Retorna zero para ponteiros (em vez de um erro de compilação). (2) Ele requer um parâmetro de tipo, portanto, para verificar uma variável que você teria que fazer, decltype
Doing sizeof( myArray )
você receberá o número total de bytes alocados para essa matriz. Você pode descobrir o número de elementos na matriz dividindo pelo tamanho de um elemento na matriz:sizeof( myArray[0] )
Embora essa seja uma pergunta antiga, vale a pena atualizar a resposta para C ++ 17. Na biblioteca padrão, agora existe a função de modelo std::size()
, que retorna o número de elementos em um contêiner std ou em uma matriz no estilo C. Por exemplo:
#include <iterator>
uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
Existe uma maneira de descobrir quantos valores uma matriz possui?
Sim!
Tentar sizeof(array)/sizeof(array[0])
Detectar se cheguei ou não ao final de uma matriz também funcionaria.
Eu não vejo nenhuma maneira para isso, a menos que sua matriz seja uma matriz de caracteres (isto é, string).
PS: Em C ++, use sempre std::vector
. Existem várias funções embutidas e uma funcionalidade estendida.
std::vector
possui um método size()
que retorna o número de elementos no vetor.
(Sim, esta é a resposta explícita)
#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 o C ++ 11, alguns novos modelos são introduzidos para ajudar a reduzir a dor ao lidar com o comprimento da matriz. Todos eles são definidos no cabeçalho <type_traits>
.
Se T
for um tipo de matriz, fornece o valor constante do membro igual ao número de dimensões da matriz. Para qualquer outro tipo, o valor é 0.
Se T
for um tipo de matriz, fornece o valor constante do membro igual ao número de elementos ao longo da N
th dimensão da matriz, se N
estiver em [0, std::rank<T>::value
). Para qualquer outro tipo, ou se a T
matriz de desconhecida estiver ligada ao longo de sua primeira dimensão e N
for 0, o valor será 0.
Se T
for uma matriz de algum tipo X
, fornece o tipo de membro typedef igual a X
, caso contrário, o tipo é T
. Observe que se T
for uma matriz multidimensional, somente a primeira dimensão será removida.
std::remove_all_extents<T>::type
Se T
for uma matriz multidimensional de algum tipo X
, fornece o tipo de membro typedef igual a X
, caso contrário, o tipo é T
.
Para obter o comprimento em qualquer dimensão de uma matriz multidimensional, decltype
pode ser usado para combinar com std::extent
. Por exemplo:
#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 obter o número total de elementos em uma matriz multidimensional:
constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);
Ou coloque-o em um modelo de função:
#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;
}
Mais exemplos de como usá-los podem ser encontrados seguindo os links.
Há também a maneira TR1 / C ++ 11 / C ++ 17 (veja 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
Em vez de usar a função de matriz incorporada, também conhecida como:
int x[3] = {0, 1, 2};
você deve usar a classe de matriz e o modelo de matriz. Tentar:
#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};
Portanto, agora, se você deseja encontrar o comprimento da matriz, tudo o que você precisa fazer é usar a função size na classe da matriz.
Name_of_Array.size();
e isso deve retornar o comprimento dos elementos na matriz.
Em C ++, usando a classe std :: array para declarar uma matriz, é possível encontrar facilmente o tamanho de uma matriz e também o ú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 fato, a classe array possui muitas outras funções que nos permitem usar um container padrão.
Referência 1 à classe std :: array do C ++
Referência 2 à classe std :: array
Os exemplos nas referências são úteis.
Essa é uma pergunta praticamente antiga e lendária e já existem muitas respostas incríveis por aí. Porém, com o tempo, novas funcionalidades são adicionadas aos idiomas; portanto, precisamos continuar atualizando as coisas de acordo com os novos recursos disponíveis.
Acabei de notar que alguém ainda não mencionou o C ++ 20. Então, pensei em escrever resposta.
No C ++ 20, há uma nova maneira melhor adicionada à biblioteca padrão para encontrar o comprimento da matriz, ie std:ssize()
. Esta função retorna a signed value
.
#include <iostream>
int main() {
int arr[] = {1, 2, 3};
std::cout << std::ssize(arr);
return 0;
}
No C ++ 17, havia uma maneira melhor (naquela época) para a mesma std::size()
definida em 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;
}
PS Esse método também funciona vector
.
Essa abordagem tradicional já é mencionada em muitas outras respostas.
#include <iostream>
int main() {
int array[] = { 1, 2, 3 };
std::cout << sizeof(array) / sizeof(array[0]);
return 0;
}
Apenas para sua informação, se você se pergunta por que essa abordagem não funciona quando o array é passado para outra função . A razão é,
Uma matriz não é passada por valor em C ++, mas o ponteiro para a matriz é passado. Como em alguns casos, passar todas as matrizes pode ser uma operação cara. Você pode testar isso passando a matriz para alguma função e fazendo algumas alterações na matriz lá e, em seguida, imprima a matriz no main novamente. Você obterá resultados atualizados.
E como você já deve saber, a sizeof()
função fornece o número de bytes; portanto, em outra função, ele retornará o número de bytes alocados para o ponteiro, em vez de toda a matriz. Portanto, essa abordagem não funciona.
Mas tenho certeza de que você pode encontrar uma boa maneira de fazer isso, conforme sua exigência.
Feliz codificação.
Você tem várias opções a serem usadas para obter um tamanho 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;
Aqui está uma implementação ArraySize
do 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 inspecionando sizeof (arr) (o número de bytes na matriz) e sizeof (* (arr)) (o número de bytes em um elemento da matriz). Se o primeiro é divisível pelo último, talvez arr seja de fato uma matriz; nesse caso, o resultado da divisão é o número de elementos na matriz. Caso contrário, arr não pode ser uma matriz e geramos um erro do compilador para impedir a compilação do código.
Como o tamanho do bool é definido pela implementação, precisamos converter! (Sizeof (a) & sizeof (* (a))) em size_t para garantir que o resultado final tenha o tipo size_t.
Essa macro não é perfeita, pois aceita erroneamente certos ponteiros, a saber, onde o tamanho do ponteiro é divisível pelo tamanho do ponteiro. Como todo o nosso código precisa passar por um compilador de 32 bits, em que um ponteiro tem 4 bytes, isso significa que todos os ponteiros para um tipo cujo tamanho é 3 ou maior que 4 serão (justamente) rejeitados.
int nombres[5] = { 9, 3 };
esta função retorna em 5
vez de 2
.
Para C ++ / CX (ao escrever, por exemplo, aplicativos UWP usando C ++ no Visual Studio), podemos encontrar o número de valores em uma matriz simplesmente usando a size()
função
Código fonte:
string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);
Se você cout
a size_of_array
saída será:
>>> 4
sizeof(array_name)
fornece o tamanho de toda a matriz e sizeof(int)
fornece o tamanho do tipo de dados de cada elemento da matriz.
Portanto, dividir o tamanho de toda a matriz pelo tamanho de um único elemento da matriz fornece o comprimento da matriz.
int array_name[] = {1, 2, 3, 4, 5, 6};
int length = sizeof(array_name)/sizeof(int);
RESPOSTA :
int number_of_elements = sizeof(array)/sizeof(array[0])
EXPLICAÇÃO :
Como o compilador coloca um pedaço de memória de tamanho específico de lado para cada tipo de dados e uma matriz é simplesmente um grupo desses, você simplesmente divide o tamanho da matriz pelo tamanho do tipo de dados. Se eu tiver uma matriz de 30 strings, meu sistema separará 24 bytes para cada elemento (string) da matriz. Com 30 elementos, isso representa um total de 720 bytes. 720/24 == 30 elementos. O algoritmo pequeno e rígido para isso é:
int number_of_elements = sizeof(array)/sizeof(array[0])
o que equivale a
number_of_elements = 720/24
Observe que você não precisa saber que tipo de dados é a matriz, mesmo que seja um tipo de dados personalizado.
Apenas um pensamento, mas apenas decidimos criar uma variável de contador e armazenar o tamanho do array na posição [0]. Eu apaguei a maior parte do código que tinha na função, mas você verá que, após sair do loop, prime [0] recebe o valor final de 'a'. Tentei usar vetores, mas o VS Express 2013 não gostou muito disso. Observe também que 'a' começa com um para evitar a substituição [0] e é inicializado no início para evitar erros. Não sou especialista, apenas pensei em compartilhar.
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;
}
Uma boa solução que usa genéricos:
template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }
Em seguida, basta ligar arraysize(_Array);
para obter o comprimento da matriz.
constexpr
é a correção. inline
não é. constexpr
é bastante moderno. Você tem certeza de que seu programa de teste não está usando outro recurso moderno, onde você pode declarar uma matriz local cujo comprimento é fornecido por uma variável? Experimente com duas matrizes globais.
Para o antigo compilador g ++, você pode fazer isso
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;
}
Eu forneço uma solução complicada aqui:
Você sempre pode armazenar length
no primeiro elemento:
// malloc/new
arr[0] = length;
arr++;
// do anything.
int len = *(arr-1);
free(--arr);
O custo é que você deve --arr
quando invocarfree
arr
é de um tipo compatível int
e a matriz não excede o valor máximo do tipo. Por exemplo, seqüências de caracteres Pascal são realmente matrizes de bytes usando esse truque; o comprimento máximo de seqüências de caracteres em Pascal é de 255 caracteres.
você pode encontrar o comprimento de uma matriz seguindo:
int arr[] = {1, 2, 3, 4, 5, 6};
int size = *(&arr + 1) - arr;
cout << "Number of elements in arr[] is "<< size;
return 0;
Simplesmente você pode usar este trecho:
#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;
}
e aqui está a referência: http://www.cplusplus.com/reference/array/array/size/
Evite usar o tipo junto com sizeof, como sizeof(array)/sizeof(char)
, de repente, fica corrompido se você alterar o tipo da matriz.
No visual studio, você tem o equivalente se sizeof(array)/sizeof(*array)
. Você pode simplesmente digitar_countof(array)
Eu, pessoalmente, sugeriria (se você não conseguir trabalhar com funções especializadas por qualquer motivo) expandir primeiro a compatibilidade do tipo de matrizes além do que você usaria normalmente (se estivesse armazenando valores ≥ 0:
unsigned int x[] -> int x[]
do que você tornaria o elemento da matriz 1 maior do que o necessário. Para o último elemento, você colocaria algum tipo incluído no especificador de tipo expandido, mas que normalmente não usaria, por exemplo, usando o exemplo anterior, o último elemento seria -1. Isso permite que você (usando um loop for) encontre o último elemento de uma matriz.
Um dos motivos mais comuns pelos quais você acabaria procurando isso é porque deseja passar um array para uma função e não precisa passar outro argumento para seu tamanho. Você também geralmente gostaria que o tamanho da matriz fosse dinâmico. Essa matriz pode conter objetos, não primitivos, e os objetos talvez complexos, de modo que size_of () seja uma opção não segura para calcular a contagem.
Como outros sugeriram, considere o uso de um std :: vector ou lista, etc, em vez de uma matriz primitiva. No entanto, em compiladores antigos, você ainda não teria a solução final que provavelmente deseja, simplesmente porque isso, porque preencher o contêiner requer várias linhas feias de push_back (). Se você é como eu, deseja uma solução de linha única com objetos anônimos envolvidos.
Se você optar pela alternativa de contêiner STL para uma matriz primitiva, esta postagem do SO poderá ser útil para você de maneiras de inicializá-la: Qual é a maneira mais fácil de inicializar um std :: vector com elementos codificados?
Aqui está um método que estou usando para isso que funcionará universalmente em compiladores e plataformas:
Crie uma estrutura ou classe como contêiner para sua coleção de objetos. Defina uma função de sobrecarga do operador para <<.
class MyObject;
struct MyObjectList
{
std::list<MyObject> objects;
MyObjectList& operator<<( const MyObject o )
{
objects.push_back( o );
return *this;
}
};
Você pode criar funções que tomam sua estrutura como um parâmetro, por exemplo:
someFunc( MyObjectList &objects );
Em seguida, você pode chamar essa função, assim:
someFunc( MyObjectList() << MyObject(1) << MyObject(2) << MyObject(3) );
Dessa forma, você pode criar e transmitir uma coleção de objetos de tamanho dinâmico para uma função em uma única linha limpa!
Digamos que você tenha uma matriz global declarada na parte superior da página
int global[] = { 1, 2, 3, 4 };
Para descobrir quantos elementos existem (em c ++) na matriz, digite o seguinte código:
sizeof(global) / 4;
O tamanho de (NAME_OF_ARRAY) / 4 retornará o número de elementos para o nome da matriz.