Macro và Hàm trong ngôn ngữ C

Macro là gì?

  • Marco là 1 tên bất kì (do lập trình viên đặt tên) trỏ tới 1 khối lệnh thực hiện một chức năng nào đó.
  • Trong quá trình tiền xử lí (pre-processor), các macro được sử dụng trong chương trình được thay thế bởi các khối câu lệnh tương ứng.
  • Định nghĩa macro bằng lệnh #define

Ví dụ: định nghĩa macro tính giá trị lớn nhất của 2 số.

#include <stdio.h>
#include <conio.h>

#define MAX(A, B) ((A) > (B) ? (A) : (B))

void main( void )
{
    int a = 5, b = 7;
    float c = 5.6, d = 4.5;
    printf("\nMAX(%d, %d) = %d", a, b, MAX(a, b));
    printf("\nMAX(%f, %f) = %f", c, d, MAX(c, d));
    getch();
}

Kết quả:

Macro tìm giá trị lớn nhất của 2 số nguyên
Macro tìm giá trị lớn nhất của 2 số nguyên

Hàm là gì?

Function là 1 khối lệnh thực hiện một chức năng nào đó.

Ví dụ: viết hàm tìm giá trị lớn nhất 2 số nguyên

#include <stdio.h>
#include <conio.h>

int MAX(int, int);

void main( void )
{
    int a = 5, b = 7;
    printf("\nMAX(%d, %d) = %d", a, b, MAX(a, b));
    getch();
}

int MAX(int a, int b)
{
    return (a > b ? a : b);
}

Kết quả:

Hàm tìm giá trị lớn nhất của 2 số nguyên
Hàm tìm giá trị lớn nhất của 2 số nguyên

Ưu nhược điểm của Macro và Hàm

Macro Hàm
Việc định nghĩa macro khó hơn định nghĩa hàm.

Nếu không chú ý, chúng ta dễ bị side effect. (Mình sẽ phân tích ở phía dưới)

Việc định nghĩa đơn giản hơn
không thể debug tìm lỗi của macro trong thời gian thực thi. Debug đơn giản, dễ bắt lỗi
Macro không cần quan tâm kiểu dữ liệu của tham số và kiểu trả về. Như ví dụ trên, chúng ta có thể truyền kiểu int, float. Phải chỉ rõ kiểu dữ liệu của tham số và giá trị trả về
Macro tạo ra các inline code, thời gian xử lí inline code ngắn hơn thời gian gọi hàm  Chương trình mất time dịch từ vùng nhớ hàm được lưu trữ sang vùng nhớ goi hàm.
Giả sử macro được gọi 20 lần trong chương trình, 20 dòng code sẽ được chèn vào chương trình trong quá trình tiền xử lí. Điều này làm cho kích thước của chương trình (.EXE, .DLL, .LIB,…) phình to ra. Giả sử 1 hàm được gọi 20 lần, sẽ chỉ có 1 bản copy của hàm trong chương trình. Kích thước chương trình nhỏ hơn sử dụng macro.

Tùy thuộc vào tiêu chí thời gian thực thi hay kích thước chương trình, mà lập trình viên quyết định chọn macro hay hàm trong chương trình của mình. Đối với khối chức năng đơn giản ít dòng code, nên sử dụng macro.

Chú ý: khi sử dụng macro để tránh side effect

Ví dụ: tạo macro tính bình phương số nguyên

#include <stdio.h>
#include <conio.h>

#define SQUARE(X) (X*X)

void main( void )
{
    printf("SQUARE(%d) = %d", 3+5, SQUARE(3+5));
    getch();
}

Giải thích:

Kết quả mong muốn sẽ là 8*8 = 64. Nhưng  thực tế, kết quả như sau: 3+5*3+5 = 3 + 15 + 5 = 23.

Khi bạn định nghĩa macro, phải chú ý dấu ngoặc. Macro SQUARE được update lại như sau:

#define SQUARE(X) ((X)*(X))

Kết quả:

Hàm tính bình phương số nguyên
Hàm tính bình phương số nguyên

Be the first to comment

Leave a Reply