2016-01-16 21 views
6

tôi đang học vectơ và bối rối về cách mảng được sao chép để thevector đây"Một phần tử cuối cùng" có nghĩa là gì trong vectơ?

double p[] = {1, 2, 3, 4, 5}; 
std::vector<double> a(p, p+5); 

Tôi cũng biết std::vector<double> a(3,5); nghĩa 'nhường chỗ cho 3 và khởi tạo chúng bằng 5. Làm thế nào để công việc mã trên?

Điểm thứ hai là tôi đọc đoạn văn từ nơi tôi đã sao chép mã ở trên.

Hiểu điểm thứ hai là rất quan trọng khi làm việc với vectơ hoặc bất kỳ vùng chứa tiêu chuẩn nào khác. Chuỗi được kiểm soát luôn là được biểu thị dưới dạng [đầu tiên, một trong quá khứ cuối cùng) —không chỉ dành cho ctors, nhưng cũng cho mọi chức năng hoạt động trên một loạt các phần tử.

Tôi không biết ý nghĩa của số [first, one-past-last) là gì? Tôi biết toán học nhưng không biết tại sao/sao vector sao chép mảng theo cách này?

Edited

một câu hỏi khác liên quan

Chức năng thành viên end() trả về một iterator rằng "điểm" để one-past-the-last-element trong chuỗi. Lưu ý rằng dereferencing bộ lặp được trả lại bởi end() là bất hợp pháp và có kết quả không xác định.

Bạn có thể giải thích điều này one-past-the-last-element nó là gì? và tại sao?

+0

std :: vector có các hàm tạo quá tải đó là lý do tại sao mã trên hoạt động. và '[first, one-past-last)' có nghĩa là phần tử đầu tiên được bao gồm và một phần tử cuối cùng bị loại trừ, là con trỏ đến phần tử cuối + 1 –

+0

@AngelusMortis nhưng tại sao? và tôi cũng đã chỉnh sửa câu hỏi của mình. tải lại. – UnKnown

+0

đọc câu trả lời ngay bây giờ :), về cơ bản một con trỏ cuối cùng được sử dụng để xác định xem bạn đã kết thúc vectơ và quay trở lại làm đối tượng để kiểm tra và so sánh v.v. –

Trả lời

11

Không bao giờ dereference end() hoặc rend() từ các thùng chứa STL vì chúng không trỏ đến các thành phần hợp lệ.
Hình ảnh dưới đây có thể giúp bạn hình dung điều này.

enter image description here

Ưu điểm của một loạt mở một nửa là:
1. Xử lý dãy trống xảy ra khi bắt đầu() == end()
2. iterating trên các yếu tố có thể được trực giác thực hiện bằng cách kiểm tra cho đến khi iterator bằng end().

+1

(có thể là sẽ rõ ràng hơn với 0-4 thay vì 1-5 dưới dạng inidices) – deviantfan

+1

@UnKnown Vì 'i ++' được cho là tạo bản sao của' i' trước khi tăng nó trong khi '++ i' thì không. Điều này thực sự không quan trọng những ngày này mặc dù vì trình biên dịch có thể dễ dàng tối ưu hóa điều này. –

+0

'1. Xử lý các khoảng trống xảy ra khi bắt đầu() == end() 'bạn có thể khám phá không? – UnKnown

2

Hàm tạo của std::vector có một số tình trạng quá tải.

Đối std::vector<double> a(3,5); constructor điền được sử dụng:

explicit vector (size_type n); 
     vector (size_type n, const value_type& val, 
       const allocator_type& alloc = allocator_type()); 

này có một tham số size vì nó là tham số đầu tiên và một tham số tùy chọn và thứ ba, tham số thứ hai xác định giá trị mà bạn muốn cung cấp cho các đối tượng mới được tạo ra.

double p[] = {1, 2, 3, 4, 5}; 
std::vector<double> a(p, p+5); 

Sử dụng một tình trạng quá tải của các nhà xây dựng, cụ thể là dãy nhà xây dựng:

template <class InputIterator> 
    vector (InputIterator first, InputIterator last, 
      const allocator_type& alloc = allocator_type()); 

này có một iterator để khởi đầu của một bộ sưu tập và end() iterator và đi qua và thêm vào vector cho đến khi first == last.

Lý do tại sao end() được thực hiện như one-past-the-last-element là bởi vì này cho phép triển khai để kiểm tra bình đẳng như:

while(first != last) 
{ 
    //savely add value of first to vector 
    ++first; 
} 
+0

+1 trong khi lop. Chỉ để xác nhận. nếu kết thúc cuối cùng mà không có 'một-quá khứ' thì 5 có thể bỏ qua trong mảng của tôi? – UnKnown

+0

@UnKnown Nếu 'end()' được dự kiến ​​sẽ không trỏ 'one-past' thì hàm tạo sẽ đọc một trong quá khứ mảng thực sự, một thứ không mong muốn. –

+0

bạn có thể cho tôi liên kết có thể xóa tất cả câu hỏi hoặc sự nhầm lẫn của tôi liên quan đến câu hỏi này không? bởi vì tôi lại bị nhầm lẫn về cách mà người thu âm có thể đọc qua một mảng thực sự? – UnKnown

3

cùng mạnh mẽ với container (ví dụ vector, danh sách, bản đồ) là khái niệm của vòng lặp. Trình lặp là một trừu tượng C++ của một con trỏ. I E. một iterator trỏ đến một đối tượng bên trong thùng chứa (hoặc đến một phần tử cuối cùng), và dereferencing iterator có nghĩa là truy cập vào phần tử đó.

Cho phép lấy ví dụ một vector của 4 yếu tố:

| 0 | 1 | 2 | 3 | | 
^  ^^
    |   | | 
    |   | one past the end (outside of the container elements) 
    |   last element   
    first element 

The (thuật toán trong) tiêu chuẩn thư viện mẫu hoạt động trên phạm vi, chứ không phải trên container. Bằng cách này, bạn có thể áp dụng các hoạt động, không chỉ cho toàn bộ vùng chứa, mà còn cho các phạm vi (các phần tử liên tiếp của vùng chứa).

Phạm vi được chỉ định bởi [first, last) (bao gồm lần đầu tiên, độc quyền cuối cùng). Đó là lý do tại sao bạn cần một iterator đến một trong quá khứ kết thúc: để xác định một phạm vi bằng toàn bộ nội dung của container. Nhưng khi mà điểm lặp đó bên ngoài nó, nó là bất hợp pháp để dereference nó.

0

Bộ lặp là trừu tượng của con trỏ.

Khoảng thời gian nửa mở [a,b) được định nghĩa là tất cả các thành phần x>=ax<b. Lợi thế của nó là [a,a) được xác định rõ ràng và trống cho bất kỳ a nào.

Mọi thứ có thể được tăng lên và so sánh bằng nhau có thể xác định khoảng thời gian mở một nửa. Vì vậy, [ptr1,ptr2) là phần tử ptr1 rồi ptr1+1 rồi ptr1+2 cho đến khi bạn đạt đến ptr2, nhưng không bao gồm ptr2.

Đối với các trình vòng lặp, nó tương tự - ngoại trừ chúng tôi không luôn có quyền truy cập ngẫu nhiên. Vì vậy, chúng tôi nói về next thay vì +1.

Con trỏ vẫn được tính là trình lặp loại.

Một loạt các trình lặp hoặc con trỏ "nói về" các yếu tố được trỏ tới. Vì vậy, khi một vectơ lấy một cặp các trình vòng lặp (đầu tiên, và một-qua-the-end), nó định nghĩa một khoảng thời gian nửa mở của các trình vòng lặp, cũng định nghĩa một tập các giá trị mà chúng trỏ đến.

Bạn có thể tạo véc-tơ từ phạm vi nửa mở như vậy. Nó sao chép các phần tử poimtrd vào trong vectơ.

Các vấn đề liên quan