2013-03-31 31 views
7

Trong đoạn mã sau, tại sao nhiều khai báo (và một định nghĩa) cho biến toàn cục "x" hoạt động tốt nhưng cùng không hoạt động với biến cục bộ "y" nằm trong hàm main()? 2 lỗi sau đây:Trong C, tại sao nhiều khai báo hoạt động tốt cho biến toàn cầu nhưng không hoạt động đối với biến cục bộ?

1) khai báo lại của 'y' không có mối liên hệ

2) tuyên bố trước đó của 'y' đã ở đây

Tại sao nó hiển thị lỗi cho biến cục bộ nhưng không toàn cầu biến Không chỉ cuốn sách của tôi, nhưng 2 liên kết sau đây từ diễn đàn này nêu rõ rằng chúng tôi có thể khai báo một biến nhiều lần (mặc dù chỉ xác định một lần).

link1 link2

Và vui lòng chăm sóc để giải thích những gì hiện các "không có mối liên kết" một phần của lỗi đầu tiên "khai báo lại của 'y' không có mối liên kết" nghĩa là gì? Liên kết gì và cho ai? Ở đâu sẽ một biến cục bộ được liên kết?

#include<stdio.h> 

    int x; 
    int x; 
    int x=303; 

    int main(void) 
    { 

     int y; 
     int y; 
     int y=776; //Works fine if above 2 declarations are removed!! 

     printf("The value of x is %d,and of y is %d",x,y); 

    } 
+0

Đọc http://en.wikipedia.org/wiki/Linker_%28computing%29 về liên kết & liên kết. Và cũng là cuốn sách của Levine http://www.iecc.com/linker/; do đó các biến cục bộ không được liên kết (vì chúng nằm trong khung gọi cục bộ, trên ngăn xếp). –

+0

Nhưng nó cho thấy lỗi cho x cũng trong trình biên dịch của tôi. – Jeyamaran

+0

@Jeyamaran bạn có thể đã sử dụng trình biên dịch C++. Đây là câu hỏi C. –

Trả lời

17

Trong C và C++, int y;trong vòng một hàm vừa là một lời tuyên bố và một định nghĩa.

Trong C, int x; trong phạm vi tập tin (bên ngoài bất kỳ chức năng) là một tuyên bố và một defintion dự kiến ​​. Nhiều định nghĩa dự kiến ​​được cho phép; chỉ cho phép định nghĩa.

+0

Có vẻ như bạn nhấn mắt của con bò. Hãy đợi một lúc và xem những gì người khác nói. –

+0

Chắc chắn. Trong khi chúng tôi ở đây, một điều thú vị khác là cách phạm vi ảnh hưởng đến các tên biến: http://stackoverflow.com/questions/2393458/why-does-using-the-same-count-variable-name-in-nested-for- loop-work – maditya

+0

@maditya: Nếu tôi khai báo và định nghĩa một biến trong hàm (phạm vi cục bộ) và không sử dụng nó thì sao? Vẫn còn bộ nhớ được cấp phát? Nhưng trong trường hợp phạm vi toàn cầu là bộ nhớ được cấp phát chỉ khi nó được sử dụng? –

5

Đây là cách định nghĩa trong tiêu chuẩn C99, phần 6.2.2, phần 2:

Trong bộ của các đơn vị dịch và các thư viện đó được hiểu là toàn bộ chương trình, mỗi tuyên bố một er fi identi đặc biệt với liên kết bên ngoài biểu thị cùng một đối tượng hoặc hàm . Trong một đơn vị dịch thuật, mỗi tờ khai có xác định với nội bộ liên kết biểu thị cùng một đối tượng hoặc chức năng. Mỗi tuyên bố của một định danh với không có liên kết biểu thị một thực thể duy nhất.

Biến "chung" x có liên kết bên ngoài, vì vậy chúng biểu thị cùng một đối tượng. Các biến địa phương y, mặt khác, không có liên kết, do đó, có một va chạm.

Tham chiếu: C99 Standard.

3

Với các biến bên ngoài, bất kỳ khai báo nào không phải là khởi tạo là định nghĩa dự kiến. Bản thân chúng không tạo ra bất kỳ dung lượng lưu trữ nào, vì vậy nhiều mục được cho phép. Vì vậy, dùng ví dụ của bạn:

int x;  // tentative def 
int x;  // and again -- ok 
int x=303; // definition -- ok 
int x=303; // multiple definition -- error 

Nếu ở phần cuối của tập tin đã có định nghĩa duy nhất dự kiến, biến được định nghĩa một lần, và thiết lập là 0.

Điều này có nghĩa rằng nếu bạn liên kết đến tập tin khác cũng có định nghĩa dự kiến ​​là x, bạn sẽ gặp lỗi theo tiêu chuẩn. Hầu hết các trình biên dịch/liên kết đã luôn luôn cho phép điều này, mặc dù, và nó được định nghĩa trong tiêu chuẩn như là một phần mở rộng.

Với các biến cục bộ, mỗi khai báo là định nghĩa vì các quy tắc phạm vi. Tuy nhiên, điều này được cho phép:

void func(void) 
{ 
    int y = 0; 
    { 
     int y = 1; // a completely different y 
    } 
} 
Các vấn đề liên quan