Có cách nào để tìm một mảng có bao nhiêu giá trị không? Phát hiện xem tôi có đạt đến cuối mảng hay không cũng sẽ hoạt động.
Có cách nào để tìm một mảng có bao nhiêu giá trị không? Phát hiện xem tôi có đạt đến cuối mảng hay không cũng sẽ hoạt động.
Câu trả lời:
Nếu bạn có nghĩa là một mảng kiểu C, thì bạn có thể làm một cái gì đó như:
int a[7];
std::cout << "Length of array = " << (sizeof(a)/sizeof(*a)) << std::endl;
Điều này không hoạt động trên con trỏ (tức là nó sẽ không hoạt động cho một trong những điều sau đây):
int *p = new int[7];
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
hoặc là:
void func(int *p)
{
std::cout << "Length of array = " << (sizeof(p)/sizeof(*p)) << std::endl;
}
int a[7];
func(a);
Trong C ++, nếu bạn muốn loại hành vi này, thì bạn nên sử dụng một lớp container; lẽ std::vector
.
Như những người khác nói bạn có thể sử dụng sizeof(arr)/sizeof(*arr)
nhưng điều này sẽ cung cấp cho bạn câu trả lời sai cho các loại con trỏ không phải là mảng.
template<class T, size_t N>
constexpr size_t size(T (&)[N]) { return N; }
Điều này có đặc tính tốt là không biên dịch cho các kiểu không phải là mảng (visual studio có _countof
cái này). Điều constexpr
này làm cho biểu thức thời gian biên dịch này để nó không có bất kỳ nhược điểm nào đối với macro (ít nhất là không có gì tôi biết).
Bạn cũng có thể xem xét sử dụng std::array
từ C ++ 11 để lộ độ dài của nó mà không có chi phí trên một mảng C gốc.
C ++ 17 có std::size()
trong <iterator>
tiêu đề cũng làm như vậy và cũng hoạt động với các thùng chứa STL (nhờ @Jon C ).
T(arg&)[N]
.
extent
, nhìn vào nó bây giờ có hai đặc điểm với nó làm cho nó ít hữu ích hơn chức năng trên (đối với usecase này). (1) Nó trả về 0 cho con trỏ (thay vì lỗi biên dịch). (2) Nó yêu cầu một tham số loại vì vậy để kiểm tra một biến bạn sẽ phải làmdecltype
Làm sizeof( myArray )
sẽ giúp bạn có tổng số byte được phân bổ cho mảng đó. Sau đó, bạn có thể tìm ra số lượng phần tử trong mảng bằng cách chia cho kích thước của một phần tử trong mảng:sizeof( myArray[0] )
Mặc dù đây là một câu hỏi cũ, nhưng nó đáng để cập nhật câu trả lời cho C ++ 17. Trong thư viện tiêu chuẩn hiện có hàm templated std::size()
, trả về số lượng phần tử trong cả thùng chứa std hoặc mảng kiểu C. Ví dụ:
#include <iterator>
uint32_t data[] = {10, 20, 30, 40};
auto dataSize = std::size(data);
// dataSize == 4
Có cách nào để tìm một mảng có bao nhiêu giá trị không?
Đúng!
Thử sizeof(array)/sizeof(array[0])
Phát hiện xem tôi có đạt đến cuối mảng hay không cũng sẽ hoạt động.
Tôi không thấy bất kỳ cách nào cho việc này trừ khi mảng của bạn là một mảng các ký tự (tức là chuỗi).
PS: Trong C ++ luôn sử dụng std::vector
. Có một số chức năng sẵn có và một chức năng mở rộng.
std::vector
có một phương thức size()
trả về số lượng phần tử trong vectơ.
(Vâng, đây là câu trả lời trực tiếp)
#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;
}
Kể từ C ++ 11, một số mẫu mới được giới thiệu để giúp giảm đau khi xử lý độ dài mảng. Tất cả chúng được định nghĩa trong tiêu đề <type_traits>
.
Nếu T
là một kiểu mảng, cung cấp giá trị hằng số thành viên bằng số lượng kích thước của mảng. Đối với bất kỳ loại nào khác, giá trị là 0.
Nếu T
là một kiểu mảng, cung cấp giá trị hằng số thành viên bằng số lượng phần tử dọc theo N
chiều thứ của mảng, nếu N
nằm trong [0, std::rank<T>::value
). Đối với bất kỳ loại nào khác, hoặc nếu T
là mảng không xác định được ràng buộc dọc theo chiều thứ nhất của nó và N
là 0, giá trị là 0.
Nếu T
là một mảng của một số loại X
, cung cấp loại typedef thành viên bằng X
, nếu không thì loại là T
. Lưu ý rằng nếu T
là một mảng nhiều chiều, chỉ có thứ nguyên đầu tiên được loại bỏ.
std::remove_all_extents<T>::type
Nếu T
là một mảng nhiều chiều của một số loại X
, cung cấp loại typedef thành viên bằng X
, nếu không thì loại là T
.
Để có được độ dài trên bất kỳ kích thước nào của mảng đa chiều, decltype
có thể được sử dụng để kết hợp với std::extent
. Ví dụ:
#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, để có được tổng số phần tử trong một mảng nhiều chiều:
constexpr auto l = sizeof(a) / sizeof(std::remove_all_extents<decltype(a)>::type);
Hoặc đặt nó trong một mẫu chức năng:
#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;
}
Có thể tìm thấy nhiều ví dụ về cách sử dụng chúng bằng cách theo các liên kết.
Ngoài ra còn có cách TR1 / C ++ 11 / C ++ 17 (xem nó 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
Thay vì sử dụng hàm dựng sẵn trong mảng aka:
int x[3] = {0, 1, 2};
bạn nên sử dụng lớp mảng và mẫu mảng. Thử:
#include <array>
array<type_of_the_array, number_of_elements_in_the_array> Name_of_Array = {};
Vì vậy, bây giờ nếu bạn muốn tìm độ dài của mảng, tất cả những gì bạn phải làm là sử dụng hàm size trong lớp mảng.
Name_of_Array.size();
và điều đó sẽ trả về độ dài của các phần tử trong mảng.
Trong C ++, sử dụng lớp std :: mảng để khai báo một mảng, người ta có thể dễ dàng tìm thấy kích thước của một mảng và cũng là phần tử cuối cùng.
#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;
}
Trong thực tế, lớp mảng có rất nhiều hàm khác cho phép chúng ta sử dụng mảng một thùng chứa tiêu chuẩn.
Tham chiếu 1 đến C ++ std :: lớp mảng
Tham chiếu 2 đến std :: lớp mảng
Các ví dụ trong tài liệu tham khảo rất hữu ích.
Đây là câu hỏi khá cũ và huyền thoại và đã có nhiều câu trả lời tuyệt vời ngoài kia. Nhưng theo thời gian, có các chức năng mới được thêm vào các ngôn ngữ, vì vậy chúng tôi cần tiếp tục cập nhật mọi thứ theo các tính năng mới có sẵn.
Tôi chỉ nhận thấy bất kỳ ai chưa được đề cập về C ++ 20. Vì vậy, suy nghĩ để viết câu trả lời.
Trong C ++ 20, có một cách mới tốt hơn được thêm vào thư viện chuẩn để tìm độ dài của mảng tức là std:ssize()
. Hàm này trả về a signed value
.
#include <iostream>
int main() {
int arr[] = {1, 2, 3};
std::cout << std::ssize(arr);
return 0;
}
Trong C ++ 17, có một cách tốt hơn (tại thời điểm đó) cho cùng một std::size()
định nghĩa được xác định trong 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 Phương pháp này cũng hoạt động vector
.
Cách tiếp cận truyền thống này đã được đề cập trong nhiều câu trả lời khác.
#include <iostream>
int main() {
int array[] = { 1, 2, 3 };
std::cout << sizeof(array) / sizeof(array[0]);
return 0;
}
Chỉ cần FYI, nếu bạn tự hỏi tại sao phương pháp này không hoạt động khi mảng được chuyển sang chức năng khác . Lý do là,
Một mảng không được truyền theo giá trị trong C ++, thay vào đó con trỏ tới mảng được truyền. Như trong một số trường hợp vượt qua toàn bộ mảng có thể là hoạt động tốn kém. Bạn có thể kiểm tra điều này bằng cách chuyển mảng đến một số hàm và thực hiện một số thay đổi cho mảng ở đó và sau đó in lại mảng trong main. Bạn sẽ nhận được kết quả cập nhật.
Và như bạn đã biết, sizeof()
hàm cho số byte, do đó, trong hàm khác, nó sẽ trả về số byte được phân bổ cho con trỏ thay vì toàn bộ mảng. Vì vậy, phương pháp này không hiệu quả.
Nhưng tôi chắc chắn rằng bạn có thể tìm thấy một cách tốt để làm điều này, theo yêu cầu của bạn.
Chúc mừng mã hóa.
Bạn có một loạt các tùy chọn được sử dụng để có được kích thước mảng 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;
Đây là một triển khai ArraySize
từ 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 (mảng) hoạt động bằng cách kiểm tra sizeof (mảng) (số byte trong mảng) và sizeof (* (mảng)) (số byte trong một thành phần mảng). Nếu cái trước chia hết cho cái sau, có lẽ mảng thực sự là một mảng, trong trường hợp đó kết quả chia là # của các phần tử trong mảng. Mặt khác, mảng không thể là một mảng và chúng tôi tạo ra lỗi trình biên dịch để ngăn mã biên dịch.
Vì kích thước của bool được xác định theo triển khai, chúng ta cần truyền! (Sizeof (a) & sizeof (* (a))) sang size_t để đảm bảo kết quả cuối cùng có loại size_t.
Macro này không hoàn hảo vì nó chấp nhận sai các con trỏ nhất định, cụ thể là kích thước con trỏ chia hết cho kích thước con trỏ. Vì tất cả mã của chúng tôi phải đi qua trình biên dịch 32 bit, trong đó con trỏ là 4 byte, điều này có nghĩa là tất cả các con trỏ tới một loại có kích thước là 3 hoặc lớn hơn 4 sẽ bị từ chối (chính xác).
int nombres[5] = { 9, 3 };
hàm này trả về 5
thay vì 2
.
Đối với C ++ / CX (khi viết ví dụ ứng dụng UWP sử dụng C ++ trong Visual Studio), chúng ta có thể tìm thấy số lượng giá trị trong một mảng bằng cách sử dụng size()
hàm.
Mã nguồn:
string myArray[] = { "Example1", "Example2", "Example3", "Example4" };
int size_of_array=size(myArray);
Nếu bạn cout
là size_of_array
đầu ra sẽ là:
>>> 4
sizeof(array_name)
đưa ra kích thước của toàn bộ mảng và sizeof(int)
đưa ra kích thước của kiểu dữ liệu của mọi thành phần mảng.
Vì vậy, chia kích thước của toàn bộ mảng cho kích thước của một phần tử duy nhất của mảng sẽ cho chiều dài của mảng.
int array_name[] = {1, 2, 3, 4, 5, 6};
int length = sizeof(array_name)/sizeof(int);
TRẢ LỜI :
int number_of_elements = sizeof(array)/sizeof(array[0])
GIẢI THÍCH :
Vì trình biên dịch đặt một đoạn bộ nhớ kích thước cụ thể sang một bên cho từng loại dữ liệu và một mảng chỉ đơn giản là một nhóm trong số đó, bạn chỉ cần chia kích thước của mảng cho kích thước của loại dữ liệu. Nếu tôi có một mảng gồm 30 chuỗi, hệ thống của tôi sẽ dành 24 byte cho mỗi phần tử (chuỗi) của mảng. Với 30 phần tử, đó là tổng cộng 720 byte. 720/24 == 30 yếu tố. Thuật toán nhỏ, chặt chẽ cho điều đó là:
int number_of_elements = sizeof(array)/sizeof(array[0])
tương đương với
number_of_elements = 720/24
Lưu ý rằng bạn không cần biết loại dữ liệu đó là gì, ngay cả khi đó là loại dữ liệu tùy chỉnh.
Chỉ là một ý nghĩ, nhưng chỉ quyết định tạo một biến đếm và lưu trữ kích thước mảng ở vị trí [0]. Tôi đã xóa hầu hết các mã tôi có trong hàm nhưng bạn sẽ thấy sau khi thoát khỏi vòng lặp, số nguyên tố [0] được gán giá trị cuối cùng là 'a'. Tôi đã thử sử dụng vectơ nhưng VS Express 2013 không thích điều đó lắm. Ngoài ra, hãy lưu ý rằng 'a' bắt đầu tại một để tránh ghi đè [0] và nó được khởi tạo ngay từ đầu để tránh lỗi. Tôi không phải là chuyên gia, chỉ nghĩ tôi muốn chia sẻ.
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;
}
Một giải pháp tốt sử dụng thuốc generic:
template <typename T,unsigned S>
inline unsigned arraysize(const T (&v)[S]) { return S; }
Sau đó, chỉ cần gọi arraysize(_Array);
để có được chiều dài của mảng.
constexpr
là bản sửa lỗi. inline
không phải. constexpr
là khá hiện đại mặc dù. Bạn có chắc chắn chương trình thử nghiệm của bạn không sử dụng một tính năng hiện đại khác, nơi bạn có thể khai báo một mảng cục bộ có độ dài được đưa ra bởi một biến? Hãy thử nó với hai mảng toàn cầu.
Đối với trình biên dịch g ++ cũ, bạn có thể làm điều này
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;
}
Tôi cung cấp một giải pháp khó khăn ở đây:
Bạn luôn có thể lưu trữ length
trong phần tử đầu tiên:
// malloc/new
arr[0] = length;
arr++;
// do anything.
int len = *(arr-1);
free(--arr);
Chi phí là bạn phải có --arr
khi gọifree
arr
có loại tương thích int
và mảng không dài hơn giá trị tối đa của loại. Ví dụ, chuỗi Pascal thực sự là các mảng byte sử dụng thủ thuật này; độ dài tối đa của chuỗi trong Pascal là 255 ký tự.
bạn có thể tìm thấy độ dài của một mảng bằng cách sau:
int arr[] = {1, 2, 3, 4, 5, 6};
int size = *(&arr + 1) - arr;
cout << "Number of elements in arr[] is "<< size;
return 0;
Đơn giản là bạn có thể sử dụng đoạn trích này:
#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;
}
và đây là tài liệu tham khảo: http://www.cplusplus.com/reference/array/array/size/
Tránh sử dụng loại cùng với sizeof, vì sizeof(array)/sizeof(char)
, đột nhiên bị hỏng nếu bạn thay đổi loại mảng.
Trong studio hình ảnh, bạn có tương đương nếu sizeof(array)/sizeof(*array)
. Bạn chỉ cần gõ_countof(array)
Cá nhân tôi sẽ đề nghị (nếu bạn không thể làm việc với các chức năng chuyên biệt vì bất kỳ lý do gì) trước tiên hãy mở rộng khả năng tương thích kiểu mảng qua những gì bạn thường sử dụng nó như (nếu bạn đang lưu trữ các giá trị ≥ 0:
unsigned int x[] -> int x[]
hơn bạn sẽ làm cho phần tử mảng 1 lớn hơn bạn cần để làm cho nó. Đối với phần tử cuối cùng, bạn sẽ đặt một số loại được bao gồm trong trình xác định loại mở rộng nhưng bạn thường không sử dụng, ví dụ như sử dụng ví dụ trước, phần tử cuối cùng sẽ là -1. Điều này cho phép bạn (bằng cách sử dụng vòng lặp for) để tìm phần tử cuối cùng của một mảng.
Một trong những lý do phổ biến nhất mà bạn sẽ tìm kiếm điều này là vì bạn muốn truyền một mảng cho một hàm và không phải truyền một đối số khác cho kích thước của nó. Bạn cũng thường muốn kích thước mảng là động. Mảng đó có thể chứa các đối tượng, không phải là nguyên thủy và các đối tượng có thể phức tạp sao cho size_of () là một tùy chọn không an toàn để tính số đếm.
Như những người khác đã đề xuất, hãy xem xét sử dụng một std :: vector hoặc list, v.v. thay vì một mảng nguyên thủy. Tuy nhiên, trên các trình biên dịch cũ, bạn vẫn sẽ không có giải pháp cuối cùng mà bạn có thể muốn bằng cách thực hiện đơn giản như vậy, bởi vì việc điền vào container yêu cầu một loạt các dòng Push_back () xấu xí. Nếu bạn giống tôi, muốn có một giải pháp dòng duy nhất với các đối tượng ẩn danh có liên quan.
Nếu bạn đi với bộ chứa STL thay thế cho một mảng nguyên thủy, bài đăng SO này có thể được sử dụng cho bạn để khởi tạo nó: Cách dễ nhất để khởi tạo một std :: vector với các phần tử được mã hóa cứng là gì?
Đây là một phương pháp mà tôi đang sử dụng cho phương pháp này sẽ hoạt động phổ biến trên các trình biên dịch và nền tảng:
Tạo một cấu trúc hoặc lớp làm thùng chứa cho bộ sưu tập các đối tượng của bạn. Xác định hàm quá tải toán tử cho <<.
class MyObject;
struct MyObjectList
{
std::list<MyObject> objects;
MyObjectList& operator<<( const MyObject o )
{
objects.push_back( o );
return *this;
}
};
Bạn có thể tạo các hàm lấy cấu trúc của bạn làm tham số, ví dụ:
someFunc( MyObjectList &objects );
Sau đó, bạn có thể gọi hàm đó, như thế này:
someFunc( MyObjectList() << MyObject(1) << MyObject(2) << MyObject(3) );
Bằng cách đó, bạn có thể xây dựng và chuyển một bộ sưu tập các đối tượng có kích thước động đến một hàm trong một dòng sạch duy nhất!
Hãy nói rằng bạn có một mảng toàn cầu được khai báo ở đầu trang
int global[] = { 1, 2, 3, 4 };
Để tìm hiểu có bao nhiêu phần tử (trong c ++) trong mảng, nhập mã sau đây:
sizeof(global) / 4;
Sizeof (NAME_OF_ARRAY) / 4 sẽ trả lại cho bạn số phần tử cho tên mảng đã cho.