Người ta có thể viết một bài viết lớn về sự khác biệt giữa hai kiểu mà người ta có thể gặp phải, những người khởi tạo biến luôn khi khai báo họ và những người khởi tạo chúng khi cần thiết. Tôi chia sẻ một dự án lớn với một người đang ở trong hạng mục đầu tiên và bây giờ tôi chắc chắn là loại thứ hai. Luôn khởi tạo các biến đã mang lại nhiều lỗi và vấn đề phức tạp hơn không và tôi sẽ cố gắng giải thích lý do tại sao, ghi nhớ các trường hợp tôi tìm thấy. Ví dụ đầu tiên:
struct NODE Pop(STACK * Stack)
{
struct NODE node = EMPTY_STACK;
if(Stack && Stack->stackPointer)
node = Stack->node[--Stack->stackPointer];
return node;
}
Đây là mã được viết bởi người kia. Hàm này là hàm nóng nhất trong ứng dụng của chúng ta (bạn tưởng tượng một chỉ mục văn bản trên 500 000 000 câu trong một cây bậc ba, ngăn xếp FIFO được sử dụng để xử lý đệ quy vì chúng tôi không muốn sử dụng các hàm gọi đệ quy). Đây là điển hình của phong cách lập trình của anh ấy vì khởi tạo hệ thống các biến. Vấn đề với mã đó là memcpy
ẩn của bản khởi tạo và hai bản sao khác của cấu trúc (mà btw không được gọi tới đôi khi làgcc), vì vậy chúng tôi có 3 bản sao + một cuộc gọi hàm ẩn trong chức năng nóng nhất của dự án . Viết lại nó để
struct NODE Pop(STACK * Stack)
{
if(Stack && Stack->stackPointer)
return Stack->node[--Stack->stackPointer];
return EMPTY_STACK;
}
Chỉ có một bản sao (và lợi ích bổ sung trên SPARC nơi nó chạy, chức năng là một chức năng lá nhờ cuộc gọi tránh để memcpy
và không cần phải xây dựng một cửa sổ đăng ký mới). Vì vậy, chức năng nhanh gấp 4 lần.
Một vấn đề khác tôi tìm thấy ounce nhưng không nhớ chính xác (vì vậy không có ví dụ mã, xin lỗi). Một biến được khởi tạo khi khai báo nhưng nó được sử dụng trong một vòng lặp, với switch
trong một automaton trạng thái hữu hạn. Vấn đề giá trị khởi tạo không phải là một trong các trạng thái của automaton và trong một số trường hợp cực kỳ hiếm hoi mà automaton không hoạt động chính xác. Bằng cách loại bỏ bộ khởi tạo, cảnh báo trình biên dịch phát ra đã làm rõ ràng rằng biến có thể được sử dụng trước khi nó được khởi tạo đúng cách. Sửa chữa các automaton đã được dễ dàng sau đó. Đạo đức: phòng thủ khởi tạo một biến có thể ngăn chặn một cảnh báo rất hữu ích của trình biên dịch.
Kết luận: Khởi tạo biến của bạn một cách khôn ngoan. Làm cho nó hệ thống là không có gì nhiều hơn là theo đuổi hàng hóa (bạn thân của tôi trong công việc là người vận chuyển hàng hóa tồi tệ nhất có thể tưởng tượng, anh ta không bao giờ sử dụng goto, luôn khởi tạo biến, sử dụng nhiều khai báo tĩnh (nó nhanh hơn bạn biết) trong thực tế thậm chí còn thực sự chậm trên SPARC 64bit), làm cho tất cả các chức năng inline
ngay cả khi chúng có 500 dòng (sử dụng __attribute__((always_inline))
khi trình biên dịch không muốn)
Nguồn
2010-04-16 18:37:58
chỉ là một vài gợi ý đi theo cùng một hướng: sử dụng phạm vi nhỏ nhất có thể cho các biến của bạn Khởi tạo trực tiếp sau khi khai báo.Chỉ sử dụng các biến cho một mục đích Sử dụng const nếu bạn dự định biến không thay đổi Lý do chính cho những gợi ý này: chúng cải thiện khả năng đọc và r giáo dục cơ hội cho các lỗi tinh tế trong quá trình thay đổi mã. Hiện tại, mã có thể không có lỗi, không theo các gợi ý này - nhưng theo sau chúng sẽ dễ dàng hơn nếu không bị lỗi với mỗi thay đổi mã. –
Xác định và khởi tạo trong một câu lệnh bất cứ khi nào có thể. –
Không, khởi tạo biến của bạn nếu thích hợp. Vòng lặp for có thể đọc được nhiều hơn khi biến vòng lặp được khởi tạo trong câu lệnh for. Biến của bạn có thể đã được khai báo trước vòng lặp. –