배열에 몇 개의 값이 있는지 찾는 방법이 있습니까? 배열의 끝에 도달했는지 여부를 감지하는 것도 효과가 있습니다.
배열에 몇 개의 값이 있는지 찾는 방법이 있습니까? 배열의 끝에 도달했는지 여부를 감지하는 것도 효과가 있습니다.
답변:
C 스타일 배열을 의미한다면 다음과 같이 할 수 있습니다.
int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl;
이것은 포인터에서 작동하지 않습니다 (즉 , 다음 중 하나 에서는 작동 하지 않습니다 ).
int *p = new int[7];
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
또는:
void func(int *p)
{
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
}
int a[7];
func(a);
C ++에서 이런 종류의 동작을 원하면 컨테이너 클래스를 사용해야합니다. 아마 std::vector
.
다른 사람이 말했듯이 사용할 수는 sizeof(arr)/sizeof(*arr)
있지만 배열이 아닌 포인터 유형에 대한 잘못된 대답을 제공합니다.
template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }
이것은 비 배열 유형에 대한 컴파일 실패의 좋은 속성을 가지고 있습니다 (시각적 스튜디오는 _countof
이것을 수행합니다). 는 constexpr
그것이 (이상 없음에서 내가 아는) 매크로를 통해 어떤 결점이없는, 그래서이 컴파일 시간 표현한다.
std::array
네이티브 C 배열보다 오버 헤드없이 길이를 노출시키는 C ++ 11에서 사용 하는 것도 고려할 수 있습니다 .
C ++ 17 은std::size()
에 <iterator>
동일한을 수행하고 너무 STL 컨테이너 (덕분에 작동 헤더 @ 존 C ).
extent
위의 기능보다 유용 하지 않은 두 가지 특성이 있습니다 (이 사용 사례의 경우). (1) 컴파일 오류가 아닌 포인터에 대해 0을 반환합니다. (2) 변수를 확인하기 위해 타입 파라미터가 필요합니다decltype
그렇게하면 sizeof( myArray )
해당 배열에 할당 된 총 바이트 수를 얻을 수 있습니다. 그런 다음 배열에서 한 요소의 크기로 나누어 배열의 요소 수를 찾을 수 있습니다.sizeof( myArray[0] )
이것은 오래된 질문이지만 C ++ 17에 대한 답변을 업데이트하는 것이 좋습니다. 표준 라이브러리에는 std::size()
std 컨테이너 또는 C 스타일 배열의 요소 수를 반환 하는 템플릿 함수가 있습니다 . 예를 들면 다음과 같습니다.
#include <iterator>
uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
배열에 몇 개의 값이 있는지 찾는 방법이 있습니까?
예!
시험 sizeof(array)/sizeof(array[0])
배열의 끝에 도달했는지 여부를 감지하는 것도 효과가 있습니다.
배열이 문자 배열 (예 : 문자열)이 아니면이 방법을 보지 못합니다.
추신 : C ++에서는 항상 사용하십시오 std::vector
. 몇 가지 내장 기능과 확장 기능이 있습니다.
std::vector
방법이있다 size()
벡터의 요소 수를 반환 가 있습니다.
(예, 이건 혀로 답입니다)
#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;
}
C ++ 11부터는 배열 길이를 처리 할 때 고통을 줄이는 데 도움이되는 몇 가지 새로운 템플릿이 도입되었습니다. 그것들은 모두 header에 정의되어 <type_traits>
있습니다.
T
배열 유형 인 경우 배열의 차원 수와 동일한 멤버 상수 값을 제공하십시오. 다른 유형의 경우 값은 0입니다.
경우 T
배열 형이고, 부재 상수 값이 함께 소자의 수와 동일 제공 N
하는 경우, 상기 어레이의 일 차원 N
[0이다 std::rank<T>::value
). 다른 유형의 경우 또는 T
첫 번째 차원을 따라 알 수없는 바인딩의 배열 N
이고 0 인 경우 값은 0입니다.
T
일부 유형의 배열 인 경우 X
멤버 typedef 유형을 같게 제공하고 X
그렇지 않으면 type은 T
입니다. 경우 유의 T
다차원 배열이고, 첫 번째 차원을 제거한다.
std::remove_all_extents<T>::type
경우 T
어떤 종류의 다차원 배열 X
, 동일한 입력 멤버 typedef에 제공 X
그렇지 타입이다 T
.
다차원 배열의 모든 차원에서 길이를 얻으려면와 decltype
결합하는 데 사용할 수 있습니다 std::extent
. 예를 들면 다음과 같습니다.
#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, 다차원 배열의 총 요소 수를 가져옵니다.
constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);
또는 함수 템플릿에 넣으십시오.
#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;
}
그것들을 사용하는 방법에 대한 더 많은 예는 링크를 따라 찾을 수 있습니다.
TR1 / C ++ 11 / C ++ 17 방법도 있습니다 (참조 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
C ++에서 std :: array 클래스를 사용하여 배열을 선언하면 배열의 크기와 마지막 요소를 쉽게 찾을 수 있습니다.
#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;
}
실제로 배열 클래스에는 배열을 표준 컨테이너로 사용할 수있는 다른 함수가 많이 있습니다.
참조 1 ~ C ++ std :: array 클래스
참조 2 ~ std :: array 클래스
참조의 예제가 도움이됩니다.
이것은 꽤 오래되고 전설적인 질문이며 이미 많은 놀라운 답변이 있습니다. 그러나 시간이 지남에 따라 언어에 새로운 기능이 추가되고 있으므로 사용 가능한 새로운 기능에 따라 계속 업데이트해야합니다.
방금 C ++ 20에 대해 언급하지 않은 사람이 있습니다. 답을 쓰려고 생각했습니다.
C ++ 20에는 배열 길이를 찾기 위해 표준 라이브러리에 새로운 더 나은 방법이 추가되었습니다 std:ssize()
. 이 함수는를 반환합니다 signed value
.
#include <iostream>
int main() {
int arr[] = {1, 2, 3};
std::cout << std::ssize(arr);
return 0;
}
C ++ 17에서는에 std::size()
정의 된 것과 동일한 더 나은 방법 (그 당시)이 있었습니다 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이 방법은 vector
.
이 전통적인 접근 방식은 이미 많은 다른 답변에서 언급되었습니다.
#include <iostream>
int main() {
int array[] = { 1, 2, 3 };
std::cout << sizeof(array) / sizeof(array[0]);
return 0;
}
참고로 배열이 다른 함수에 전달 될 때 왜이 접근법 이 작동하지 않는지 궁금하다면 . 그 이유는,
배열은 C ++에서 값으로 전달되지 않고 대신 배열에 대한 포인터가 전달됩니다. 경우에 따라 전체 어레이를 전달하는 데 비용이 많이들 수 있습니다. 배열을 함수에 전달하고 배열을 변경 한 다음 주 배열을 다시 인쇄하여이를 테스트 할 수 있습니다. 업데이트 된 결과가 나타납니다.
그리고 이미 알고 있듯이 sizeof()
함수는 바이트 수를 제공하므로 다른 함수에서는 전체 배열이 아닌 포인터에 할당 된 바이트 수를 반환합니다. 따라서이 방법은 효과가 없습니다.
그러나 귀하의 요구 사항에 따라이 작업을 수행하는 좋은 방법을 찾을 수 있다고 확신합니다.
행복한 코딩.
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;
다음 중 하나 구현 ArraySize
에서 구글 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)는 sizeof (arr) (배열의 바이트 수)와 sizeof (* (arr)) (한 배열 요소의 바이트 수)를 검사하여 작동합니다. 전자가 후자로 나눌 수 있다면, 아마도 arr은 실제로 배열 일 것입니다.이 경우 나누기 결과는 배열의 요소 수입니다. 그렇지 않으면 arr은 배열이 될 수 없으며 코드가 컴파일되지 않도록 컴파일러 오류를 생성합니다.
bool의 크기는 구현에 따라 정의되므로 최종 결과의 유형이 size_t인지 확인하려면! (sizeof (a) & sizeof (* (a)))를 size_t로 캐스팅해야합니다.
이 매크로는 포인터 크기를 포인트 크기로 나눌 수있는 특정 포인터를 잘못 받아들이므로 완벽하지 않습니다. 우리의 모든 코드는 포인터가 4 바이트 인 32 비트 컴파일러를 거쳐야하기 때문에 크기가 3 이상이거나 4보다 큰 유형에 대한 모든 포인터는 (의롭게) 거부됩니다.
int nombres[5] = { 9, 3 };
이 함수가 반환 5
됩니다 2
.
sizeof(array_name)
전체 배열 sizeof(int)
의 크기를 제공하고 모든 배열 요소의 데이터 유형 크기를 제공합니다.
따라서 전체 배열의 크기를 배열의 단일 요소 크기로 나누면 배열의 길이 가됩니다.
int array_name[] = {1, 2, 3, 4, 5, 6};
int length = sizeof(array_name)/sizeof(int);
답변 :
int number_of_elements = sizeof(array)/sizeof(array[0])
설명 :
컴파일러는 각 유형의 데이터에 대해 특정 크기의 메모리 청크를 설정하고 배열은 단순히 그 그룹이므로 배열의 크기를 데이터 유형의 크기로 나눕니다. 30 개의 문자열 배열이있는 경우 시스템은 배열의 각 요소 (문자열)에 대해 24 바이트를 따로 설정합니다. 30 개의 요소에서 총 720 바이트입니다. 720/24 == 30 개 요소 작고 엄격한 알고리즘은 다음과 같습니다.
int number_of_elements = sizeof(array)/sizeof(array[0])
이는 다음과 같습니다
number_of_elements = 720/24
사용자 정의 데이터 유형 인 경우에도 배열이 어떤 데이터 유형인지 알 필요는 없습니다.
방금 생각했지만 카운터 변수를 만들고 배열 크기를 [0] 위치에 저장하기로 결정했습니다. 함수에있는 대부분의 코드를 삭제했지만 루프를 종료하면 prime [0]에 'a'의 최종 값이 할당됩니다. 벡터를 사용해 보았지만 VS Express 2013은 그다지 좋아하지 않았습니다. 또한 'a'는 덮어 쓰기를 피하기 위해 한 번에 시작하고 [0]은 오류를 피하기 위해 처음에 초기화됩니다. 난 전문가가 아니에요.
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;
}
제네릭을 사용하는 좋은 솔루션 :
template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }
그런 다음 단순히 arraysize(_Array);
배열의 길이를 얻기 위해 호출 하십시오.
constexpr
가 수정되었습니다. inline
아니다. constexpr
그래도 꽤 현대적입니다. 테스트 프로그램이 다른 최신 기능을 사용하고 있지 않은지 확인하십시오. 여기서 변수에 의해 길이가 지정된 로컬 배열을 선언 할 수 있습니까? 두 개의 전역 배열로 시도하십시오.
오래된 g ++ 컴파일러의 경우이 작업을 수행 할 수 있습니다
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;
}
여기에 까다로운 솔루션을 제공합니다.
항상 length
첫 번째 요소에 저장할 수 있습니다 .
// malloc/new
arr[0] = length;
arr++;
// do anything.
int len = *(arr-1);
free(--arr);
비용은 당신이 --arr
호출 할 때 해야합니다free
arr
호환되는 유형 int
이고 배열이 유형의 최대 값보다 길지 않은 경우에만 작동 합니다. 예를 들어 파스칼 문자열은 실제로이 트릭을 사용하는 바이트 배열입니다. 파스칼에서 문자열의 최대 길이는 255 자입니다.
다음과 같이 배열의 길이를 찾을 수 있습니다.
int arr[] = {1, 2, 3, 4, 5, 6};
int size = *(&arr + 1) - arr;
cout << "Number of elements in arr[] is "<< size;
return 0;
이 스 니펫을 간단히 사용할 수 있습니다.
#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;
}
그리고 여기에 참조가 있습니다 : http://www.cplusplus.com/reference/array/array/size/
개인적으로 (어떤 이유로 든 특수 함수로 작업 할 수없는 경우) 일반적으로 사용하는 값보다 배열 유형 호환성을 확장하는 것이 좋습니다 (값을 ≥ 0으로 저장하는 경우).
unsigned int x[] -> int x[]
배열 1 요소를 필요한 것보다 크게 만드는 것보다. 마지막 요소의 경우 확장 유형 지정자에 포함 된 일부 유형을 배치하지만 이전 예제를 사용하여 일반적으로 사용하지 않는 일부 유형은 -1입니다. for 루프를 사용하여 배열의 마지막 요소를 찾을 수 있습니다.
이것을 찾는 가장 일반적인 이유 중 하나는 배열을 함수에 전달하고 크기에 대해 다른 인수를 전달할 필요가 없기 때문입니다. 일반적으로 배열 크기가 동적이기를 원합니다. 이 배열에는 프리미티브가 아닌 객체가 포함될 수 있으며 size_of ()가 개수를 계산하는 안전하지 않은 옵션이 될 수 있습니다.
다른 사람들이 제안했듯이 기본 배열 대신 std :: vector 또는 list 등을 사용하는 것이 좋습니다. 그러나 오래된 컴파일러에서는 컨테이너를 채우는 데 많은 못생긴 push_back () 행이 필요하기 때문에 단순히 그렇게하는 것으로 원하는 최종 솔루션은 여전히 없습니다. 나와 같은 사람이라면 익명의 객체가 포함 된 한 줄 솔루션을 원하십시오.
기본 배열 대신 STL 컨테이너 대안을 사용하는 경우이 SO 게시물을 초기화하는 방법으로 사용할 수 있습니다. 하드 코딩 된 요소로 std :: vector를 초기화하는 가장 쉬운 방법은 무엇입니까?
다음은 컴파일러와 플랫폼에서 보편적으로 작동하는 방법입니다.
객체 모음에 대한 컨테이너로 구조체 또는 클래스를 만듭니다. <<에 대한 연산자 과부하 함수를 정의하십시오.
class MyObject;
struct MyObjectList
{
std::list<MyObject> objects;
MyObjectList& operator<<( const MyObject o )
{
objects.push_back( o );
return *this;
}
};
구조체를 매개 변수로 사용하는 함수를 만들 수 있습니다. 예 :
someFunc( MyObjectList &objects );
그런 다음 다음과 같이 해당 함수를 호출 할 수 있습니다.
someFunc( MyObjectList() << MyObject(1) << MyObject(2) << MyObject(3) );
이렇게하면 동적으로 크기가 조정 된 객체 컬렉션을 하나의 깔끔한 라인으로 함수에 전달하고 전달할 수 있습니다!
페이지 상단에 전역 배열이 선언되어 있다고 가정 해 봅시다.
int global[] = { 1, 2, 3, 4 };
배열에 몇 개의 요소가 있는지 확인하려면 (C ++에서) 다음 코드를 입력하십시오.
sizeof(global) / 4;
sizeof (NAME_OF_ARRAY) / 4는 주어진 배열 이름의 요소 수를 돌려줍니다.