STDIO
Tìm kiếm gần đây

    Nội dung

    Preprocessor Và #include Directive

    Amy

    10/06/2015
    27/02/2016
    Preprocessor Và #include Directive
    Chỉ thị tiền xử lí (preprocessor) là những chỉ thị cung cấp hướng dẫn trình biên dịch xử lí trước các thông tin trước khi bước vào giai đoạn biên dịch thực tế. Những hướng dẫn này có thể bao gồm một thư viện hay một số hướng dẫn đặc biệt để trình biên dịch hiểu về một số điều kiện nhất định được sử dụng trong chương trình.

    Giới thiệu

    Chỉ thị include (include directive) là thuật ngữ không hề xa lạ đối với những bạn bước đầu tìm hiểu lập trình và những lập trình viên trong quá trình sử dụng ngôn ngữ C/C++. Bài viết này nhằm giúp các bạn sẽ hiểu rõ hơn, sâu hơn về khái niệm cũng như cách sử dụng chỉ thị này. Qua đó, các bạn có thể sử dụng chúng một cách linh hoạt, đồng thời tránh những sai lầm khi sử dụng.

    Tiền đề bài viết

    Trong quá trình học tập tại STDIO Training, tôi nhận ra rằng mình cùng một số các lập trình viên khác vẫn chưa hiểu thật sự bản chất của include directive cũng như preprocessor, dẫn đến đã sử dụng sai lầm thành một thói quen. Sau một thời gian học lập trình C/C++ tại STDIO Training, tôi đã quyết định viết ra bài viết này nhằm chia sẻ những quan điểm, suy nghĩ của mình về vấn đề trên.

    Đối tượng hướng đến

    Bài viết hướng đến đối tượng là những lập trình viên mới bắt đầu học lập trình căn bản và những lập trình viên muốn hiểu rõ hơn về include directive trong chương trình C/C++.

    Preprocessor là gì?

    Bất cứ một file C++ hoặc C nào khi được biên dịch cũng sẽ trải qua các bước sau:

    ss_1

    Chỉ thị tiền xử lí (preprocessor) là những chỉ thị cung cấp hướng dẫn trình biên dịch xử lí trước các thông tin trước khi bước vào giai đoạn biên dịch thực tế. Các quá trình hướng dẫn đặc biệt này có thể được viết trong một chương trình C/C++. Những hướng dẫn này có thể bao gồm một thư viện hay một số hướng dẫn đặc biệt để trình biên dịch hiểu về một số điều kiện nhất định được sử dụng trong chương trình.

    Preprocessor được nhận biết là những dòng code bắt đầu với một kí tự #. Trước nó có thể tồn tại các khoảng trắng và preprocessor chỉ kéo dài trên một dòng code. Ngay sau khi một kí tự xuống dòng được phát hiện, các preprocessor kết thúc. Các preprocessor không phải là lệnh của ngôn ngữ C/C++ nên không kết thúc bằng dấu chấm phẩy.

    Các preprocessor khác nhau sẽ thực hiện các nhiệm vụ khác nhau. Chúng ta có thể phân loại preprocessor như sau:

    • Inclusion directives
    • Macro Definition Directives
    • Conditional Compilation Directives

    Trong bài này, tôi chỉ đề cập đến Inclusion Directives.

    #include directive là gì?

    Một trong những ứng dụng phổ biến nhất của preprocessor đó là inclusion directive. Thể loại này chỉ có một chỉ thị, đó là #include. Chắc hẳn, lệnh này không xa lạ gì với các lập trình viên đã từng học qua C/C++. Vì quá quen thuộc nên có thể dẫn đến nhiều suy nghĩ sai lầm về nó. Và tôi cũng đã từng như thế. Lúc đầu, tôi chỉ suy nghĩ đơn giản đó là một trong những thủ tục bắt buộc hoặc lệnh hệ thống khi muốn sử dụng C/C++. Sau một thời gian, từ việc học hỏi, chia sẻ kinh nghiệm của những người thầy, người anh tôi phát hiện ra những suy nghĩ của mình hoàn toàn sai lầm. Vậy đến khi chúng ta sử dụng lệnh #include, điều gì đang diễn ra bên trong nó?

    Câu trả lời là trước khi vào giai đoạn Compile, chỉ thị #include sẽ chỉ thị cho bộ tiền xử lí tìm kiếm tập tin theo tên được ghi trong lệnh #include. Nếu tìm thấy, bộ tiền xử lí sẽ nhận nội dung của tập tin đó và đặt chèn vào tập tin nguồn đang xét ngay đúng vị trí của #include xuất hiện. Ngược lại, nếu không tìm thấy tập tin, chương trình sẽ thông báo lỗi: 

    Error C1083: Cannot open include file

    Ta có một ví dụ về #include:

    stdio_thuy_library.h

    int add(int a, int b)
    {
    	return a + b;
    }

    stdio_thuy_library_implement.cpp

    #include "stdio_thuy_library.h"
    
    #include <iostream>
    using namespace std;
    
    int main()
    {
    	cout << add(5, 10);
    	return 0;
    }
    

    Như ví dụ trên ta thấy có 2 cách sử dụng #include đó là:

    • #include <filename>
    • #include "filename"

    Khi #include được viết với dấu ngoặc nhọn có nghĩa chúng ta đã cung cấp hướng dẫn cho bộ tiền xử lí tìm kiếm tập tin theo một đường dẫn được xác định trong các thư mục include được trình biên dịch thiết lập, chẳng hạn như các thư viện chuẩn của C++( iostream, string…). Còn khi #include được viết với dấu ngoặc kép, con đường tìm kiếm của bộ tiền xử lí được mở rộng, bao gồm cả các thư mục hiện hành. Trình biên dịch C/C++ và môi trường lập trình đều có một cơ sở cho phép lập trình viên xác định nơi bao gồm các tập tin có thể được tìm thấy. Trong trường hợp tập tin không được tìm thấy ở các thư mục hiện hành, các thư mục include của trình biên dich sẽ được kiểm tra, hay các bạn có thể xem như dấu ngoặc kép được thay thế bởi các dấu ngoặc nhọn <...>.

    Ưu điểm

    Include directive cho phép các thư viện code được phát triển nhằm:

    • Đảm bảo rằng tất cả mọi người sử dụng cùng một phiên bản của một định nghĩa bố trí dữ liệu hoặc mã thủ tục trong suốt một chương trình.
    • Dễ dàng tham chiếu chéo những thành phần được sử dụng trong một hệ thống.
    • Dễ dàng thay đổi chương trình khi cần thiết (chỉ cần một bản sao thay đổi).
    • Tiết kiệm thời gian.

    Nhược điểm

    Bên cạnh những ưu điểm trên, include directive vẫn tồn tại nhược điểm. Đó là có thể xảy ra tình trạng khai báo lại những đối tượng đã được khai báo. Chẳng hạn như, 2 file stdio_a.h và stdio_b.h đều chứa:

    #include "stdio_c.h"

    Vậy nếu 1 file khác include 2 file trên:

    • #include "stdio_a.h"
    • #include "stdio_b.h"

    Thì trong file đó sẽ có 2 phần nội dung trùng lắp từ file stdio_c.h và có thể gây ra lỗi biên dịch (một class được định nghĩa 2 lần).

    Lời kết

    Thông qua bài viết này, tôi mong rằng các bạn sẽ hiểu rõ hơn về bản chất, tác dụng của include directive cũng như preprocessor. Từ đó tránh được những sai lầm khi sử dụng chúng. Trên đây chỉ là những kiến thức do chính bản thân tôi tích luỹ, do đó mong rằng sẽ nhận được sự đóng góp từ các bạn để hoàn thiện hơn bài viết.

    Thảo luận

    In order to comment you must be a STDIO Insider. Please sign up or log in to continue.

    Đăng nhập

    Bài viết liên quan

    Conditional Compilation Directives Giải Quyết Xung Đột Include

    Conditional Compilation Directives Giải Quyết Xung Đột Include

    Trong quá trình xây dựng các thư viện mã nguồn, nếu không có phương pháp kiểm soát tốt, include directive sẽ làm cho một đoạn mã nguồn được khai báo nhiều lần dẫn đến ...

    Đinh Hòa

    03/09/2015

    Khảo Sát File Sau Khi Preprocess Với Visual Studio C++

    Khảo Sát File Sau Khi Preprocess Với Visual Studio C++

    Cách thức tạo ra file sau khi preprocess một file .cpp hoặc .c với Visual Studio, sau khi tạo ra ta có thể khảo sát nhằm xem xét việc hoạt động của các Directive trong ...

    La Kiến Vinh

    28/07/2014

    Inline Functions Trong C++

    Inline Functions Trong C++

    Bài viết giới thiệu về Inline function (hàm nội tuyến) trong ngôn ngữ lập trình C/C++. Có phải chăng inline functions là một loại function và được cải tiến hơn? Cùng đọc ...

    Amy Lê

    10/06/2015

    Compiler Warning C4996 và C Run-time Library hay _CRT_SECURE_NO_WARNINGS (CRT)

    Compiler Warning C4996 và C Run-time Library hay _CRT_SECURE_NO_WARNINGS (CRT)

    Compiler warning C4996 là cảnh báo thường gặp khi sử dụng các hàm strcpy hay scanf trong Visual Studio từ bản 2012 trở đi. Bài viết sẽ giúp bạn hiểu rõ và khắc phục cảnh ...

    Trần Thị Thu Hiền

    10/12/2014

    Chỉ Thị Tiền Xử Lý Trong C/C++

    Chỉ Thị Tiền Xử Lý Trong C/C++

    Chỉ thị tiền xử lý là những chỉ thị cung cấp cho bộ tiền xử lý để xử lý những thông tin trước khi bắt đầu quá trình biên dịch. Tất cả các chỉ thị tiền xử lý đều bắt đầu ...

    Phạm Hoài Nguyên

    10/08/2016

    Nhập Xuất Cơ Bản Trong C

    Nhập Xuất Cơ Bản Trong C

    Trong bất cứ một ngôn ngữ lập trình nào, việc tương tác trực tiếp với máy tính là rất quan trọng và cần thiết. Một chương trình được viết ra cần có khả năng nhận dữ liệu ...

    Rye Nguyen

    28/07/2015

    Xử Lý Sự Kiện Chuột Và Phím Với Borland Graphics Interface - BGI

    Xử Lý Sự Kiện Chuột Và Phím Với Borland Graphics Interface - BGI

    Đối với các ứng dụng đồ họa, ví dụ như: vẽ, xử lý văn bản, xử lý bảng tính … thì có thể nói việc nhận và xử lý các sự kiện chuột và bàn phím gần như là điều tiên quyết. ...

    Amy Lê

    17/07/2015

    Phân Tích Dữ Liệu Và Viết Rule Cho Modsecurity

    Phân Tích Dữ Liệu Và Viết Rule Cho Modsecurity

    Giới thiệu về hệ thống trích xuất và phân tích dữ liệu của mình thông qua Modsecurity, tiếp đến tôi sẽ giới thiệu chi tiết về chương trình phân tích dữ liệu đã thu thập ...

    Nguyễn Hồng Hải Đăng

    01/04/2015

    Kỹ Thuật Grayscale Và Nhị Phân Hoá Ảnh (Adaptive Threshold)

    Kỹ Thuật Grayscale Và Nhị Phân Hoá Ảnh (Adaptive Threshold)

    Nẳm trong loạt bài viết trong chương trình Tự Học OpenCV Qua Các Ví Dụ Thực Tế. Bài viết sẽ giới thiệu và chi tiết các thuật toán Grayscale, ảnh nhị phân và một số thuật ...

    Trương Xuân Đạt

    23/01/2015

    Làm Quen Với SQL Server

    Làm Quen Với SQL Server

    Database là nơi tạo, cập nhật và lưu trữ các thông tin của một hệ thống. Nếu không có database, sẽ không có thế giới thông tin, không có cộng đồng mạng hay bất cứ hoạt ...

    Rye Nguyen

    30/07/2015

    STDIO
    Trang chính
    Công ty TNHH STDIO

    30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
    +84 28.36205514 - +84 942.111912
    developer@stdio.vn

    383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
    Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012

    ©STDIO, 2013 - 2020