30/09/2018, 16:01
Hỏi về #pragma trong khai báo thư viện c++
Em đang muốn biết thêm về #pragma once, anh chị nào có thể giúp em được không ạ? Càng nhiều thông tin dễ hiểu càng tốt :))
Bài liên quan
Em đang muốn biết thêm về #pragma once, anh chị nào có thể giúp em được không ạ? Càng nhiều thông tin dễ hiểu càng tốt :))
Anh nhớ anh giải thích cái này ở đâu đó rồi, chắc trên Facebook.
#pragma là gì?
#pragma
nói chung cũng là một tiền xử lý, nó sẽ được thực thi trước khi việc compile xảy ra. Em xem lại phần C của anh có nói về tiền xử lý.#pragma once là gì?
Có nhiều loại lệnh bắt đầu bằng
#pragma
mà trong đó#pragma once
được sử dụng nhiều nhất, được nhiều compiler hỗ trợ. Tuy nhiên#pragma once
không phải là chuẩn.Bài này a có nói về chuẩn và không chuẩn
Công dụng của
#pragma once
là để tránh việc include trùng lặp. Trong tiếng Anh,once
có nghĩa là một lần.#pragma once
đảm bảo cho việc include một file, một lần duy nhất. Ví dụ như sau lấy từ Wikipediapragma once | Wikiwand
In the C and C++ programming languages, #pragma once is a non-standard but widely supported preprocessor directive designed to cause the current source file to be included only once in a single compilation. Thus, #pragma once serves the same purpose...
File “grandparent.h”
File “parent.h”
File “child.c”
File
child.c
vừa includeparent.h
vừa includegrandparent.h
. Chú ý một điều làparent.h
đã includegrandparent.h
. Điều này dẫn đếnchild.c
sẽ includegrandparent.h
hai lần. Như vậy sẽ dẫn đến lỗi nếu có khai báo biến ở filegrandparent.h
. Lỗi đó gọi là lỗi khai báo nhiều lầnredefinition
.Để tránh lỗi xảy ra do include nhiều hơn một lần. Ta thêm
#pragma once
ở filegrandparent.h
. Trước khi compiler thực hiện compile, thì tiền xử lý sẽ đảm bảo child.c chỉ includegrandparent.h
một lần.Cách khác để tránh include nhiều lần
Vậy nếu nói
#pragma once
không phải là chuẩn. Vậy chuẩn thì dùng cái nào? Ta dùng như sauỞ đoạn code trên, người ta dùng một cái mẹo có sẵn trong C. Đó là người ta dùng tiền xử lý #ifndef, có nghĩa là
if not define
==nếu chưa định nghĩa
. Thì mới định nghĩa cái đoạn bên trong của file đó, tức là phần nội dung củagrandparent.h
.Giải thích khi ta include 1 file nhiều lần, như ví dụ trên
child.c
includegrandparent.h
lần đầu thì nội dung củagrandparent.h
sẽ được includechild.c
includegrandparent.h
lần tiếp theo thì nội dung củagrandparent.h
sẽ không được include nữa, vì bây giờ_GRANDPARENT_H
đã được định nghĩa.Vậy
_GRANDPARENT_H
là gì? Thực ra đây là một cái mẹo thôi, tên file gốc làgrandparent.h
thì ta thêm một_
ở trước và thay dấu.
bằng_
. Tất cả các chữ cái viết hoa lên hết là được_GRANDPARENT_H
.Dạ, em cảm ơn…còn nhiều thắc mắt nữa mong sẽ đc anh giải đáp lần sau . cái này hơi dài, e đọc chỉ hiểu dc sơ sơ, anh nói chi tiết, liên quan đến nhiều thứ quá làm e hơi rối.
Mà #pragma once chỉ dùng để tránh include “thư viện.h”(theo em hiểu đây là thư viện tự tạo) nhiều lần, hay là tất cả các thư viện chuẩn của c++ ạ ?
Thư viện hệ thống họ có làm sẵn cái cách khác để tránh include nhiều lần rồi.
thế rốt cuộc cái này là gì hả a?
Cái này là một
#define
thôi, không có ý nghĩa gì cả. Nhưng nó sẽ giúp cho mình đảm bảo filegrandparent.h
không bị include hai lần.không, ý e là cái e trích thôi a ạ. a đặt câu hỏi đó, mà câu trả lời ko rõ, chưa nói đc nó là gì, chức năng của nó ạ
Em đọc lại từ đoạn “Cách khác để tránh include nhiều lần”, anh giải thích chức năng của nó từ đoạn đấy.
thế cái GRANDPARENT kia thay bằng tên gì cũng đc ạ?
Thay bằng gì cũng chạy được. Em thử đi. Nhưng cách tốt nhất vẫn là theo chuẩn trên, tránh nhầm lẫn.
e nghĩ thế này đúng ko a:
Nó định nghĩa thêm một cái gì đó (có phải là hằng???) để qua file khác nếu include rồi tức là phía trên đã định nghĩa cái gì đó rồi (hằng???) nên nó sẽ ko định nghĩa lại, cũng như bỏ qua mấy cái trong
#ifndef ... #endif
luôn.Chính xác rồi đấy, nhưng sao lại nhắc tới hằng? Mình chỉ cần hiểu rằng cái này đã định nghĩa, thế nên bỏ qua.
Đừng thêm chữ hằng vào gây sai vấn đề đi.
vì e thấy chả có gì cả, mỗi cái tên. chắc là nó chỉ định nghĩa cái tên đó thôi a nhỉ.
Em đã chú ý được tới điểm này là rất tốt. Em nhớ lại định nghĩa của macro. Khi mình define tức là mình thay thế vế trái bằng vế phải trong lệnh define
Trong trường hợp này vế phải rỗng, vì ta không quan tâm nó là gì cả. Mình chỉ quan tâm là nó đã được define.
vâng, cái này đấy ạ.
à, ok ok, e hiểu rồi, thế cái mình define trong này là Mr.Nothing.