Hoàn toàn để trả lời câu hỏi của bạn, bạn có thể sử dụng một trình vòng lặp:
std::vector<char> path;
// ...
for (std::vector<char>::const_iterator i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Nếu bạn muốn sửa đổi nội dung của vectơ trong vòng lặp for, thì hãy sử dụng iterator
chứ không phải const_iterator
.
Nhưng có rất nhiều điều có thể nói về điều này. Nếu bạn chỉ muốn một câu trả lời bạn có thể sử dụng, thì bạn có thể dừng ở đây; mặt khác, đọc tiếp
tự động (C ++ 11) / typedef
Đây không phải là một giải pháp khác, mà là một bổ sung cho iterator
giải pháp trên . Nếu bạn đang sử dụng tiêu chuẩn C ++ 11 (hoặc mới hơn), thì bạn có thể sử dụng auto
từ khóa để giúp dễ đọc:
for (auto i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
Nhưng loại i
sẽ không phải là const (tức là trình biên dịch sẽ sử dụng std::vector<char>::iterator
làm kiểu i
).
Trong trường hợp này, bạn cũng có thể chỉ sử dụng một typedef
(không giới hạn ở C ++ 11 và rất hữu ích để sử dụng):
typedef std::vector<char> Path;
Path path;
// ...
for (Path::const_iterator i = path.begin(); i != path.end(); ++i)
std::cout << *i << ' ';
quầy tính tiền
Tất nhiên, bạn có thể sử dụng loại số nguyên để ghi lại vị trí của mình trong for
vòng lặp:
for(int i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';
Nếu bạn định làm điều này, tốt hơn là sử dụng các loại thành viên của bộ chứa, nếu chúng có sẵn và phù hợp. std::vector
có một loại thành viên được gọi size_type
cho công việc này: đó là loại được trả về bởi size
phương thức.
// Path typedef'd to std::vector<char>
for( Path::size_type i=0; i<path.size(); ++i)
std::cout << path[i] << ' ';
Tại sao không chỉ sử dụng điều này trên các iterator
giải pháp? Đối với các trường hợp đơn giản, bạn cũng có thể, nhưng vấn đề là iterator
lớp là một đối tượng được thiết kế để thực hiện công việc này cho các đối tượng phức tạp hơn, nơi giải pháp này sẽ không lý tưởng.
dựa trên phạm vi cho vòng lặp (C ++ 11)
Xem giải pháp của Jefffrey . Trong C ++ 11 (và phiên bản mới hơn), bạn có thể sử dụng for
vòng lặp dựa trên phạm vi mới , trông giống như sau:
for (auto i: path)
std::cout << i << ' ';
Vì path
là một vectơ của các mục (rõ ràng std::vector<char>
), đối tượngi
là loại của mục của vectơ (tức là, rõ ràng, nó là loại char
). Đối tượng i
có một giá trị là một bản sao của mục thực tế trong path
đối tượng. Do đó, tất cả các thay đổi i
trong vòng lặp không được bảo tồn trong path
chính nó. Ngoài ra, nếu bạn muốn thực thi thực tế là bạn không muốn để có thể thay đổi giá trị sao chép của i
trong vòng lặp, bạn có thể buộc các loại i
là const char
như thế này:
for (const auto i: path)
std::cout << i << ' ';
Nếu bạn muốn sửa đổi các mục trong path
, bạn có thể sử dụng một tài liệu tham khảo:
for (auto& i: path)
std::cout << i << ' ';
và ngay cả khi bạn không muốn sửa đổi path
, nếu việc sao chép các đối tượng đắt tiền, bạn nên sử dụng tham chiếu const thay vì sao chép theo giá trị:
for (const auto& i: path)
std::cout << i << ' ';
std :: bản sao
Xem câu trả lời của Joshua . Bạn có thể sử dụng thuật toán STL std::copy
để sao chép nội dung vectơ vào luồng đầu ra. Đây là một giải pháp tao nhã nếu bạn cảm thấy thoải mái với nó (và bên cạnh đó, nó rất hữu ích, không chỉ trong trường hợp in nội dung của một vectơ).
std :: for_each
Xem giải pháp của Max . Sử dụngstd::for_each
là quá mức cần thiết cho kịch bản đơn giản này, nhưng nó là một giải pháp rất hữu ích nếu bạn muốn làm nhiều hơn là chỉ in ra màn hình: sử dụng std::for_each
cho phép bạn thực hiện bất kỳ thao tác (hợp lý) nào trên nội dung vectơ.
quá tải Ostream :: toán tử <<
Xem câu trả lời của Chris , đây là phần bổ sung cho các câu trả lời khác vì bạn vẫn sẽ cần phải thực hiện một trong những giải pháp ở trên trong tình trạng quá tải. Trong ví dụ của mình, anh ta đã sử dụng một bộ đếm trong một for
vòng lặp. Ví dụ, đây là cách bạn có thể nhanh chóng sử dụng giải pháp của Joshua :
template <typename T>
std::ostream& operator<< (std::ostream& out, const std::vector<T>& v) {
if ( !v.empty() ) {
out << '[';
std::copy (v.begin(), v.end(), std::ostream_iterator<T>(out, ", "));
out << "\b\b]";
}
return out;
}
Việc sử dụng bất kỳ giải pháp nào khác nên đơn giản.
phần kết luận
Bất kỳ giải pháp được trình bày ở đây sẽ làm việc. Tùy thuộc vào bạn và mã mà cái nào là "tốt nhất". Bất cứ điều gì chi tiết hơn điều này có lẽ là tốt nhất để lại cho một câu hỏi khác trong đó những ưu / nhược điểm có thể được đánh giá đúng; nhưng như mọi khi, sở thích của người dùng sẽ luôn đóng một phần: không có giải pháp nào được trình bày là sai, nhưng một số giải pháp sẽ đẹp hơn đối với mỗi lập trình viên riêng lẻ.
phụ lục
Đây là một giải pháp mở rộng của một giải pháp trước đó tôi đã đăng. Vì bài đăng đó tiếp tục được chú ý, tôi quyết định mở rộng về nó và tham khảo các giải pháp tuyệt vời khác đã được đăng ở đây. Bài viết gốc của tôi có một nhận xét đề cập rằng nếu bạn đang có ý định sửa đổi vectơ của mình trong một for
vòng lặp thì có hai phương thức được cung cấp std::vector
để truy cập các phần tử: std::vector::operator[]
không thực hiện kiểm tra giới hạn và std::vector::at
thực hiện kiểm tra giới hạn. Nói cách khác, at
sẽ ném nếu bạn cố gắng truy cập một phần tử bên ngoài vectơ và operator[]
sẽ không. Tôi chỉ thêm bình luận này, ban đầu, vì mục đích đề cập đến một cái gì đó có thể hữu ích để biết nếu có ai đã không làm. Và tôi thấy không có sự khác biệt bây giờ. Do đó phụ lục này.