2011-02-27 43 views
12

Tại sao mã sau xuất ra cùng một vị trí bộ nhớ mỗi lần?Biến cục bộ vòng lặp trong C

int x; 
for (x = 0; x < 10; x++) { 
    int y = 10; 
    printf("%p\n", &y); 
} 

Tôi nghĩ rằng vị trí bộ nhớ nên thay đổi khi mỗi lần vòng lặp được chạy, biến mới.

Trả lời

18

Có, bạn hoàn toàn đúng rằng vị trí bộ nhớ có thể thay đổi. Nhưng nó không phải :). Trong mỗi lần lặp, biến cũ là "bị hủy" và một biến mới được "tạo" ở cùng một vị trí. Mặc dù bất kỳ trình biên dịch nào cũng sẽ tối ưu hóa "hành động" không cần thiết

+0

Oh, được rồi, cảm ơn bạn. Tôi đã đơn giản hóa câu hỏi này, vì tôi thực sự đang cố gắng tạo một danh sách liên kết, và tôi tạo một nút mới trong vòng lặp, và tôi không muốn nút tiếp theo ghi đè nút từ lần lặp trước, nhưng đó là những gì nó đang làm. Tôi sẽ đăng câu hỏi mới, khi tôi có thể tạo đoạn mã có thể dễ dàng được phân tích. –

+4

nếu bạn muốn cấu trúc dữ liệu liên tục, chúng phải được tạo trên 'heap' thay vì 'stack'. Sử dụng 'malloc' vv cho việc này. – Alnitak

+1

@amandeepGrewal: Bạn nên tạo các biến trên heap (với malloc) để đạt được hành vi mong muốn –

5

Có, biến là mới mỗi lần, nhưng ở cuối khối bất kỳ biến mới nào trên ngăn xếp được phát hành lại.

Do đó, lần tiếp theo xung quanh con trỏ ngăn xếp đã trở lại chính xác vị trí của nó. Lưu ý: hành vi này là phổ biến, nhưng không được đảm bảo theo tiêu chuẩn.

0

Quy tắc phạm vi cho các biến chỉ mô tả phạm vi mà bạn có quyền truy cập vào biến cục bộ: từ định nghĩa đến cuối khối của nó.

Quy tắc này không nói gì về thời điểm không gian được dành riêng cho nó. Một chiến lược chung cho điều đó là để dành không gian cho tất cả các biến cần thiết cho một lời gọi hàm một lúc, ở đầu hàm.

Vì vậy, khi thực hiện vượt qua một định nghĩa của một biến, thường không có gì đặc biệt phải được thực hiện, không phải là một hướng dẫn duy nhất. Mặt khác, điều này để lại giá trị của biến đó cho bất kỳ biến nào đã được tìm thấy ở đó trước đó. Vì vậy, tầm quan trọng của việc khởi tạo một trạng thái đã biết, như bạn đã làm trong ví dụ của bạn với = 10.

2

Đó là tối ưu hóa trình biên dịch. Bởi vì biến cục bộ sẽ không nằm trong phạm vi và một biến của cùng loại chính xác sắp được tạo, nó sẽ sử dụng lại địa chỉ bộ nhớ. Điều quan trọng cần lưu ý rằng đây vẫn là biến "mới" hoặc "mới" theo như chương trình của bạn có liên quan.

Hãy so sánh các đoạn mã sau và đầu ra:

for (i = 0; i < 3; i++) { 
    int n = 0; 
    printf("%p %d\n", (void *)&n, n++); 
} 
 
0x7fff56108568 0 
0x7fff56108568 0 
0x7fff56108568 0 
for (i = 0; i < 3; i++) { 
    static int n = 0; 
    printf("%p %d\n", (void *)&n, n++); 
} 
 
0x6008f8 0 
0x6008f8 1 
0x6008f8 2 
Các vấn đề liên quan