PDA

View Full Version : Dùng extern variable như thế nào?


littlephoc
01-10-2007, 09:55 AM
Mình viết chương trình trong C18:
isr.h khai báo biến int state;
isr.c include isr.h để sử dụng biến state;
bây giờ file main.c muốn thay đổi giá trị của biến state thì mình phải khai báo thế nào cho hợp lý:
- khai báo trong file main.c: extern int state;
- hoặc khai báo #include "isr.c" ?
- liệu như vậy có đúng hay có cách nào khác đúng hoặc tốt hơn?

bien_van_khat
01-10-2007, 12:09 PM
Để tiện việc quản lý code người ta chia code thành nhiều module nhỏ. Compiler sẽ dịch các module này thành file đối tượng (.o hoặc .obj). Linker sẽ liên kết các file đối tượng thành file thực thi (với PIC là .hex). Đây là nguyên tắc cơ bản khi biên dịch code, nhưng bây giờ các IDE quá phổ biến, nên thật ra ít người hiểu được điều này.

Với C18, bạn #include "isr.c" đồng thời add cả nó vào project của bạn thì sẽ bị báo lỗi.

Tốt nhất bạn chỉ add "isr.c" vào project thôi, module này sẽ được dịch và liên kết với "main.c" của bạn. Nếu biến state đã đc khai báo ở trong isr.c (vì isr.c include isr.h) thì trong tất cả các module khác nếu cần sử dụng biến này, bạn phải khai báo extern (external). Chỉ thị extern báo cho compiler biết biến đó được khai báo ở trong file đối tượng khác, nó chỉ cần dịch, còn linker sẽ lo việc phân phối bộ nhớ.

littlephoc
01-10-2007, 09:23 PM
nhầm, câu hỏi là nếu file main.c khai báo #include isr.h (chứ không phải isr.c) thì sao:
- hàm main sử dụng biến state bình thường không cần phải khai báo lại extern int state; linker sẽ biết chỉ có 1 variable duy nhất là state ?
(add isr.c vào project và cùng compile, nên interrupt vẫn hoạt động, không cần phải khai báo ở main.c.)
Tuy nhiên vì hàm main dùng để điều khiển interrupt nên chỉ thay đổi biến state của isr routine, không dùng các hàm nên không cần phải include isr.h, cho nên mình nghĩ rằng dùng chỉ thị extern là hợp lý.
Vì dùng C cho PC thì bình thường, không biết rõ C18 trên PIC thì thế nào nên hỏi. Giờ thì đã hiểu là sử dụng thế là OK.
cám ơn anh biển_vẫn_khát nhhiều.

bien_van_khat
01-10-2007, 11:06 PM
Nếu bạn include isr.h vào trong main.c, như vậy biến state đc khai báo cùng lúc 2 nơi khi liên kết sẽ bị báo lỗi trùng định danh.

Khai báo extern đc đưa ra để giải quyết vấn đề này, nên bạn dùng nó là tốt nhất.

littlephoc
03-10-2007, 11:31 PM
trong file isr.h có định nghĩa biến REV như sau:

union {
unsigned char ShiftReg;
struct {
unsigned char ShiftRegLSB :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char :1;
unsigned char ShiftRegMSB :1;
};
} REV;

Vậy trong file main.c, sẽ khai báo extern như thế nào?
Trong chương trình mình khai báo ở file main y chang như trên, thêm từ khóa extern phía trước. Hình như nó làm cho chương trình của mình chạy sai.

honghoan
22-09-2012, 11:27 AM
Hình như kiểu dữ liệu có cấu trúc không dùng được extern đâu. Chỉ kiểu dữ liệu cơ bản thôi. extern chỉ là biển tham chiếu một biến đã được khai báo ở một module khác (cùng địa chỉ và tên giống nhau).
Nếu
char A; // khai báo trong module1.h (module1.c) và bắt buộc A phải khai báo là biến toàn cục
extern char A ; //khai báo trong module2.h
vậy nếu ta khai báo. #include "module2.h" ở những module (*.c) là ta có thể dùng chung biến A mà ta đã khai báo ở module1.c