2010-05-08 40 views
5

Im tự hỏi nếu mã này:C++ khai báo biến

int main(){ 
    int p; 
    for(int i = 0; i < 10; i++){ 
     p = ...; 
    } 
    return 0 
} 

là chính xác giống như một

int main(){ 
    for(int i = 0; i < 10; i++){ 
     int p = ...; 
    } 
    return 0 
} 

trong nhiệm kỳ của hiệu quả? Ý tôi là biến p sẽ được tạo lại 10 lần trong ví dụ thứ hai?

Trả lời

9
  • Điều này cũng tương tự về mặt hiệu quả.
  • Điều này không giống nhau về khả năng đọc. Thứ hai là tốt hơn trong khía cạnh này, phải không?

Đó là một ngữ nghĩa chênh lệch mà mã vẫn tiếp tục ẩn vì nó không làm nên sự khác biệt cho int, nhưng nó làm cho một sự khác biệt đối với người đọc của con người. Bạn có muốn mang giá trị của bất kỳ phép tính nào bạn thực hiện trong ... ngoài vòng lặp không? Bạn không, vì vậy bạn nên viết mã phản ánh ý định của bạn.

Trình đọc của con người sẽ cần tìm kiếm chức năng và tìm kiếm các cách sử dụng khác của p để xác nhận rằng những gì bạn đã làm chỉ là "tối ưu" sớm và không có mục đích sâu sắc hơn.

Giả sử nó làm cho một sự khác biệt cho các loại hình bạn sử dụng, bạn có thể giúp người đọc con người bằng cách bình luận mã của bạn

/* p is only used inside the for-loop, to keep it from reallocating */ 
std::vector<int> p; 
p.reserve(10); 

for(int i = 0; i < 10; i++){ 
    p.clear(); 
    /* ... */ 
} 
+0

Vâng, nó chỉ bằng hiệu quả nếu trình biên dịch của bạn không có biến số ngăn xếp. –

+1

Tôi không lo lắng nhiều với hiệu quả lúc đầu, nhưng khả năng đọc là một phí bảo hiểm. Khi nó hoạt động, nếu nó quá chậm, thì đã đến lúc lập hồ sơ và tối ưu hóa những gì có thể. –

0

Trong ví dụ thứ hai p là có thể nhìn thấy chỉ bên trong vòng lặp for. bạn không thể sử dụng nó thêm trong mã của bạn. Về mặt hiệu quả, chúng bằng nhau.

4

Trong trường hợp này, nó giống nhau. Sử dụng phạm vi nhỏ nhất có thể cho mã dễ đọc nhất.

Nếu int là một lớp có hàm tạo và phá hủy đáng kể, thì đầu tiên (khai báo bên ngoài vòng lặp) có thể tiết kiệm đáng kể - nhưng bên trong bạn thường cần tạo lại trạng thái ... vì vậy đôi khi nó kết thúc không tiết kiệm chút nào.

Một trường hợp có thể tạo sự khác biệt là vùng chứa. Một chuỗi hoặc vector sử dụng bộ nhớ trong được tăng lên để phù hợp với kích thước của dữ liệu mà nó đang lưu trữ. Bạn có thể không muốn xây dựng lại vùng chứa này mỗi lần thông qua vòng lặp, thay vào đó, chỉ cần xóa nội dung của nó và nó có thể không cần nhiều bản phân phối bên trong vòng lặp. Điều này có thể (trong một số trường hợp) dẫn đến cải thiện hiệu suất đáng kể.

Các mấu chốt là viết rõ ràng, và nếu hồ sơ cho thấy vấn đề, di chuyển nó ra :)

1

Họ đều bình đẳng về mặt hiệu quả - bạn nên tin tưởng biên dịch của bạn để thoát khỏi sự khác biệt vô cùng nhỏ . Thứ hai là thiết kế tốt hơn.

Chỉnh sửa: Điều này không nhất thiết đúng đối với các loại tùy chỉnh, đặc biệt là những loại xử lý bộ nhớ. Nếu bạn đang viết một vòng lặp cho bất kỳ T, tôi chắc chắn sử dụng hình thức đầu tiên chỉ trong trường hợp. Nhưng nếu bạn biết rằng đó là một loại sẵn có, như int, con trỏ, char, float, bool, vv Tôi sẽ đi cho thứ hai.