C/C++

C/C++ Preprocessor Directives

Xin chào, trong bài viết này chúng ta sẽ tìm hiểu về một số directive của ngôn ngữ C/C++.

Mỗi directive được bắt đầu bởi ký tự # và có thể được biểu diễn ở nhiều dòng với ký tự backslash ( \ ) ở cuối mỗi dòng.

Bộ biên dịch C/C++ sẽ xử lý các directive trước khi bắt đầu biên dịch mã nguồn.


#include

Directive #include được dùng để gọi các file header sẽ được sử dụng cùng với source code. Gồm 2 kiểu:

  • #include <filename>: sử dụng cho standard library header;
  • #include “filename”: sử dụng cho user-defined header.

#define và #undef

Directive #define được dùng để định nghĩa các macros, trong khi đó #undef được dùng để xóa một macro đã được định nghĩa từ trước.

Cú pháp:

#define name[(parameter_list)] [replacement_text]

#undef name

Trong đó:

  • parameter_list – các tham số đi kèm với macro name; không bắt buộc.
  • replacement_text – nội dung sẽ được thay thế macro name mỗi khi macro name xuất hiện trong file; không bắt buộc.

#ifdef, #ifndef, #else, #endif

Các directives này được sử dụng để kiểm tra xem macro đã được định nghĩa hay chưa, trong đó:

  • #ifdef name – trả về 1 nếu macro name đã được định nghĩa trước đó;
  • #ifndef name – trả về 1 nếu macro name chưa được định nghĩa;
  • #else – điều kiện ngược lại;
  • #endif – kết thúc điều kiện #ifdef hoặc #ifndef.

#if, #elif, #else, #endif

Các derectives này được sử dụng để kiểm tra trạng thái của các macro, được sử dụng tương tự với mệnh đề if/else.


#error

Khi gặp derective #error, quá trình biên dịch sẽ bị ngừng lại và một message sẽ được cung cấp.

#error message


Example

File: header.h

#ifndef HEADER_H
#define HEADER_H

#define BUF_SIZE 512
#define MAX(a,b) (((a) > (b)) ? (a):(b))

#define DEBUG 1
#endif

File: source.c

#include
#include "header.h"

int main() {
    char data[BUF_SIZE];
    int a = 100, b = 50;
    printf("max(%d,%d) = %d\n", a, b, MAX(a,b));

    #if DEBUG == 1
        printf("Debug enabled.\n");
    #else
        printf("Debug disabled.\n");
    #endif

    #ifdef DEV_MODE
        #error DEV_MODE macro should be disabled.
    #endif
}

Executation:
$ gcc source.c -o main

Output:
max(100,50) = 100
Debug enabled.

Giải thích:
– File header.h:

  • dòng 1 – được gọi là Include Guard, dùng để đảm bảo file header.h được include vào source.c chỉ một lần duy nhất;
  • dòng 4 – khai báo macro BUF_SIZE với giá trị thay thế là 512;
  • dòng 5 – khai báo macro MAX với 2 tham số a, b và giá trị thay thế là một mệnh đề if ở dạng rút gọn.

– File source.c:

  • dòng 9-13: kiểm tra giá trị của macro DEBUG và in ra thông báo tương ứng;
  • dòng 15-17: kiểm tra xem macro DEV_MODE đã được khai báo chưa, nếu có thì dừng biên dịch và thông báo lỗi.

Bên cạnh việc định nghĩa macro trong file header.h, chúng ta có thể thêm macro vào chương trình trong quá trình biên dịch với option -D macro[=define]. Các bạn hãy biên dịch lại chương trình với lệnh: “gcc source.c -D DEV_MODE -o main” để hiểu rõ hơn.

Cảm ơn các bạn đã theo dõi bài viết.
Thân ái và quyết thắng.


Reference:
[1] Macro defined in main.c not visible in another included file.
[2] Options Controlling the Preprocessor.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s