C語言宏定義、條件編譯


筆記整理:

C語言帶參數宏定義

 

宏定義

宏定義的一般形式為:
#define 宏名 字符串或者表達式
預處理的工作就是替換,就是將宏名替換成相應的字符串與表達式。

宏定義字符串:

#define 宏名 字符串

該示例中的語句int sum = 20 + N;,N被100代替了

#include <stdio.h>
#define N 100
int main(){
    int sum = 20 + N;
    printf("%d\n", sum);
    return 0;
}

宏定義表達式:

#define  宏名  (表達式)
#include <stdio.h>
#define M (n*n+3*n)
int main(){
    int sum, n;
    printf("Input a number: ");
    scanf("%d", &n);
    sum = 3*M+4*M+5*M;
    printf("sum=%d\n", sum);
    return 0;
}

注意:宏定義中表達式必須用括號

對宏定義的幾點說明

1) 宏定義是用宏名來表示一個字符串,在宏展開時又以該字符串取代宏名,這只是一種簡單粗暴的替換。字符串中可以含任何字符,它可以是常數、表達式、if 語句、函數等,預處理程序對它不作任何檢查,如有錯誤,只能在編譯已被宏展開后的源程序時發現。

2) 宏定義不是說明或語句,在行末不必加分號,如加上分號則連分號也一起替換。

3) 宏定義必須寫在函數之外,其作用域為宏定義命令起到源程序結束。如要終止其作用域可使用#undef命令。例如:
表示 PI 只在 main() 函數中有效,在 func() 中無效。

#define PI 3.14159
int main(){
    // Code
    return 0;
}
#undef PI
void func(){
    // Code
}

4)代碼中的宏名如果被引號包圍,那么預處理程序不對其作宏代替。

5)宏定義允許嵌套,在宏定義的字符串中可以使用已經定義的宏名,在宏展開時由預處理程序層層代換。例如:

#define PI 3.1415926
#define S PI*y*y    /* PI是已定義的宏名*/
對語句:
printf("%f", S);
在宏代換后變為:
printf("%f", 3.1415926*y*y);

6) 習慣上宏名用大寫字母表示,以便於與變量區別。但也允許用小寫字母。

7) 可用宏定義表示數據類型,使書寫方便。例如:

#define UINT unsigned int

在程序中可用 UINT 作變量說明:

UINT a, b;

應注意用宏定義表示數據類型和用 typedef 定義數據說明符的區別。宏定義只是簡單的字符串替換,由預處理器來處理;而 typedef 是在編譯階段由編譯器處理的,它並不是簡單的字符串替換,而給原有的數據類型起一個新的名字,將它作為一種新的數據類型。


帶有參數的宏定義


C語言允許宏帶有參數。在宏定義中的參數稱為“形式參數”,在宏調用中的參數稱為“實際參數”,這點和函數有些類似。

對帶參數的宏,在展開過程中不僅要進行字符串替換,還要用實參去替換形參。

帶參宏定義的一般形式為:
#define 宏名(形參列表) 字符串或者表達式

在字符串中可以含有各個形參,形參列表中參數以逗號分隔。

帶參宏調用的一般形式為:
宏名(實參列表);
例如:

#define M(y) y*y+3*y //宏定義
// Code
k=M(5); //宏調用

 

注意:

#include <stdio.h>
#define SQ(y) (y)*(y)
int main(){
    int a, sq;
    printf("input a number: ");
    scanf("%d", &a);
    sq = SQ(a+1);
    printf("sq=%d\n", sq);
    return 0;
}
sq=(a+1)*(a+1);

結果:

input a number: 9
sq=100

#include <stdio.h>
#define SQ(y) y*y
int main(){
    int a, sq;
    printf("input a number: ");
    scanf("%d", &a);
    sq = SQ(a+1);
    printf("sq=%d\n", sq);
    return 0;
}
sq=a+1*a+1;

結果:

input a number: 9
sq=19

 

條件編譯

⑴        #if…#else…格式

 

#if 判斷條件
           代碼段1
#else
           代碼段2
#endif
或者

#if 判斷條件1
           代碼段1
#elif 判斷條件2
           代碼段2
#else
           代碼段3
#endif

功能:和if…else…表達式是一樣的。適用的場景是存在真假的判斷條件,此條件一般情況下是一個表達式。


⑵        #ifdef…#else…或者#ifndef…#else…格式

#ifdef 標識符
           代碼段1
#else
           代碼段2
#endif

或者

#ifndef 標識符
           代碼段1
#else
           代碼段2
#endif

功能:判斷條件主要是查看標識符是否被定義(#define定義)。

在現實的工程項目中會使用大量的條件編譯。比如說通過條件編譯來使用各個不同的硬件平台;通過條件編譯來實現平台和產品線管理;通過條件編譯來區分正式版本和調試版本等等。

 

部分預處理指令

指令 說明
# 空指令,無任何效果
#include 包含一個源代碼文件
#define 定義宏
#undef 取消已定義的宏
#if 如果給定條件為真,則編譯下面代碼
#ifdef 如果宏已經定義,則編譯下面代碼
#ifndef 如果宏沒有定義,則編譯下面代碼
#elif 如果前面的#if給定條件不為真,當前條件為真,則編譯下面代碼
#endif 結束一個#if……#else條件編譯塊

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM