2011-11-02 21 views
7
#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; 
} 
+0

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

+0

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ý) –

Trả lời

13

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

+0

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

+0

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

+0

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

2

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.

5

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

+0

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

+0

@ SR_ Đúng vậy, cảm ơn đã sửa. – inf

2

Làm cho int i của bạn là size_type i.
std::vector::size() sẽ trả lại size_typeunsigned 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.

2

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:

  1. Để loại bỏ các cảnh báo, thay đổi loại 's iunsigned, auto (đối với C++ 11) hoặc std::vector<your_type>::size_type
  2. 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 đến size-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 :) đó).
  3. Để 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) 
{ 
    //.. 
} 
2

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 đó).

3

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

0

Khai báo 'size_t i' cho tôi hoạt động tốt.

1

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

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