2012-03-13 40 views
9
#include <stdio.h> 

static i = 5; 

int main() 
{ 
extern int i; 
printf("%d\n",i); 
return 0; 
} 

Ai đó có thể đưa ra bất kỳ trường hợp sử dụng nào để khai báo biến tĩnh dưới dạng extern bên trong khối chức năng không?Việc sử dụng khai báo một biến tĩnh như extern bên trong một hàm là gì?

MỚI: Tại sao điều này không được phép?

int main() 
{ 
static i = 5; 
extern int i; 
printf("%d\n",i); 
return 0; 
} 
+3

Vì 'i' là extern hoặc local - không thể là cả hai. – Till

+0

không được phép? Đoạn mã thứ hai của bạn chạy hoàn toàn tốt trên gcc (mingw) –

+0

Tôi đang sử dụng gcc 4.1.2 20080704 (Red Hat 4.1.2-51) và tôi nhận được lỗi sau: file1.c: Trong hàm âm thanh: file1.c : 6: error: extern declaration của âiâ sau khai báo không có liên kết file1.c: 5: error: định nghĩa trước đây của âiâ là ở đây – Bruce

Trả lời

8

này rất hữu ích khi bạn cần phải truy cập vào một biến mà cư trú trong phạm vi một đơn vị dịch thuật, mà không lộ biến bên ngoài trên toàn thế giới (đối với một vài lý do, như tên va chạm, hoặc là biến không nên được truy cập trực tiếp, vì vậy static được sử dụng để giới hạn phạm vi của nó, nhưng tiêu đề của TU vẫn cần truy cập).

Như một ví dụ, cho phép nói rằng chúng ta có một đơn vị dịch foo.c, nó chứa:

//foo.c 
static int i = 0; 

i không nên thay đổi hoặc trực tiếp truy cập bên ngoài foo.c Tuy nhiên, foo.h đến cùng đòi hỏi quyền truy cập vào i cho một chức năng nội tuyến, nhưng i không được tiếp xúc với bất kỳ đơn vị dịch nào sử dụng foo.h, vì vậy chúng tôi có thể sử dụng extern ở cấp chức năng để chỉ hiển thị nó trong phạm vi IncI, hàm nội tuyến yêu cầu sử dụng i:

//foo.h 
inline void IncI(int val) 
{ 
    extern int i; 
    i += val; 
} 

ví dụ thứ hai của bạn là 'cấm' vì trình biên dịch nghĩ rằng bạn đang cố gắng để ràng buộc hai biến khác nhau với tên biểu tượng tương tự, ví dụ: nó tạo ra static i ở phạm vi địa phương, nhưng tìm kiếm cho extern int i ở phạm vi toàn cầu, nhưng không tìm thấy nó, bởi vì static i như ở phạm vi chức năng. một trình biên dịch thông minh hơn sẽ chỉ sửa liên kết đến static i, cho dù điều này có tuân thủ các tiêu chuẩn mà tôi không biết hay không.


Bây giờ tôi có một C standards document làm việc từ (xấu hổ về tôi Tôi biết ...), chúng ta có thể nhìn thấy những gì lập trường chính thức là (trong C99):

6.2.2 Linkages of identifiers

Section 3:

If the declaration of a file scope identifier for an object or a function contains the storageclass specifier static, the identifier has internal linkage.

Section 4:

For an identifier declared with the storage-class specifier extern in a scope in which a prior declaration of that identifier is visible, if the prior declaration specifies internal or external linkage, the linkage of the identifier at the later declaration is the same as the linkage specified at the prior declaration. If no prior declaration is visible, or if the prior declaration specifies no linkage, then the identifier has external linkage.

như vậy, bởi vì static sẽ gây ra liên kết nội bộ, extern sẽ đưa liên kết đó vào phạm vi hiện tại. đó cũng là một ghi chú nói rằng điều này có thể gây ra ẩn của các biến:

23) As specified in 6.2.1, the later declaration might hide the prior declaration.

+2

Bạn có thể đưa ra một số mã ví dụ xin vui lòng – Bruce

+0

Sau đó, điểm cho một tĩnh toàn cầu là gì? – pezcode

+0

@pezcode: 'static' có thể được sử dụng để hạn chế khả năng hiển thị của đối tượng đối với đơn vị dịch, nhưng tiêu đề có hàm' inline' có thể cần truy cập vào biến tĩnh, do đó extern ở cấp hàm xuất hiện, hàm có thể truy cập biến mà không có 'toàn cầu' thay đổi mức hiển thị của biến tĩnh – Necrolis

0

Trong trường hợp thứ hai, bạn đang nói với trình biên dịch bạn có một tĩnh (địa phương) biến i và khác (toàn cầu) biến i được định nghĩa ở một nơi khác.

+0

thì tại sao nó hoạt động trong trường hợp đầu tiên? – Bruce

+0

vì trong trường hợp đầu tiên, 'static i = 5' nằm ngoài khối mã, nghĩa là. bên ngoài. – len

+0

Tôi nghĩ rằng đó là bởi vì khi chúng ta viết static int i = 5 bên trong một hàm, nó không có liên kết. Tuy nhiên, khi viết bên ngoài nó có liên kết nội bộ. – Bruce

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