Bộ tiền xử lý trong C
Bộ tiền xử lý trong C ở đây không phải là một phần của bộ biên dịch, nhưng có những bước riêng rẽ trong quá trình biên dịch. Theo cách hiểu cơ bản nhất, bộ tiền xử lý trong ngôn ngữ C là các công cụ thay thế văn bản và hướng dẫn trình biên dịch không yêu cầu tiền xử lý trước khi được biên dịch. Chúng tôi hướng đến bộ tiền xử lý C như CPP.
Tất cả các lệnh tiền xử lý bắt đầu với ký thự #. Nó ít nhất không phải là ký tự trắng, để dễ dàng đọc. Dưới đây là danh sách các thẻ tiền xử lý quan trọng.
Directive | Miêu tả |
---|---|
#define | Thay thể cho bộ tiền xử lý macro |
#include | Chèn một header đặc biệt từ file khác |
#undef | Không định nghĩa một macro tiền xử lý |
#ifdef | Trả về giá trị true nếu macro này được định nghĩa |
#ifndef | Trả về giá trị true nếu macro này không được định nghĩa |
#if | Kiểm tra nếu điều kiện biên dịch là đúng |
#else | Phần thay thế cho #if |
#elif | #else một #if trong một lệnh |
#endif | Kết thúc điều kiện tiền xử lý |
#error | In thông báo lỗi trên stderr |
#pragma | Thông báo các lệnh đặc biệt đến bộ biên dịch, sử dụng một phương thức được tiêu chuẩn hóa |
Ví dụ bộ tiền xử lý trong C
Phân tích các ví dụ sau để hiểu các directive đa dạng.
#define DO_DAI_MANG_TOI_DA 20
Tiền xử lý này thông báo cho trình biên dịch C thay thế DO_DAI_MANG_TOI_DA với 20. Sử dụng #define cho các hằng số làm tăng khả năng đọc của chương trình.
#include#include "headercuatoi.h"
Tiền xử lý này thông báo cho trình biên dịch lấy thư viện stdio.h từ Thư viện hệ thống và thêm vào mã nguồn hiện tại. Dòng kế tiếp thông báo cho trình biên dịch lấy tệp headercuatoi.h từ thư mục máy tính và thêm nội dung và mã nguồn hiện tại.
#undef KICH_CO_FILE #define KICH_CO_FILE 42
Tiền xử lý này thông báo cho trình biên dịch vộ hiệu hóa biến KICH_CO_FILE và định nghĩa mới có giá trị 42.
#ifndef THONGDIEP #define THONGDIEP "Chao mung chang dep trai nhat nha!" #endif
Điều này thông báo cho trình biên dịch ngôn ngữ C định nghĩa THONGDIEP nếu THONGDIEP không được định nghĩa.
#ifdef DEBUG /* tai day la phan lenh de debug cua ban */ #endif
Điều này thông báo cho tiền xử lý thao tác đoạn lệnh nếu DEBUG được định nghĩa.
Các Macro được định nghĩa trước trong C
ANSI C định nghĩa một số các macro. Mặc dù mỗi macro này có sẵn cho bạn sử dụng trong chương trình, bạn không nên chỉnh sửa một cách trực tiếp các macro được định nghĩa trước này.
Macro | Miêu tả |
---|---|
__DATE__ | Ngày hiện tại, như là một hằng số ký tự, trong định dạng "MMM DD YYYY" |
__TIME__ | Thời gian hiện tại, như là một hằng số ký tự, trong định dạng "HH:MM:SS" |
__FILE__ | Nó chứa tên file hiện tại như là một hằng số chuỗi |
__LINE__ | Nó chứa số dòng hiện tại như là một hằng số thập phân |
__STDC__ | Được định nghĩa là 1 khi bộ biên dịch biên dịch với chuẩn ANSI |
Bạn thử ví dụ sau:
#includemain() { printf("File :%s\n", __FILE__ ); printf("Date :%s\n", __DATE__ ); printf("Time :%s\n", __TIME__ ); printf("Line :%d\n", __LINE__ ); printf("ANSI :%d\n", __STDC__ ); printf("\n===========================\n"); printf("VietJack chuc cac ban hoc tot! \n");}
Khi chương trình C trên trong file Untitled4.cpp được biên dịch và thực hiện. Nó sẽ in ra kết quả sau đây:
Toán tử tiền xử lý trong C
Ngôn ngữ C cung cấp các toán tử sau giúp bạn tạo các macro:
Toán tử tiếp tục (\) của macro trong C
Một macro thường được bao gồm trong 1 dòng đơn. Toán tử tiếp tục của macro thường được sử dụng để tiếp tục một macro nếu có nhiều hơn một dòng. Ví dụ:
#define thong_diep(a, b) \ printf(#a " va " #b ": nghia la Forever Alone!\n")
Dấu thăng (#) trong C
Toán tử stringize - dấu thăng ('#'), khi được sử dụng trong một định nghĩa macro, chuyển đổi một tham số macro thành một hằng số chuỗi. Toán tử này có thể sử dụng với macro để xác định một tham số cụ thể trong danh sách tham số. Ví dụ:
#include#define thong_diep(a, b) \ printf(#a " va " #b ": nghia la Forever Alone!\n")int main(void) { thong_diep(F, A); printf("\n===========================\n"); printf("VietJack chuc cac ban hoc tot! \n"); return 0; }
Biên dịch và thực thi chương trình C trên sẽ cho kết quả sau:
Toán tử Token Pasting (##) trong C
Toán tử token pasting (##) sử dụng trong một định nghĩa macro kết nối 2 tham số. Nó cho phép 2 token riêng biệt trong định nghĩa marco có thể kết hợp thành 1 token. Do đó nó còn được gọi là toán tử ghép. Ví dụ:
#include#define vidutoken(n) printf ("token" #n " = %d", token##n)int main(void) { int token1 = 123; vidutoken(1); printf("\n===========================\n"); printf("VietJack chuc cac ban hoc tot! \n"); return 0; }
Biên dịch và thực thi chương trình C trên sẽ cho kết quả sau:
Nó xảy ra thế nào, bởi vì ví dụ này có kết quả là đầu ra thực sự từ bộ tiền xử lý:
printf ("token1 = %d", token1);
Ví dụ này chỉ ra sự móc nối của token##n trong token34 và ở đây chúng tôi đã sử dụng cả stringize và token-pasting.
Toán tử defined() trong C
Toán tử tiền xử lý defined được sử dụng với biểu thức hằng để xác định nếu một định danh được định nghĩa bởi #define. Nếu định danh đã xác định được định nghĩa, thì giá trị là true (khác 0). Nếu chưa được định nghĩa thì giá trị là false (zero). Toán tử được định nghĩa được xác định như sau:
#include#if !defined (THONGDIEP) #define THONGDIEP "Chao mung chang dep trai nhat nha!" #endifint main(void) { printf("Dev-C++: %s\n", THONGDIEP); printf("\n===========================\n"); printf("VietJack chuc cac ban hoc tot! \n"); return 0; }
Biên dịch và thực thi chương trình C trên sẽ cho kết quả sau:
Macro tham số trong C
Một trong những tính năng mạnh mẽ của CPP là khả năng bắt chước các hàm bởi sử dụng các macro tham số. Ví dụ, chúng ta có thể có một đoạn code để bình phương một số như sau:
int binhphuong(int x) { return x * x; }
Chúng ta có thể viết lại code trên bởi sử dụng một macro như sau:
#define binhphuong(x) ((x) * (x))
Các macro với các tham số phải được định nghĩa bởi sử dụng #define trước khi chúng có thể được sử dụng. Danh sách tham số được bao quanh trong dấu ngoặc đơn và phải ngay lập tức theo tên macro. Các khoảng trống là không được phép ở giữa tên macro và các dấu ngoặc đơn mở. Ví dụ:
#include#define LONNHAT(x,y) ((x) > (y) ? (x) : (y))int main(void) { printf("Gia tri lon nhat giua 123 va 321 la %d\n", LONNHAT(123, 321)); printf("\n===========================\n"); printf("VietJack chuc cac ban hoc tot! \n"); return 0; }
Biên dịch và thực thi chương trình C trên sẽ cho kết quả sau:
Các bài học lập trình C phổ biến khác tại VietJack: