2012-08-29 66 views
13

C++ Primer nóiOn biến tĩnh địa phương và toàn cầu trong C++

Mỗi biến tĩnh địa phương được khởi tạo trước khi lần đầu tiên thực hiện qua định nghĩa của đối tượng. Số liệu thống kê cục bộ là không bị hủy khi chức năng kết thúc; chúng bị phá hủy khi chương trình chấm dứt.

Biến tĩnh cục bộ có khác gì với biến tĩnh toàn cầu không? Khác thì vị trí mà chúng được khai báo, còn gì khác?

void foo() { 
    static int x = 0; 
    ++x; 

    cout << x << endl; 
} 

int main (int argc, char const *argv[]) { 
    foo(); // 1 
    foo(); // 2 
    foo(); // 3 
    return 0; 
} 

so sánh với

static int x = 0; 

void foo() { 
    ++x; 

    cout << x << endl; 
} 

int main (int argc, char const *argv[]) { 
    foo(); // 1 
    foo(); // 2 
    foo(); // 3 
    return 0; 
} 

Trả lời

18

Sự khác biệt là:

  • Tên là chỉ có thể trong phạm vi chức năng, và không có liên kết.
  • Khởi tạo lần đầu tiên đạt được định nghĩa, không nhất thiết trong giai đoạn khởi tạo của chương trình.

Sự khác biệt thứ hai có thể hữu ích để tránh fiasco trật tự intialisation tĩnh, nơi các biến toàn cầu có thể được truy cập trước khi chúng được khởi tạo. Bằng cách thay thế biến toàn cầu bằng một hàm trả về một tham chiếu đến một biến tĩnh cục bộ, bạn có thể đảm bảo rằng nó được khởi tạo trước khi bất cứ điều gì truy cập nó. (Tuy nhiên, vẫn không đảm bảo rằng nó sẽ không bị phá hủy trước khi bất cứ điều gì kết thúc truy cập nó, bạn vẫn cần phải chăm sóc tuyệt vời nếu bạn nghĩ rằng bạn cần một biến toàn cầu có thể truy cập. Xem các ý kiến ​​cho một link để giúp đỡ trong tình huống đó.)

+1

Bạn có thể đảm bảo trật tự hủy diệt với một công việc nhỏ. http://stackoverflow.com/a/335746/14065 –

5

phạm vi của họ là khác nhau. Biến tĩnh toàn cục có thể truy cập được tới bất kỳ hàm nào trong tệp, trong khi biến chức năng phạm vi chỉ có thể truy cập trong hàm đó.

+0

Vâng, tất nhiên. Cảm ơn bạn – JAM

+0

@ DavidRodríguez-dribeas: 'không xác định trên đơn vị biên dịch ** s **. Trong đơn vị biên dịch, thứ tự được xác định rõ ràng như thứ tự khai báo. –

+0

@LokiAstari: Bạn đúng ... Tôi đã quá mơ hồ trong nhận xét :) –

4

Có tên thật là:

static storage duration object. 

biến toàn cầu cũng là 'lưu trữ tĩnh thời gian đối tượng'. Sự khác biệt lớn từ các biến toàn cục là:

  • Họ không khởi tạo cho đến khi sử dụng đầu tiên
    Lưu ý: Một ngoại lệ trong quá trình thi có nghĩa là họ không được khởi tạo và do đó không được sử dụng.
    Vì vậy, nó sẽ thử lại lần sau khi chức năng được nhập.
  • Có visability được giới hạn bởi phạm vi của họ
    (tức là họ có thể không được nhìn thấy bên ngoài hàm)

Bên cạnh đó họ cũng giống như 'đối tượng thời gian lưu trữ tĩnh' khác.

Lưu ý: Giống như tất cả các đối tượng thời lượng lưu trữ tĩnh 'chúng bị hủy theo thứ tự ngược lại của việc tạo.

+0

Tôi có đang đọc sai thông số khi tôi đọc nó vì địa phương tĩnh _may_ được khởi tạo cùng với các thống kê khác và có thể không bị trì hoãn cho đến lần gọi đầu tiên ? (C++ 11 §6.7.4 dường như chuyển tiếp đến §3.6.2 cho một số trường hợp và cho phép điều đó) –

+0

** 3.7.1 Thời gian lưu trữ tĩnh ** (Lưu ý: 6.7 mô tả khởi tạo biến tĩnh cục bộ). ** 6.7 Tuyên bố khai báo ** (Khởi tạo không đổi (3.6.2) của một thực thể khối phạm vi với thời gian lưu trữ tĩnh, nếu có, được thực hiện trước khi khối của nó được nhập lần đầu. ... Nếu không biến đó được khởi tạo lần đầu tiên kiểm soát đi qua khai báo của nóConstant khởi tạo (3.6.2) của một thực thể khối phạm vi với thời gian lưu trữ tĩnh, biến như vậy được coi là khởi tạo khi hoàn thành khởi tạo của nó.) –

1

Sự khác biệt chính hoặc nghiêm trọng nhất là thời gian khởi tạo. Các biến tĩnh cục bộ được khởi tạo trên lần gọi đầu tiên đến hàm mà chúng được khai báo.Những cái toàn cầu được khởi tạo vào một thời điểm nào đó trước khi cuộc gọi đến hàm chính, nếu bạn có vài biến tĩnh toàn cục, chúng được intialized theo một thứ tự không xác định, có thể gây ra vấn đề; điều này được gọi là fiasco khởi tạo tĩnh.

0

Trong khối mã đầu tiên của bạn, x là địa phương cho hàm foo() có nghĩa là nó được tạo trong foo() và bị hủy ở cuối hàm sau khi cout. Tuy nhiên, trong khối thứ hai của bạn x là toàn cục, có nghĩa là phạm vi của x là toàn bộ chương trình. Nếu bạn muốn đến dưới int main của bạn có thể cout < < x < < endl và nó sẽ in tuy nhiên, trong khối đầu tiên nó sẽ nói x không tuyên bố

0
  1. Họ được biết là tất cả các chức năng trong một chương trình trong khi toàn cầu các biến chỉ được biết đến trong một phạm vi giới hạn.
  2. Biến tĩnh toàn cầu có thể được khởi tạo trước khi chương trình khởi động trong khi các biến tĩnh cục bộ có thể được khởi tạo khi thực thi đạt đến điểm.
3

Hy vọng rằng, ví dụ này sẽ giúp hiểu sự khác biệt giữa biến cục bộ và biến cục bộ tĩnh.

#include <iostream> 

using namespace std; 

static int z = 0; 

void method1() { 
    static int x = 0; 
    cout << "X : " << ++x << ", Z : " << ++z << endl; 
} 

void method2() { 
    int y = 0; 
    cout << "Y : " << ++y << ", Z : " << ++z << endl; 
} 

int main() { 
    method1(); 
    method1(); 
    method1(); 
    method1(); 
    method2(); 
    method2(); 
    method2(); 
    method2(); 
    return 0; 
} 

đầu ra:

X : 1, Z : 1 
X : 2, Z : 2 
X : 3, Z : 3 
X : 4, Z : 4 
Y : 1, Z : 5 
Y : 1, Z : 6 
Y : 1, Z : 7 
Y : 1, Z : 8 
Các vấn đề liên quan