2012-05-24 54 views
16

Tôi đã viết một số mã thử nghiệm trong C. Do nhầm lẫn, tôi đã chèn một số ; sau #define, điều này đã cho tôi lỗi. Tại sao dấu chấm phẩy không được yêu cầu cho #define s?Tại sao #define không yêu cầu dấu chấm phẩy?

Cụ thể hơn:

Phương pháp 1: Công việc

const int MAX_STRING = 256; 

int main(void) { 
    char buffer[MAX_STRING]; 
} 

Cách 2: Không làm việc - lỗi biên dịch.

#define MAX_STRING 256; 

int main(void) { 
    char buffer[MAX_STRING]; 
} 

Lý do hành vi khác nhau của các mã đó là gì? Cả hai MAX_STRING không phải là hằng số?

+35

Tháo; trong phương pháp 2 –

+7

Xem đầu ra tiền xử lý và câu trả lời sẽ nhìn chằm chằm vào mặt bạn. –

+0

@MichaelFoukarakis vâng, đó là cách dễ nhất 'cpp prog_name.c | tail' nói tất cả. – user51390233

Trả lời

20

#define là một preprocessor directive, không phải là một tuyên bố hoặc khai theo quy định của ngữ pháp C (cả những người được yêu cầu phải kết thúc bằng dấu chấm phẩy). Các quy tắc cho cú pháp của mỗi cái là khác nhau.

10

Vì đó là cách cú pháp được quyết định cho chỉ thị biên dịch trước trước.

Chỉ báo cáo cuối với một ; trong c/C++, #define là một chỉ thị tiền xử lý và không phải là một tuyên bố.

17

define là một chỉ thị tiền xử lý, và là một sự thay thế đơn giản, nó không phải là một tuyên bố.

BTW, như một sự thay thế nó có thể chứa một số ; như là một phần của nó:

// Ugly as hell, but valid 
#define END_STATEMENT ; 

int a = 1 END_STATEMENT // preprocessed to -> int a = 1; 
11

Phiên bản thứ hai không xác định một hằng số như xa như ngôn ngữ là có liên quan, chỉ cần một quy tắc thay thế cho một khối bản văn. Khi Preprocessor đã hoàn thành nhiệm vụ của nó, các biên dịch thấy

char buffer [256;];

mà không phải là cú pháp hợp lệ.

Đạo đức của câu chuyện: thích cách const int MAX_STRING = 256; giúp bạn, trình biên dịch và trình gỡ lỗi.

+0

Tôi không chắc chắn, nó giúp trình gỡ rối như thế nào? – saeleko

+3

Bạn đã bao giờ thử gỡ lỗi tải mã với các macro trong đó chưa? – Bathsheba

+5

Trong trường hợp chung 'const int MAX_STRING = 256;' là * không * một cách tiếp cận khả thi trong ngôn ngữ C, vì 'MAX_STRING' sẽ không phải là * hằng số * trong C và sẽ không được phép sử dụng khi biểu thức liên tục là cần thiết. – AnT

38
#define MAX_STRING 256; 

có nghĩa là:

bất cứ khi nào bạn tìm MAX_STRING khi tiền xử lý, thay thế nó với 256;. Trong trường hợp của bạn, nó sẽ làm cho phương thức 2:

#include <stdio.h> 
#include <stdlib.h> 
#define MAX_STRING 256; 

int main(void) { 
    char buffer [256;]; 
} 

không phải là cú pháp hợp lệ.Thay

#define MAX_STRING 256; 

với

#define MAX_STRING 256 

Sự khác biệt giữa hai mã của bạn là trong phương pháp đầu tiên bạn khai báo một tương đương liên tục để 256 nhưng trong mã thứ hai bạn xác định MAX_STRING đứng cho 256; trong tập tin nguồn của bạn .

Chỉ thị #define được sử dụng để xác định giá trị hoặc macro được sử dụng bởi các tiền xử lý để thao tác mã nguồn chương trình trước khi nó được biên dịch. Bởi vì các định nghĩa tiền xử lý được thay thế trước khi trình biên dịch hoạt động trên mã nguồn, bất kỳ lỗi nào được giới thiệu bởi #define đều khó theo dõi.

Cú pháp là:

#define CONST_NAME VALUE 

nếu có một ; ở cuối, nó được xem như một phần của VALUE.

để hiểu chính xác như thế nào #define s làm việc, cố gắng xác định:

#define FOREVER for(;;) 
... 
    FOREVER { 
     /perform something forever. 
    } 

Thú nhận xét bởi John Hascall:

Hầu hết các trình biên dịch sẽ cung cấp cho bạn một cách để xem kết quả sau khi giai đoạn tiền xử lý, điều này có thể hỗ trợ với các vấn đề gỡ lỗi như thế này.

Trong gcc nó có thể được thực hiện với cờ -E.

+5

Hầu hết các trình biên dịch sẽ cung cấp cho bạn một cách để xem đầu ra sau giai đoạn tiền xử lý, điều này có thể hỗ trợ gỡ lỗi các vấn đề như thế này. –

13

Cả hai hằng số? Số

Phương pháp đầu tiên không tạo ra hằng số bằng ngôn ngữ C. Biến số đủ điều kiện Const không đủ điều kiện làm hằng số trong C. Phương thức đầu tiên của bạn chỉ hoạt động vì các trình biên dịch trước C99 C hỗ trợ các mảng có độ dài biến đổi (VLA). buffer là VLA trong trường hợp đầu tiên, cụ thể là vì MAX_STRINGkhông phải một hằng số. Hãy thử khai báo cùng một mảng trong phạm vi tệp và bạn sẽ gặp lỗi vì VLA không được phép trong phạm vi tệp.

Phương pháp thứ hai có thể được sử dụng để gán tên cho các giá trị không đổi trong C, nhưng bạn phải làm điều đó đúng cách. Không được có ; trong định nghĩa macro. Macro hoạt động thông qua thay thế văn bản và bạn không muốn thay thế thêm ; vào khai báo mảng của mình. Cách thích hợp để xác định macro đó là

#define MAX_STRING 256 

Trong ngôn ngữ C, khi nói đến giới hạn về các hằng số được đặt tên thích hợp, về cơ bản bạn bị giới hạn về macro và enums. Đừng cố gắng sử dụng const "hằng số", trừ khi bạn thực sự biết rằng nó sẽ hoạt động cho mục đích của bạn.

+0

Ngoài ra, VLAs không được phép ở phạm vi tệp vì chúng phải được phân bổ động (stack hoặc 'malloc'). –

1

chỉ thị tiền xử lý này:

#define MAX_STRING 256; 

kể tiền xử lý để thay thế tất cả MAX_STRING s với 256; - và với dấu chấm phẩy. Các câu lệnh tiền xử lý không cần dấu chấm phẩy ở cuối. Nếu bạn đặt một, bộ tiền xử lý thực sự nghĩ rằng bạn có nghĩa là nó với một dấu chấm phẩy.

Nếu bạn bị nhầm lẫn với #define s cho các hằng số, const int có thể dễ hiểu hơn.

Nếu bạn muốn tìm hiểu thêm về cách sử dụng đúng các chỉ thị tiền xử lý, hãy thử nhìn vào this website.

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