Làm thế nào để tôi tìm thấy chiều dài của một mảng?


539

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.


22
Mảng đến từ đâu? Thông thường các hàm lấy mảng cũng lấy tham số độ dài để xử lý vấn đề này.
Michael Myers

2
Chà, tôi đang tạo một chương trình "mad libs" có một mảng với tất cả các văn bản, cũng như vị trí của các danh từ / động từ mà người dùng phải điền vào. Tôi muốn sử dụng một chức năng để chạy qua toàn bộ mảng, thay thế các giá trị "[danh từ]" và "[động từ]" bằng văn bản được nhập bởi người dùng.
Tối đa


5
Xin lưu ý rằng trong mảng C không phải là đối tượng hoặc cấu trúc. Như vậy, chúng không có tham số độ dài được lưu trữ ở bất cứ đâu theo mặc định. Nếu bạn muốn làm việc với chúng như các đối tượng trong C ++, hãy sử dụng các đối tượng C ++ std :: vector hoặc std :: mảng của C ++ 11 nếu bạn có thể. Nếu bạn phải sử dụng các con trỏ, luôn luôn chuyển chiều dài của mảng làm tham số thứ hai cho mọi hàm hoạt động với nó.
Pihhan

Nếu bạn đang sử dụng C ++ 20, thì tôi cũng đã thêm câu trả lời cho điều đó. Nó có thể bị bỏ qua dễ dàng vì có rất nhiều câu trả lời ở đây.
gprathour

Câu trả lời:


511

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.


86
Nó cũng không hoạt động nếu bạn chuyển mảng sang một chức năng khác và cố gắng thực hiện nó ở đó :)
San Jacinto

23
@San Jacinto: Không, điều này hoạt động (trên mảng ) cho dù bạn đang ở chức năng nào. Truyền một mảng có độ dài thay đổi cho một hàm làm tham số, tuy nhiên, không thể (nó phân rã thành một con trỏ) - nhưng nếu bạn vượt qua mảng bên trong một cấu trúc, sau đó điều này hoạt động như mong đợi.
eq-

1
@OliverCharlesworth cũng vậy nếu bạn chuyển mảng theo giá trị sang hàm khác và thử nó ở đó, nó sẽ không hoạt động, phải không? Câu hỏi đặt ra là tại sao
A_Matar

5
@A_Matar - Bạn không thể vượt qua một mảng theo giá trị trong C hoặc C ++.
Oliver Charlesworth

1
@yusha - Chúng giống nhau.
Oliver Charlesworth

142

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ó _countofcái này). Điều constexprnà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::arraytừ C ++ 11 để lộ độ dài của nó mà không có chi phí trên một mảng C gốc.

C ++ 17std::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 ).


3
@yau đó là cách bạn viết một tham chiếu đến một mảng , xem câu trả lời này . Phiên bản của tôi trông hơi khác một chút vì tôi đã bỏ qua tên của tham số vì tham số không được sử dụng, chỉ cần loại của nó. Với một cái tên, nó sẽ là T(arg&)[N].
Motti

1
Cảm ơn Motti! Tên tham số bên trái đã rõ ràng với tôi. Nhưng không thể tin được rằng rõ ràng là tôi không sử dụng ref / con trỏ cho mảng trước đây. Và có lẽ sẽ không có trong tương lai, vì các mảng như vậy sẽ còn nhiều hơn nữa.
yau


1
Nếu sử dụng C ++ 11 không phải là std :: thì một giải pháp tốt hơn ???? en.cppreference.com/w/cpp/types/extent
Isaac Pascual

2
@IsaacPascual Tôi không quen thuộc 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
Motti

86

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] )


3
Đây là một giải pháp rất đơn giản và dễ dàng để khắc phục những gì dường như là một vấn đề lâu đời.

4
Không hoạt động cho các mảng "mới" của C ++ được giữ bởi một con trỏ. Bạn nhận được kích thước của con trỏ (4 byte) hoặc kích thước của phần tử đầu tiên của nó nếu bạn bỏ qua nó.
DragonLord

1
@DragonLord có, mặc dù bất kỳ ai khai báo kích thước của mảng bằng từ khóa mới sẽ biết kích thước của mảng khi chạy, vì vậy không cần phải sử dụng toán tử sizeof để tìm kích thước của mảng trong trường hợp đó. Tôi chắc rằng bạn biết điều đó. Điều này chỉ vì lợi ích của bất cứ ai không.
Martyn Shutt

@surega Nó sẽ không sụp đổ
CITBL

60

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

58

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.


Điều này sẽ không hoạt động đối với các kích thước mảng riêng lẻ khác nhau
Don Larynx 27/12/14

4
+1 cho vectơ. Có rất ít trường hợp mạnh để sử dụng mảng C ++ kiểu cũ nữa. Trừ khi kích thước của mảng sẽ không bao giờ thay đổi, nhưng ngay cả khi đó, bạn nên sử dụng lớp container mảng thay thế. Tốt hơn là sử dụng một lớp container như vector để lưu trữ mảng động. Ưu điểm của việc sử dụng các lớp container vượt xa các nhược điểm của việc phải quản lý bộ nhớ của riêng bạn.
Martyn Shutt

@MartynShutt Khi bạn bị ràng buộc bộ nhớ cache, như trong gamedev, đôi khi bạn không thể sử dụng một vectơ.
Tara

30

std::vectorcó 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)


10
Lưỡi có thể có, nhưng nó gần như chắc chắn là cách tiếp cận đúng.
Jerry Coffin

Tại sao bạn nói đó là lưỡi trong má? Đối với tôi (một người mới chơi c ++) có vẻ như đó là câu trả lời đúng.
dbliss

6
@dbliss Đó là câu nói hay vì OP đã hỏi về độ dài của một mảng và eq- cho họ biết làm thế nào để có được độ dài của một vectơ , đó là một điều khác biệt trong C ++. Tuy nhiên, điều đó đúng ở mức sâu hơn bởi vì nếu bạn cần lấy độ dài khi chạy, vectơ là lựa chọn tốt hơn nhiều .
poolie

Bạn cũng có thể sử dụng std :: list hoặc một số container khác mà tôi tin.
BuvinJ

1
Điều đặc biệt tuyệt vời về câu trả lời này là bạn có thể khởi tạo một vectơ hoặc danh sách với một mảng bằng chữ.
BuvinJ

26
#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;
}

10
Tôi tin rằng cái này chỉ hoạt động cho các biến cục bộ trên stack.
DragonLord

Đây là câu trả lời tốt nhất. @DragonLord, nó cũng hoạt động cho các vars thành viên. Xem cpp.sh/92xvv .
Shital Shah

24

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>.

  • std::rank<T>::value

    Nếu Tlà 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.

  • std::extent<T, N>::value

    Nếu Tlà 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 Nchiều thứ của mảng, nếu Nnằm trong [0, std::rank<T>::value). Đối với bất kỳ loại nào khác, hoặc nếu Tlà mảng không xác định được ràng buộc dọc theo chiều thứ nhất của nó và Nlà 0, giá trị là 0.

  • std::remove_extent<T>::type

    Nếu Tlà 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 Tlà 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 Tlà 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, decltypecó 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.


18

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

9

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.


6

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.


2
Đẹp; Tôi thấy bạn có nhiều kỹ năng; và ... cách tiếp cận tuyệt vời. Tôi nghĩ cũng nên viết nhiều câu trả lời cho những câu hỏi nổi tiếng như vậy ;-)
GhostCat

5

Đâ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.

C ++ 20

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;
}

C ++ 17

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.


4

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;

3

Đây là một triển khai ArraySizetừ 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).


với một mảng số nguyên như sau: int nombres[5] = { 9, 3 };hàm này trả về 5thay vì 2.
Anwar

GOOGLE_ARRAYSIZE(new int8_t)trả 8về env thử nghiệm của tôi, thay vì tăng lỗi. Phần đúc có vẻ dư thừa, không đề cập đến macro C la hét. sizeof(a) / sizeof(*a)cách làm việc đủ như là giải pháp di sản.

3

Đố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 coutsize_of_arrayđầu ra sẽ là:

>>> 4

3

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);

Mặc dù đoạn mã này có thể giải quyết vấn đề, nhưng nó không giải thích tại sao hoặc làm thế nào để trả lời câu hỏi. Vui lòng bao gồm một lời giải thích cho mã của bạn, vì điều đó thực sự giúp cải thiện chất lượng bài đăng của bạn. Hãy nhớ rằng bạn sẽ trả lời câu hỏi cho độc giả trong tương lai và những người đó có thể không biết lý do cho đề xuất mã của bạn
Balagurunathan Marimuthu

3

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.


Không cần đến cách tiếp cận dễ bị lỗi thời và lỗi thời này vào năm 2019. stackoverflow.com/a/59109106/560648 Ngoài ra, đây chỉ là một bản sao của các câu trả lời hiện có.
Các cuộc đua nhẹ nhàng trong quỹ đạo

Tuy nhiên, nó đơn giản, hùng hồn, nhanh chóng, yêu cầu thấp, nền tảng độc lập và loại bỏ sự cần thiết phải bao gồm vectơ hoặc con trỏ. Theo như những câu trả lời khác, dường như chỉ có một câu trả lời khác có cùng thuật toán và người ta không đưa ra lời giải thích nào về cơ chế cơ bản của vấn đề như câu trả lời của tôi. Tôi trân trọng đề nghị rằng, thay vì dễ bị lỗi, nó khá mạnh mẽ.
Bob Warner

1

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;
}

1

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.

Nguồn


@bobbogo Hoạt động với nội tuyến hoặc constexpr, có thể bạn đã tắt nội tuyến hoặc nó là tùy chọn? ideone.com/VxogJ4
QuentinUK

@QentinUK constexprlà bản sửa lỗi. inlinekhông phải. constexprlà 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.
bobbogo

1

Đố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;
}

Đây là câu trả lời chính xác. Rất di động giữa các phiên bản C ++, không hoạt động với con trỏ, cộng với câu trả lời có sẵn tại thời gian biên dịch
bobbogo

1

Tôi cung cấp một giải pháp khó khăn ở đây:

Bạn luôn có thể lưu trữ lengthtrong 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ó --arrkhi gọifree


2
Điều đó chỉ hoạt động khi arrcó loại tương thích intvà 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ự.
Palec

Tôi cho rằng người ta có thể dự trữ 8 byte ở đầu mỗi mảng và sử dụng một dấu dài nếu họ muốn lưu trữ các đối tượng. Tôi nghĩ rằng một vector có lẽ dễ dàng hơn. Nhưng chắc chắn là một giải pháp tốt cho các hệ thống nhúng.
aj.toulan

1

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 hóa thành (& mảng) [1] - mảng;
QuentinUK

1

Đơ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/


0

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)


0

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.


0

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!


-4

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.


8
sizeof (int) phụ thuộc vào nền tảng. Không có gì đảm bảo rằng nó sẽ là 4 (mặc dù đây là trường hợp phổ biến nhất)
người chiến thắng

Hơn bạn cho thêm.
miksiii

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.