#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main() {
vector<double> vector_double;
vector<string> vector_string;
...
while (cin >> sample_string)
{
...
}
for(int i = 0; i <= vector_string.size(); i++)
{
....
}
for (int i = 0; i < vector_double.size(); i++)
....
return 0;
}
Trả lời
Tại sao lại có một cảnh báo với
-Wsign-compare
?
Là tên của cảnh báo và văn bản của nó, ngụ ý, vấn đề là bạn đang so sánh số nguyên đã ký và số không dấu. Nó thường được giả định rằng đây là một tai nạn.
Để tránh cảnh báo này, bạn chỉ cần đảm bảo rằng cả hai toán hạng của <
(hoặc bất kỳ toán tử so sánh nào khác) đều được ký hoặc không được ký.
Làm cách nào tôi có thể làm tốt hơn?
Cách thành ngữ viết một vòng lặp for
là để khởi tạo cả quầy và giới hạn trong báo cáo kết quả đầu tiên:
for (std::size_t i = 0, max = vec.size(); i != max; ++i)
Điều này tiết kiệm recomputing size()
tại mỗi lần lặp.
Bạn cũng có thể (và có lẽ) nên sử dụng vòng lặp thay vì chỉ số:
for (auto it = vec.begin(), end = vec.end(); it != end; ++it)
auto
đây là viết tắt của std::vector<int>::iterator
. Iterator làm việc cho bất kỳ loại container nào, trong khi các chỉ số giới hạn bạn với các mảng C, deque
và vector
.
hoạt động. mặc dù max() không hoạt động nên tôi đã thay đổi nó thành CPC cảm ơn – code511788465541441
Tôi sẽ không sử dụng cách tối đa bởi vì - tùy thuộc vào vòng lặp của bạn, kích thước của vec có thể thay đổi, do đó, nó là an toàn hơn để kiểm tra mỗi lần cho kích thước thực tế của vec. – inf
Việc khởi tạo giới hạn đầu tiên chỉ hoạt động nếu vùng chứa không thay đổi kích thước bên trong vòng lặp. Nếu không, tôi sẽ khai báo giới hạn dưới dạng biến 'const' trước vòng lặp, để cung cấp cho trình biên dịch thêm đạn dược đối với các lập trình viên đang cố gắng thay đổi biến. –
bạn biến i
là một số nguyên trong khi chức năng size
viên của vector đó trả về một Allocator::size_type
rất có thể trở về một size_t
, đó là hầu như luôn luôn được triển khai dưới dạng int không dấu của một số kích thước.
Đó là bởi vì các .size() chức năng từ lớp véc tơ không phải là kiểu int nhưng loại vector :: size_type
Sử dụng đó hoặc auto i = 0u
và các thông điệp sẽ biến mất.
Sử dụng tính năng tự động ở đây sẽ không hoạt động vì loại được khấu trừ sẽ được ký int. Sử dụng auto i = 0U; công trinh. –
@ SR_ Đúng vậy, cảm ơn đã sửa. – inf
Làm cho int i
của bạn là size_type i
.
std::vector::size()
sẽ trả lại size_type
là unsigned int
vì kích thước không thể là -ve.
Cảnh báo rõ ràng là vì bạn đang so sánh số nguyên đã ký với số nguyên không dấu.
Answering sau rất nhiều câu trả lời, nhưng không ai chú ý cuối vòng lặp .. Vì vậy, đây là câu trả lời đầy đủ của tôi:
- Để loại bỏ các cảnh báo, thay đổi loại 's
i
làunsigned
,auto
(đối với C++ 11) hoặcstd::vector<your_type>::size_type
- Vòng
for
của bạn sẽ bị lỗi, nếu bạn sử dụng sối
làm chỉ mục này - bạn phải lặp lại từ0
đếnsize-1
, bao gồm. Vì vậy, thay đổi nó để được
for(std::vector<your_type>::size_type i = 0; i < vector_xxx.size(); ++i)
(chú ý<
, không<=
; tư vấn cho tôi không phải là để sử dụng<=
với.begin() - 1
, bởi vì bạn có thể có một vector kích thước 0 và bạn sẽ có vấn đề với :) đó). - Để thực hiện điều này chung chung hơn, vì bạn đang sử dụng vùng chứa và bạn đang lặp lại qua vùng chứa, bạn có thể sử dụng
iterator
s. Điều này sẽ làm cho sự thay đổi tương lai dễ dàng hơn của loại container (nếu bạn không cần vị trí chính xác như số, tất nhiên). Vì vậy, tôi sẽ viết nó như thế này:
for(std::vector<your_type>::iterator iter = vector_XXX.begin();
iter != vector_XXX.end();
++iter)
{
//..
}
Bạn nhận được cảnh báo này vì kích thước của vùng chứa trong C++ là loại chưa ký và trộn các loại đã ký/chưa ký là nguy hiểm.
Những gì tôi làm như thường lệ là
for (int i=0,n=v.size(); i<n; i++)
....
đây là theo ý kiến của tôi cách tốt nhất để sử dụng chỉ số vì sử dụng một loại unsigned cho một chỉ số (hoặc kích thước của một container) là một sai lầm logic.
Các loại không được chỉ định sẽ chỉ được sử dụng khi bạn quan tâm đến biểu diễn bit và khi nào bạn sẽ sử dụng hành vi modulo- (2 ** n) trên tràn. Sử dụng các loại unsigned chỉ vì một giá trị không bao giờ là tiêu cực là một vô nghĩa.
Một lỗi điển hình của việc sử dụng các loại unsigned cho kích thước hay chỉ là ví dụ
// Draw all lines between adjacent points
for (size_t i=0; i<pts.size()-1; i++)
drawLine(pts[i], pts[i+1]);
mã trên là UB khi mảng Vấn đề là trống rỗng, vì trong C++ 0u-1
với là một số dương khổng lồ.
Lý do C++ sử dụng loại không dấu cho kích thước vùng chứa là do sự lựa chọn đó là di sản lịch sử từ máy tính 16 bit (và IMO cho C++ ngữ nghĩa với các loại chưa ký nó là lựa chọn sai ngay cả khi đó).
int
được ký theo mặc định - tương đương với văn bản signed int
. Lý do bạn nhận được cảnh báo là bởi vì size()
trả lại số vector::size_type
có nhiều khả năng chưa được ký.
Điều này có nguy cơ tiềm ẩn vì signed int
và unsigned int
giữ các phạm vi giá trị khác nhau. signed int
có thể giữ giá trị giữa –2147483648
đến 2147483647
trong khi unsigned int
có thể giữ giá trị giữa 0
đến 4294967295
(giả sử int
là 32 bit).
Khai báo 'size_t i' cho tôi hoạt động tốt.
tôi thường giải quyết nó như thế này:
for(int i = 0; i <= (int)vector_string.size(); i++)
tôi sử dụng các diễn viên C-phong cách vì nó ngắn và dễ đọc hơn so với C++ static_cast<int>()
, và hoàn thành điều tương tự.
Có khả năng tràn ở đây, nhưng chỉ khi kích thước véc tơ của bạn lớn hơn int
lớn nhất, thường là 2147483647. Tôi chưa bao giờ trong cuộc đời của tôi có một véc tơ lớn. Nếu thậm chí có khả năng sử dụng một vector lớn hơn, một trong những câu trả lời cho thấy size_type
sẽ phù hợp hơn.
Tôi không lo lắng về việc gọi size()
nhiều lần trong vòng lặp vì có thể là truy cập nội tuyến vào biến thành viên không giới thiệu chi phí.
- 1. hành vi cảnh báo Strange với gcc và ký/so sánh unsigned
- 2. So sánh char unsigned và EOF
- 3. So sánh và so sánh số nguyên chuỗi PHP Weird
- 4. So sánh giữa con trỏ và số nguyên
- 5. Hãy so sánh int và unsigned int
- 6. Objective C: Unsigned int so sánh
- 7. So sánh giá trị số nguyên
- 8. Cảnh báo so sánh hiệu chỉnh trong g + +
- 9. so sánh giữa con trỏ và số nguyên ('int *' và 'int')
- 10. Điều gì đang xảy ra khi() của tôi là có điều kiện?
- 11. So sánh số nguyên Java: lớn hơn
- 12. Findbugs và so sánh
- 13. So sánh hiệu suất của int và số nguyên
- 14. “Cảnh báo: so sánh là luôn luôn đúng”
- 15. Các so sánh giữa trình vòng lặp và const_iterator có hiệu quả không?
- 16. Cảnh báo: So sánh liên tục 8 với biểu hiện của loại XXXX luôn là sai
- 17. Làm cách nào để khắc phục các cảnh báo như: "so sánh giữa chữ ký và chưa ký"?
- 18. So sánh PropertyInfo từ Type.GetProperties() và biểu thức lambda
- 19. Điều gì "không thể được so sánh bởi trình so khớp thời gian" nghĩa là gì?
- 20. So sánh hai LinkedList <String> với ListIterator so với vòng lặp và nhận (int index)
- 21. Performance khác biệt khi so sánh số nguyên và so sánh chuỗi
- 22. Javascript: so sánh hiệu quả hai mảng số nguyên
- 23. Tôi có cần phương thức equals và Hashcode không nếu lớp của tôi thực hiện so sánh được trong Java?
- 24. Điều gì tương đương với mệnh đề giữa, cho chuỗi so sánh trong LINQ hoặc biểu thức lambda?
- 25. Truy xuất chức năng so sánh của thùng chứa với một trình lặp vòng
- 26. Đối sánh so sánh nguyên trong rspec
- 27. vấn đề python với so sánh số nguyên
- 28. So sánh biến với số nguyên trong trình bao?
- 29. Visual C++ 2010: Tại sao "không khớp/unsigned không khớp" biến mất nếu tôi thêm "const" vào một so sánh?
- 30. lỗi biên dịch C++: ISO C++ cấm so sánh giữa con trỏ và số nguyên
Lỗi này cho bạn biết chính xác những gì là sai. Có chính xác một hoạt động so sánh cho mỗi vòng lặp, vì vậy bạn có thể xem những gì đang được so sánh với đó. Bạn có thể thấy rằng 'i' là một kiểu đã ký (bạn đã chọn kiểu!), Do đó, nó ngụ ý rằng biểu thức khác là một kiểu unsigned. –
Bản sao có thể có của [Làm cách nào tôi có thể sửa các cảnh báo như: "so sánh giữa chữ ký và chưa ký"?] (Http://stackoverflow.com/questions/859943/how-can-i-fix-warnings-like-comparison-between- đã ký và không được ký) –