Chào mừng bạn đến blog Cốc Cốc News Tin Tức Trang Chủ

Table of Content

Video Bộ tiền xử lý c được chỉ định bằng ký hiệu: ?

Thủ Thuật Hướng dẫn Bộ tiền xử lý c được chỉ định bằng ký hiệu: Mới Nhất

Bùi Ngọc Phương Anh đang tìm kiếm từ khóa Bộ tiền xử lý c được chỉ định bằng ký hiệu: được Cập Nhật vào lúc : 2022-08-08 00:50:06 . Với phương châm chia sẻ Bí kíp Hướng dẫn trong nội dung bài viết một cách Chi Tiết 2022. Nếu sau khi tham khảo tài liệu vẫn ko hiểu thì hoàn toàn có thể lại Comment ở cuối bài để Mình lý giải và hướng dẫn lại nha.

Bộ tiền xử lý – Lập trình C : Bài 20

1. Giới thiệu

Trong những bài đã trình bày ở những phần trước, tất cả chúng ta đã sử dụng những thông tư như #include, #define, và tất cả chúng ta cũng không cần quan tâm rõ ràng về những thông tư này hoạt động và sinh hoạt giải trí ra làm sao.

Thực chất những thông tư #include, define và một số trong những những thông tư khác được xử lý bởi bộ tiền xử lý (prepeocessor). Bộ tiền xử lý theo định nghĩa nó là một phần phần nhỏ và được biên soạn bởi chương trình C. Nó thực thi trước khi thực hiện biên dịch chương trình.

Bộ tiền xử lý là một công cụ mạnh mẽ và tự tin của lập trình C. Tuy nhiên với những lập trình viên khi xuất hiện lỗi với bộ tiền xử lý thì vấn đề tìm ra bugs là một thách thức. Ngoài ra bộ tiền xử lý rất dễ gây ra ra việc sử dụng sai và nó cũng là nguyên nhân gây ra sự khó hiểu của chương trình. Tuy nhiên với sức mạnh và tính tiện lợi của cục tiền xử lý vẫn được sử dụng rộng dãi khi xây dựng những ứng dụng bằng việc sử dụng ngôn từ lập trình C.

1.1. Sử dụng bộ tiền xử lý:

Xét theo khía cạnh tổng quát trong phát triển và xây dựng ứng dụng thì bộ tiền xử lý được sử dụng để xử lý và xử lý những trường hợp:

Tính khả chuyển – Portability: Xây dựng ứng dụng C cần tương hỗ chạy trên nhiều những nền tảng Hệ điều hành hoặc những môi trường tự nhiên thiên nhiên rất khác nhau là một yêu cầu trên thực tế. Bộ tiền xử lý được xem là một cách thuận tiện để đảm bảo tính khả chuyển của khối mạng lưới hệ thống khi khối mạng lưới hệ thống chạy trên nhiều hệ điều hành, môi trường tự nhiên thiên nhiên rất khác nhau. Ví dụ : Lập trình viên sử dụng những thông tư điều kiện (#if, #else, # if defined ...) để kiểm tra những thiết lập cho chương trình khi chạy trên những hệ điều hành, môi trường tự nhiên thiên nhiên rất khác nhau. Dựa trên những thông tin đã được thiết lập này, lập trình viên sẽ sử dụng một số trong những những macro, những thư viện.. tương ứng với từng hệ điều hành, môi trường tự nhiên thiên nhiên rõ ràng. Ví dụ sử dụng #include khi chương trình C chạy trên hệ điều hành Linux hoặc MacOS...

Tính biến hóa – Variability: Lập trình viên thường sủ dụng thông tư điều kiện (#if, #else, # if defined ...) để đáp ứng những đặc tính tùy chọn hoặc để lựa chọn một trong những giải pháp thực thi. Ví dụ : Sử dụng thông tư điều kiện để vô hiệu một phần thư viện không thiết yếu của ứng dụng nhằm mục đích tăng tính hiệu năng của khối mạng lưới hệ thống và giảm kích cỡ ứng dụng. Tính năng DEBUG là một ví dụ về vấn để này. Sử dụng DEBUG thường là để in ra dòng thông báo khi chương trình xảy ra lỗi, với người tiêu dùng cuối DEBUG không còn ý nghĩa tuy nhiên với lập trình viên, sử dụng DEBUG để ngăn ngừa những lỗi xẩy ra không đáng có và hoàn toàn có thể là nguyên nhân gây ra chương trình bị lỗi.

Tối ưu mà - Code Optimization: Một số nhà lập trình viên nhận định rằng, ngoài việc loại trừ một số trong những hiệu suất cao không thiết yếu, họ cũng sử dụng những thông tư điều kiện nhằm mục đích để tối ưu những đoạn mã và giảm kích cỡ chương trình.

Tiến hóa mã - Code Evolution: Một số lập trình viên thường sử dụng những thông tư điều kiện để khi tăng cấp hoặc tối ưu Code gắn với một hiệu suất cao nào đó. (Sử dụng thông tư có điều kiện hoàn toàn có thể thiết lập một hàm hay một nhóm hàm gắn với một hiệu suất cao rõ ràng hoàn toàn có thể chạy trên nhiều phiên bản rất khác nhau. Điều này được cho phép những lập trình viên hoàn toàn có thể kiểm định được những tính năng mới phát triển của khối mạng lưới hệ thống.

Giới hạn ngôn từ - Language Limitations: Một số nhà phát triển đề cập đến việc sử dụng những thông tư có điều kiện vì những hạn chế của ngôn từ C. Ví dụ : Họ sử dụng #ifdef để kiểm tra tránh việc sử dụng cùng lúc nhiều những tệp header.

1.2. Bộ tiền xử lý trong lập trình

Cụ thể trong lập trình bộ tiền xử lý được sử dụng để:

Bao hàm những tệp header : Khi xây dựng khối mạng lưới hệ thống những lập trình thông thường phải gọi đến những thư viện được đáp ứng sẵn bởi ngôn từ lập trình C. Để thực hiện điều này thì những lập trình viên thường sử dụng thông tư #include để thực hiện.

Mở rộng và định nghĩa những macro: Các lập trình viên hoàn toàn có thể định nghĩa những macro, đó là những chữ viết tắt cho những đoạn mã C tùy ý. Bộ tiền xử lý sẽ thay thế những macro bằng định nghĩa của chúng trong suốt chương trình. Một số macro được C định nghĩa sẵn.

Chỉ thị có điều kiện: Trong một số trong những những trường hợp lập trình viên nên phải vô hiệu hoặc gồm có (chứa) những đoạn mã của chương trình.

Chẩn đoán: Trong quá trình chạy chương trình, chương trình hoàn toàn có thể bị lỗi, sử dụng bộ tiền xử lý để hạn chế những lỗi phát sinh không đáng có và thông báo cho những nhà phát triển và người tiêu dùng. Ví dụ như dùng DEBUG.

1.3 Bộ tiền xử lý thao tác ra làm sao

Các hành vi của cục tiền xử lý được điều khiển bởi những thông tư của cục tiền xử lý: Các thông tư được đánh dấu khởi đầu bằng kí tự #, tất cả chúng ta đã gặp 2 tiền xử lý #include và #define ở những phần mà tôi đã trình bày.

Chỉ thị #define định nghĩa một macro gồm mang tên của macro và thực thể của nó (đôi khi nó hoàn toàn có thể như một hằng hoặc là một biểu thức). Khi một tiền xử lý được sử dụng trong chương trình, chương trình gặp tên marcro thì nó sẽ thay thế tên macro đó bằng chính nội dung của macro.

Chỉ thị #include thông báo cho bộ tiền xử lý mở một file được xác định thông qua tên file với nội dung gắn với file này và coi nội dung file như thể một phần đã được biên dịch bởi chương trình.

Ví dụ : #include

Chỉ thị cho bộ tiền xử lý mở file stdio.h và mang nội dung của file này vào trong chương trình. Stdio.h chứa những nguyên mẫu của những hàm vào/ra chuẩn của ngôn từ C.

Lược đồ mô tả thứ vai trò của cục tiền xử lý trong biên dịch chương trình.

Bộ tiền xử lý c được chỉ định bằng ký hiệu:

Hình số 1 : Vai trò tiền xử lý trong xử lý chương trình C

Đầu vào của tiền xử lý là chương trình C. Trong chương trình C chứa những thông tư và bộ tiền xử lý sẽ thực thi những thông tư. Đầu ra của khi kết thúc quá trình tiền xử lý là một chương trình C khác, phiên bản mới sẽ được update và không hề chứa những thông tư của cục tiền xử lý nữa (Vì những thông tư của cục tiền xử lý đã được thay thế bằng nội dung của nó). Nội dung này sẽ làm đầu vào trực tiếp cho trình biên dịch. Trình biên dịch sẽ thực hiện kiểm tra cú pháp, ngữ nghĩa khi thực hiện biên dịch chương trình.

2. Chỉ thị tiền xử lý Include

Chỉ thị Tiền xử lý #include được sử dụng để chèn tệp tiêu đề vào chương trình thông qua cú pháp :

#include

Hoặc

#include “filename”

Các file được thông tư tiền xử lý thông qua #include được gọi là những header file(file tiêu đề). File tiêu đề là file chứa những khai báo hoặc những định nghĩa macro và hoàn toàn có thể là cả tài liệu mang tính chất chất toàn cục. Các file tiêu đề này hoàn toàn có thể được chia sẻ ở nhiều những file chứa mã nguồn xử lý trách nhiệm của chương trình.

Lưu ý : filename hoàn toàn có thể là tên gọi file đầy đủ của file header hay nói cách khác là hoàn toàn có thể chứa cả đường dẫn tới file header.

Ví dụ :

#include

Trong hệ điều hành Unix, thì với trình biên dịch C thuần, những file header sẽ nằm ở thư mục /usr/include.

Khi thực hiện thông tư #include thì chương trình sẽ thực hiện tìm kiếm những file tiêu đề tại thự mục mặc định hoặc lại thư mục chứa những file .c (mã nguồn của chương trình).

2.1. Các file tiêu đề phục vụ 2 mục tiêu

+ File tiêu đề chứa những khai báo và những macro được tương hỗ sẵn bởi ngôn từ C. File tiêu đề có đuôi mở rộng là .h; Khi những lập trình viên cần sử dụng thì sẽ sử dụng #include để gọi đến thư viện chứa những file tiêu đề này.

+ Các file tiêu đề (header) do những lập trình viên tự định nghĩa. Khi đó nó sẽ đóng vai trò như thể những interface thực hiện tiếp xúc Một trong những file nguồn trong chương trình. Khi xây dựng chương trình, bạn cần nhóm những vấn đề có liên quan với nhau và định nghĩa những marcro cho việc xử lý tập hợp vấn đề phát sinh thì bạn lên sử dụng file tiêu đề để chứa những thông tin này.

Thực chất quá trình sử dụng thông tư #include hoặc #include “filename” tại những file nguồn .c có kết quả in như thể thực hiện copy nội dung của file header vào trong file nguồn .c của chương trình. Tuy nhiên nếu thực hiện copy (Theo nghĩa thông thường) thì sẽ gây mất thời gian và rất dễ lỗi. Với file header, việc khai báo thông qua việc sử dụng #include chỉ xuất hiện ở một nơi trong file nguồn (file .c).

Nếu vì một nguyên do nào đó cần update những file header thì quá trình này sẽ được thực hiện tại nơi chứa những file header, và tại file nguồn không cần sửa đổi gì cả và nội dung thực thi của chương trình sẽ tự động update lại khi chương trình được biên dịch lại.

Ví dụ :

Khi tất cả chúng ta thao tác với tài liệu file, tất cả chúng ta phải sử dụng những hàm như fopen khi đó tất cả chúng ta nên phải tương hỗ update thông tư bộ tiền xử lý sau :

#include

Trong nội dung của file studio.h chứa nội dung là những nguyên mẫu những hàm như sau :

FILE *fopen( const char *, const char * );

size_t fread( void *, size_t, size_t, FILE * );

FILE *freopen( const char *, const char *, FILE * );

char *tempnam( char *, char * );

FILE *tmpfile( void );

char *tmpnam( char * );

extern long ftell( FILE * );

2.2. Sử dụng file tiêu đề để chứa tài liệu toàn cục

Khi lập trình, những lập trình viên hoàn toàn có thể khai báo biến

int global_counter;

char global_char;

main()

...

Khi đó những biến global_counter, global_char sẽ được sử dụng trên phạm vi toàn bộ chương trình. Ngoài cách này ra thì những lập trình viên hoàn toàn có thể định nghĩa những biến này trong file header như sau:

Tạo file "global_decs.h", trong file global_decs.h chứa những khai báo

int global_counter;

char global_char;

Khi đó trong những đoạn mã muốn sử dụng 2 biến này tất cả chúng ta sẽ phải

#include "global_decs.h"

2.3. Khai báo biến toàn cục với từ khóa extern

Trong lập trình C, sử dụng từ khóa extern để khai báo một biến sử dụng chung mang tính chất chất toàn cục trong phạm vi của một module nào đó. Khi khai báo một biến có từ khóa extern thì biến đó sẽ tránh việc phải khởi tạo giá trị ban đầu tại file header thay vào đó lập trình viên sẽ khởi tạo giá trị của biến này tại những file nguồn .c; Lưu ý tại file header khi khai báo biến với từ khóa extern nên phải sử dụng comment để ghi chú thích đối với từng biến.

Ví dụ

Định nghĩa file globalvar.h có nội dung

/* Initialized to 1 in start.c */

extern int page_num;

Khi đó tại file start.c lập trình viên sẽ sử dụng

int page_num = 1;

Khi gặp từ khóa extern trình biên dịch sẽ hiểu là biến đó sẽ được khai báo ở phạm vi toàn cục, không thiết yếu lập giá trị trước (Có nghĩa là tránh việc phải để giành vùng bộ nhớ trống cho biến này) và biến này sẽ được thiết lập giá trị tại những file nguồn .c khi cần.

3. Macro

3.1 Định nghĩa Macro như một hằng

Cú pháp :

#define name_macro body_macro

Trong số đó :

name_macro : là tên gọi macro, body_macro: Nội dung macro hay thân macro.

Một macro là một tên có chứa chuỗi ký tự liên quan. Chuỗi ký tự này được gọi là nội dung hay thân của macro (macro body toàn thân).

Trong C, sử dụng những chữa cái Hoa để đặt tên cho những macro, điều này được sử dụng để phân biệt giữa tên những macro với tên những biến (thông thường tên những biến sử dụng cả vần âm hoa và thường).

Ví dụ

#define PI 3.14159

#define BUFF_LEN 512

Tên macro : PI, BUFF_LEN

Nội dung macro tương ứng với PI là : 3.14159 và tương ứng với BUFF_LEN là 512

Khi lập trình thay vì phải khai báo : char buf [512] thì tất cả chúng ta sử dụng char buf [BUFF_LEN];

Với những lập trình viên còn ít kinh nghiệm tay nghề, khi lập trình tất cả chúng ta thường hay viết như sau :

static char in_buf[256];

main()

...

for (a = 0; a < 256 ; a++)

                    in_buf[al = getchar();

Khi chạy chương trình tất cả chúng ta thấy giá trị 256 không đủ để lưu thông tin, lập tức tất cả chúng ta phải sửa đổi giá trị 256 này. Lúc đó tất cả chúng ta phải sửa ở 2 vị trí chứa số 256. Nếu một chương trình có nhiều chỗ sử dụng giá trị 256 thì lập tức tất cả chúng ta gặp vấn đề. Như vậy thay vì sử dụng giá trị trực tiếp 256 tất cả chúng ta sẽ thay thế nó bằng :

#define MAX_INPUT_BUFFER_SIZE 256

static char in_buf[MAX_INPUT_BUFFER_SIZE];

main()

...

for (a = 0; a < MAX_INPUT_BUFFER_SIZE; a++)

                    in_buf[al = getchar();

3.2. Macro với tham số

Tương tự như hàm, macro hoàn toàn có thể có chứa một hoặc nhiều tham số đầu vào, những tham số này sẽ được sử dụng tại nội dung (macro body toàn thân) hay tại thân của macro:

Hình sau mô tả định nghĩa macro với tham số:

Bộ tiền xử lý c được chỉ định bằng ký hiệu:

Hình số 2 : Macro có tham số

Ví dụ : Macro có một tham số

#define CIRCLE_AREA(x) ((PI) * (x) * (x))

Thay vì viết hàm tính diện tích s quy hoạnh đường tròn với bán kính x; sử dụng macro để thực hiện

Tên macro là : CIRCLE_AREA

Tham số truyền vào : x;

Nội dụng của macro: ((PI) * (x) * (x))

Khi lập trình sử dụng macro CIRCLE_AREA như sau:

float area = CIRCLE_AREA(4);

thì sẽ được dịch ra bởi bộ tiền xử lý là

float area =((PI)*(4)*(4));

Ví dụ : Với macro có 2 tham số

#define RECTANGLE_AREA(x, y) ((x) * (y))

Khi đó trong code

int rectArea = RECTANGLE_AREA(5, 6);

thì sẽ được dịch ra bởi bộ tiền xử lý là :

int rectArea = ((5) * (6));

3.3 Cảnh báo lỗi

3.3.1 Sử dụng dấu ;

Một trong những lỗi xảy ra khi lập trình đó là sử dụng định nghĩa marcro có chứa dấu ; ở cuối dòng định nghĩa marco

Ví dụ

#define SIZE 10;

Khi sử dụng macro SIZE như sau

int i = SIZE;

Thì sẽ được dịch ra bởi bộ tiền xử lý như sau

int i = 10;;

và thời điểm hiện nay sẽ xuất hiện lỗi, với những lập trình viên ít kinh nghiệm tay nghề thì sẽ rất khó tìm ra lỗi này.

Một ví dụ khác :

#define GOOD_CONDITION (var == 1);

Sau đó sử dụng macro GOOD_CONDITION áp dụng với while

while GOOD_CONDITION

          ...

Bộ tiền xử lý sẽ xử lý như sau

while (var == 1);

          ...

Và lúc đó sẽ gây lỗi vì kết quả là nội dung thực thi trong while sẽ không hề là một nội dung của while nữa.

3.3.2. Thứ tự thực hiện những phép toán
Do đặc thù macro nên khi sử dụng macro cần rất lưu ý về thứ tự ưu tiên ví dụ

#define RECTANGLE_AREA(x, y) (x * y)

Có nghĩa ở nội dung macro RECTANGLE_AREA ta thay thế ((x)*(y)) bằng (x * y) khi đó ta sử dụng:

int i = RECTANGLE_AREA(a+2,b); Lúc này bộ tiền xử lý sẽ thực hiện

int i = a+2*b; và thời điểm hiện nay kết quả sẽ khác (a+2) * (b);

3.3.3. Sử dụng dấu = trong định nghĩa macro

Một lỗi thông dụng xảy ra khi định nghĩa Macro đó là sử dụng phép gán để khởi tạo giá trị cho macro.

Ví dụ:

Thay vì phải viết :

#define MAX 100

Thì những lập trình viên sẽ viết

#define MAX = 100

Loại sai lầm này sẽ gây ra những lỗi tối nghĩa. Ví dụ áp dụng gây lỗi

for (j=MAX, j > 0; j-- )...


Khi đó bộ tiền xử lý sẽ thực hiện :

for (j== 100; j > 0, j--) ...

Vậy khi đó biểu thức j=100 sẽ trở thành j==100; lúc đó ngữ nghĩa sẽ khác hoàn toàn và là nguyên nhân gây ra lỗi.

3.4. Các vấn đề cần lưu ý

Không in như hàm, những tham số hình thức truyền vào hàm có kiểu, còn tham số của macro không còn kiểu, điều đó nghĩa là bộ tiền xử lý sẽ không kiểm tra kiểu đối với tham số của marco.

Ngoài ra thì marco không biến thành xung đột khi lập trình viên sử dụng những tham số trùng tên nhau, với hàm C thì không thể sử dụng những tham số hình thức truyền vào của hàm là trùng tên được;

Ví dụ

#define RECTANGLE_AREA(x, y) ((x) * (y))

Khi gọi hoàn toàn có thể sử dụng

int i = RECTANGLE_AREA(a-1);

Lúc đó

i = ((a-1)*(a-1));

Vậy với hàm trong C thì không như vậy được.

3.5. Chỉ thị bộ tiền xử lý #undef

Sử dụng thông tư bộ tiền xử lý #define để định nghĩa macro. Macro này sẽ có hiệu lực hiện hành Tính từ lúc lúc nó được định nghĩa đến khi kết thúc file chứa mã nguồn hoặc file header hoặc khi gặp thông tư bộ tiền xử lý #undef. Sử dụng thông tư bộ tiền xử lý #undef để vô hiệu những định nghĩa của những macro, khi đó muốn sử dụng lại macro thì lập trình viên sẽ phải định nghĩa lại.

Ví dụ:

#define WIDTH 80

#define ADD( X, Y ) ((X) + (Y))

.

.

.

#undef WIDTH

#undef ADD

3.6. Sử dụng tên Macro trong chính nội dung định nghĩa của Macro

Với hầu hết những trình biên dịch cũ của C đều không được cho phép tên Macro trong chính nội dung (body toàn thân) của chính macro.

Ví dụ:

Định nghĩa macro sqrt, trong đó sqrt là tên gọi macro và sqrt cũng nằm trong chính body toàn thân của nó.

#define sqrt (x) ( (x < 0) ? sqrt ('x) : sqrt (x) )

Tuy nhiên Chuẩn ANSI tương hỗ cú pháp này. Nhưng xuất hiện chú ý nếu tên macro có trong nội dung của chính macro thì nó sẽ không được mở rộng (if a macro name appears in its own definition, it will not be expanded). Điều này tránh được vấn đề mở rộng vô hạn hay là đệ quy vô hạn trong định nghĩa macro.

Ở ví dụ trên, khi sử dụng sqrt như sau:

int y = sqrt ( 5 );

Bộ tiền xử lý sẽ thay thế như sau

int y = ( (5 < 0 ? sqrt (- 5) : sqrt (5 ) );

Bộ tiền xử lý sẽ coi sqrt là một hàm với những tham số truyền vào là -5 để tính kết quả của y. Lưu ý sử dụng tên macro trong chính nội dung của macro là rất nhậy cảm, đặc biệt khi tên macro trùng với tên hàm.

3.7. Macro và Hàm

Xét về một khía cạnh nào đó thì Macro và hàm là tương tự như nhau ở chỗ cả hai đều cho sử dụng tên để định danh và đều chứa nội dung được cho phép một tập hợp những xử lý gắn với một trách nhiệm nào đó của bài toán. Do vậy đôi khi khó quyết định xem sử dụng macro hay hàm thì hiệu suất cao hơn.

Các list sau đây tóm tắt những ưu điểm và nhược điểm của macro so với hàm trong C.

Ưu điểm

+ Tốc độ thực thi của Macro nhanh hơn hàm.

+ Số lượng những tham số truyền vào cho macro được kiểm tra để phù phù phù hợp với định nghĩa. Trình biên dịch C cũng thực hiện điều đó với hàm nếu hàm đó được khai báo những nguyên mẫu hàm.

+ Tham số truyền vào cho macro không còn kiểu do vậy khi sử dụng hoàn toàn có thể truyền vào nhiều kiểu tài liệu rất khác nhau.

Nhược điểm

+ Hàm trong C được cho phép gọi những hàm khác và gọi chính nó trong nội dung hàm. Còn macro không được cho phép thực hiện điều này. Chính vì vậy với cùng một trách nhiệm, nếu chương trình sử dụng macro thì mã phát triển chương trình sẽ to hơn so với khi sử dụng hàm.

+ Mặc dù macro có kiểm tra số lượng những tham số truyền vào nhưng không kiểm tra kiểu tài liệu của tham số, điều này dẫn đến khi sử dụng nếu không thận trọng sẽ gây lỗi.

+ Sử dụng macro sẽ khó debug hơn vì macro hoạt động và sinh hoạt giải trí ở gian đoạn tiền xử lý.

3.8. Macro được xây dựng sẵn

Chuẩn ANSI đáp ứng 5 macro được định nghĩa sẵn của cục tiền xử lý. Mỗi tên của macro được xây dựng sẵn sẽ khởi đầu bởi dấu “__”. Lập trình viên không được sử dụng thông tư bộ tiền xử lý #undif để vô hiệu những macro này.

__LINE__: tin tức về số dòng trong mã chương trình khi dòng lệnh đó được gọi, __LINE__ Hữu dụng khi xuất hiện những lỗi thực thi tại dòng lệnh nào đó. Lập trình viên muốn in thông tin về số thứ tự dòng lệnh xuất hiện lỗi này.

__FILE__: Trả về tên file khi file đó được gọi

__TIME__: Trả về thời gian hiện tại tại thời điểm biên dịch chương trình theo mẫu hh::mm::ss trong 24h.

__DATE__: Trả về ngày hiện tại tại thời điểm biên dịch chương trình theo mẫu mmm dd yyyy trong 24h.

__STDC__: Trả về giá trị 1 nếu trình biên dịch C theo chuẩn ANSI C

Ví dụ

Sử dụng macro được xây dựng sẵn để in những thông tin về số thứ tự dòng, tên file, thời gian, ngày tháng và thông tin chuẩn ANSI của trình biên dịch

Code minh họa

Bộ tiền xử lý c được chỉ định bằng ký hiệu:

Hình số 3 : Macro được xây dựng sẵn

Kết quả khi chạy chương trình sẽ in ra những dòng thông tin liên quan tới LINE, TIME, DATE ...

Các lập trình viên thường hay sử dụng những macro được tương hỗ sẵn để định nghĩa những file header nhằm mục đích tương hỗ quá trình DEBUG chương trình.

3.9. Toán tử tiền xử lý ##

Trong ANSI sử dụng toán tử tiền xử lý ## để thực hiện dán 2 token (ghép 2 token) lại

Ví dụ

#define FILENAME ( extension ) test_ ## extension

Khi đó nếu thực hiện

FILENAME( bak )
Thì kết quả trả về là test_bak

Lưu ý : Trong C, những lập trình viên khi sử dụng bộ tiền xử lý thì không thể tự động ghép 2 token (thông tin) lại với nhau một cách thủ công.

Ví dụ

#define FILENAME ( extension ) test_extension

Không hoạt động và sinh hoạt giải trí bởi test_extension được xem là một định danh duy nhất và phần mở rộng (extension) không xuất hiện ở trong định danh.

Một ví dụ khác sử dụng toán tử tiền xử lý ##

#define READ( type) (file_##type == NULL?

open_##type##_file(), read __ ##type() :

read_##type() )

Trong ví dụ trên khi viết những macro dài quá số lượng giới hạn của dòng thì sử dụng để nối với dòng phía dưới. Macro này được sử dụng để đọc những phần tử trực thuộc file. Nếu file không được mở (ví dụ : file_##type == NULL), macro sẽ mở và gọi đến hàm read_##type(), mặt khác sẽ gọi đến hàm read_##type mà không cần mở tệp.

s = READ( player );

sẽ được thay thế bằng

s = ( file_player == NULL ? open __ FILE__player(), read_player () : read_player() );

Sẽ tương đương với

if (file_p1ayer == NULL) {

open __ FILE__player();

s = read_p1ayer;

else

s = read_p1ayer;

4. Dịch có điều kiện

Dịch có điều kiện được cho phép lập trình viên trấn áp được quá trình thực thi những thông tư của cục tiền xử lý và thực hiện dịch mã chương trình. Giống như khi lập trình, C sử dụng cấu trúc if, else ... để trấn áp sự thực thi những đoạn mã tương ứng với những điều kiện logic, bộ tiền xử lý sử dụng những macro #if, #else, #elif, and #endif để thực hiện những vấn đề này.

Hình sau mô tả những thông tư bộ tiền xử lý #if, #else...

Bộ tiền xử lý c được chỉ định bằng ký hiệu:

Hình số 4: Mô tả thông tư dịch có điều kiện

Ví dụ:

#if x == 1

#undef x

#define x 0

#elif x == 2

#under x

#define x 3

#else

#define y 4

#endif

Trong đoạn mã trên, x là một macro. Nếu nội dung của x là một trong thì x sẽ được định nghĩa lại, và giá trị nội dung x sẽ là 0. Nếu giá trị nội dung là 2 thì định nghĩa lại x và giá trị nội dung nó là 3. Trong những trường hợp còn sót lại thì định nghĩa y và giá trị nội dung y là 4.

Việc áp dụng những thông tư tiền xử lý có điều kiện vào nhiều những trường hợp rất khác nhau như tương hỗ xử lý những BUG, Lựa chọn thực thi những hàm gắn với những trình biên dịch rất khác nhau.

Ví dụ : Sử dụng thông tư bộ tiền xử lý có điều kiện để lựa chọn những hàm xử lý :

#if (_STDC_)

          extern int foot char a, float b );

          extern char *goo( char *string );

#else

          extern int foo();

          extern char *qoo();

#endif

Đoạn mã trên sẽ kiểm tra, nếu trình biên dịch theo chuẩn ANSI thì sử dụng 2 hàm

          extern int foot char a, float b );

          extern char *goo( char *string );

Trong trường hợp ngược lại thì sử dụng 2 hàm:

          extern int foo();

          extern char *qoo();

4.1. DEBUG với dịch có điều kiện

Dịch có điều kiện thỉnh thoảng phục vụ mục tiêu xử lý những vấn đề liên quan tới DEBUG của chương trình. Các bộ công cụ lập trình tương hỗ những tính năng rất mạnh mẽ và tự tin để phục vụ cho việc DEBUG, tuy nhiên đôi khi DEBUG không thành công hoặc gặp trở ngại vất vả, khi đó đôi khi lập trình viên sẽ nên phải in ra thông tin của một biến rõ ràng trong một vòng lặp while, for hay do-while ví dụ điển hình.

Sử dụng printf kèm theo những thông tư có điều kiện khi gặp DEBUG và in ra giá trị của một biến.

Ví dụ:

#ifdef DEBUG

  printf("Variable x = %dn", x);

#endif

Tất nhiên là DEBUG sẽ phải được định nghĩa bởi #define trước khi sử dụng thông tư #indef. Khi những lỗi được xử lý xong, thì những bạn hoàn toàn có thể comment lại những #define DEBUG và hàm printf có liên quan. Ngoài cách này ra thì lập trình viên hoàn toàn có thể sử dụng #undef. Tuy nhiên những xử lý này chỉ áp dụng với những chương trình nhỏ. Với những chương trình lớn thì lập trình viên cần tạo ra những file header riêng biệt để xử lý những vấn đề liên quan tới DEBUG.

4.2. Kiểm tra tồn tại của Macro

Chỉ thị dịch có điều kiện #if, #eif... được cho phép kiểm tra gắn với những điều kiện, thường những điều kiện được xác định bởi giá trị của những biểu thức toán học. Lập trình viên cũng hoàn toàn có thể sử dụng những điều kiện dịch đặc biệt để kiểm tra sự tồn tại hay là không tồn tại của một macro thông qua #ifdef, #ifndef, và #endif.

Ví dụ:

#ifdef TEST

printf( "This is a test.n" ):

#else

printf ( "This is not a test. n" );

#endif

Đoạn mã trên nhằm mục đích mục tiêu kiểm tra macro TEST đã được định nghĩa hay chưa.

Nếu TEST đã được định nghĩa thì sẽ in ra dòng thông báo "This is a test.n" ngược lại thì in ra dòng thông báo "This is not a test. n"

Trong số đó #ifdef TEST là tương đương với :

#if defined TEST

Hoặc

#if defined (TEST)

Về bản chất thì :

#if defined macro_name

Sẽ tương đương với

#ifdef macro_name

Và đảo ngược với đã định nghĩa (defined) thì tất cả chúng ta có chưa định nghĩa (!defined)

#if !defined macro_name

Tương đương với

#ifndef macro_name

Ví dụ:

Sử dụng !defined để định nghĩa Macro FALSE có mức giá trị là 0.

#if !FALSE

# define FALSE 0

#endif

Để tránh việc sử dụng !FALSE thì tất cả chúng ta hoàn toàn có thể sử dụng #ifndef khi đó đoạn mã trên sẽ được viết thành:

#ifndef FALSE

# define FALSE 0

#elif FALSE

# undef FALSE

# define FALSE 0

#endif

4.3 Chỉ thị #error
Chỉ thị #error được cho phép đưa ra thông báo lỗi trong quá trình dịch chương trình. Dòng thông báo gắn với thông tư #error sẽ gửi ra thiết bị thông báo lỗi chuẩn. Thông thường nó được sử dụng gắn với những #if... để kiểm tra một điều kiện nào đó.

Ví dụ:

#if INTSIZE < 16

# error INTSIZE too small

#endif

Thực hiện dịch bằng câu lệnh

Nội dung được ghi vào file ví dụ test.c hoặc một file header, sau đó trong test.c sẽ tiến hành #include.

cc -D INTSIZE=8 test.c

Khi đó sẽ nhận được tin báo

INTSIZE too small

5. Điều khiển dòng

Theo chuẩn ANSI, định nghĩa thông tư tiền xử lý #line thiết lập số thứ tự dòng hiện thời của câu lệnh được thực thi hiện tại của tệp mã nguồn và tên tệp mã nguồn.

Bộ tiền xử lý c được chỉ định bằng ký hiệu:

Hình số 5: Cú pháp thông tư #line

Cú pháp

#line number_row

Với number_row là số dòng

Giả sử ta có câu lệnh:

printf( "Current line: %dn", __LlNE_);

Khi đó kết quả in ra là Current line: 5

Điều đó nghĩa là loại lệnh thực thi hiện tại sẽ có thứ tự 5

Sau đó ta tương hỗ update câu lệnh

printf( "Current line: %dn", __LlNE_);

#line 100

printf( "Current line: %dn", __LlNE_);

Khi đó nó sẽ in ra thông tin là:

Current line: 5

Current line: 100

Vì khi gặp câu lệnh #line 100, thì trình biên dịch sẽ chuyển câu lệnh thực thi dòng hiện tại về vị trí là 100. Do vậy câu lệnh sau sẽ in ra là 100 chứ không phải là 7.

Ví dụ code minh họa

Bộ tiền xử lý c được chỉ định bằng ký hiệu:

Hình số 6: Minh họa thông tư #line

6. Chỉ thị #pragma

Chỉ thị tiền xử lý #pragma thực thi những trách nhiệm rõ ràng và để đáp ứng những thông tin tương hỗ update cho trình biên dịch C.

Cú pháp

#prama token_name

Trong số đó : token_name có chứa 6 giá trị như : startup, exit, warn...

Ví dụ:

#include

int display();

#pragma startup display

#pragma exit display

int main()

  printf("nI am in main function");

  return 0;

int display()

  printf("nI am in display function");

  return 0;

Khi gặp #pragma startup display thì trước khi thực hiện hàm main nó sẽ thực hiện hàm display.

Khi gặp #pragma exit display thì trước khi kết thúc chương trình nó sẽ gọi đến hàm display.


Review Bộ tiền xử lý c được chỉ định bằng ký hiệu: ?

Bạn vừa đọc Post Với Một số hướng dẫn một cách rõ ràng hơn về Review Bộ tiền xử lý c được chỉ định bằng ký hiệu: tiên tiến nhất

Chia Sẻ Link Download Bộ tiền xử lý c được chỉ định bằng ký hiệu: miễn phí

Bạn đang tìm một số trong những Chia Sẻ Link Down Bộ tiền xử lý c được chỉ định bằng ký hiệu: Free.

Hỏi đáp thắc mắc về Bộ tiền xử lý c được chỉ định bằng ký hiệu:

Nếu sau khi đọc nội dung bài viết Bộ tiền xử lý c được chỉ định bằng ký hiệu: vẫn chưa hiểu thì hoàn toàn có thể lại phản hồi ở cuối bài để Admin lý giải và hướng dẫn lại nha #Bộ #tiền #xử #lý #được #chỉ #định #bằng #ký #hiệu - 2022-08-08 00:50:06 Bộ tiền xử lý c được chỉ định bằng ký hiệu:

Post a Comment