2012-05-09 22 views
9

Tôi hơi bối rối trước tuyên bố #define. Trong thư viện, chúng dường như là một phương tiện giao tiếp giữa các tệp khác nhau, với rất nhiều #ifdef s và #ifndef s.C: Chỉ thị #define có toàn cầu không?

Có nói rằng, bây giờ tôi có hai tệp file1.cfile2.c được biên dịch cùng nhau, với #define TEST 10 bên trong file2.c. Tuy nhiên, khi tôi sử dụng TEST bên file2.c trình biên dịch cung cấp cho các thông báo lỗi sau:

'TEST' undeclared (first use in this function) 

Are #define chỉ thị toàn cầu?

+0

Tùy thuộc vào nơi chúng được xác định. – Nick

+0

'# define' là một chỉ thị tiền xử lý - nó chỉ làm thay thế văn bản đơn giản tại thời gian biên dịch - chỉ đơn vị biên dịch và bất kỳ tệp' # include'd nào sẽ * thấy * một '# define'. –

Trả lời

13

#define s không phải là toàn cầu, họ là một thay thế chỉ nơi nào chúng được sử dụng (nếu khai báo trong đơn vị biên dịch giống nhau)

Họ là không globals, họ không biểu tượng, họ không liên quan khi liên kết, chúng chỉ liên quan tại biên dịch trước.

+0

Bạn có ý nghĩa gì bởi "đơn vị biên dịch"? Làm thế nào tôi có thể có 'file1.c' và' file.2' trong cùng một đơn vị biên dịch? – Randomblue

+1

No. chúng được biên dịch riêng biệt. và hen liên kết với nhau. Bạn có quen thuộc với quy trình xây dựng C không? – MByD

+0

Vì vậy, 'file1.c' và' file2.c' không bao giờ có thể ở trong cùng một đơn vị biên dịch? – Randomblue

4

#define d macro là toàn cầu ở chỗ chúng không tuân thủ các quy tắc phạm vi C thông thường. Thay thế văn bản từ macro sẽ được áp dụng (hầu hết) ở bất kỳ nơi nào tên macro xuất hiện sau số #define. (Ngoại lệ đáng chú ý là nếu tên macro là một phần của nhận xét hoặc một phần của chuỗi ký tự.)

Nếu bạn xác định macro trong tệp tiêu đề, bất kỳ tệp nào mà tệp tiêu đề #include s sẽ kế thừa macro đó (cho dù chúng muốn hay không), trừ khi họ xác định rõ ràng nó với #undef.

Trong ví dụ của bạn, file2.c không biết về macro TEST. Làm cách nào để biết cách nhận số #define từ file1.c? Bằng phép thuật? Vì các macro thực hiện thay thế văn bản trên mã nguồn, không có đại diện của chúng trong các tệp đối tượng đã tạo. file2.c do đó cần phải biết rằng chính quy tắc thay thế và nếu bạn muốn chia sẻ trên nhiều tệp, thì #define cần phải xuất hiện trong tệp tiêu đề chung mà các tệp .c#include của bạn.

Nếu bạn hỏi cụ thể về số lượng #ifdef mà bạn thấy trong thư viện hoạt động, nhiều người trong số họ có khả năng kiểm tra tên macro được xác định trước được cung cấp bởi môi trường biên dịch. Ví dụ, một trình biên dịch C99 định nghĩa một macro __STDC_VERSION__ chỉ định phiên bản ngôn ngữ; một trình biên dịch của Microsoft định nghĩa một macro _MSC_VER. Hầu hết các trình biên dịch cũng cho phép xác định các macro đơn giản như các đối số dòng lệnh. Ví dụ: bạn có thể biên dịch mã của mình qua gcc -DNDEBUG file1.c để biên dịch file.c với NDEBUG được xác định để tắt assert s.

+0

Thx để biết thông tin hữu ích – Hydro

1

bạn nên tạo tệp1.h và đặt định nghĩa của bạn ở đó. Sau đó, trong tệp 2.c

#include "file1.h" 

dễ dàng như một chiếc bánh :)

0

Trong trường hợp ai đó đọc này sau, và thêm một số thông tin thực hiện:

  • Một số môi trường như Atmel, vs, hoặc IAR, cho phép bạn để xác định chỉ thị #define chung. Về cơ bản, chúng truyền các giá trị được định nghĩa này tới trình biên dịch trước trong một số định dạng dòng lệnh.
  • Bạn có thể thực hiện tương tự trong các lệnh hoặc tập lệnh theo lô, v.v.
  • Arduino luôn thêm biến thể bảng (thường nằm ở phần cứng \ arduino \ biến thể) vào tất cả các tập hợp. Tại thời điểm đó, bạn có thể tạo một bảng mới chứa các chỉ thị xác định toàn cầu của bạn và sử dụng nó theo cách đó. Ví dụ, bạn có thể xác định một mega2560 (gỡ lỗi) hội đồng quản trị ra khỏi mega2560 ban đầu có chứa một số chỉ thị gỡ lỗi. Bạn sẽ thêm một tham chiếu đến biến thể đó trong "boards.txt", bằng cách sao chép dán một số văn bản và sửa đổi nó một cách chính xác.

Vào cuối ngày, bạn sẽ phải cung cấp chỉ thị toàn cục hoặc chỉ thị chung đó cho trình biên dịch theo cách này hay cách khác.

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