真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網站制作重慶分公司

【C語言】高級宏定義-創(chuàng)新互聯(lián)

前言

宏定義分為不帶參數的宏定義和帶參數的宏定義,不帶參數的宏定義就是普通的宏定義,帶參數的宏定義則稍稍復雜。下面將結合一些例子講解這些顯得比較高級的宏定義。

創(chuàng)新互聯(lián)-專業(yè)網站定制、快速模板網站建設、高性價比寶安網站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式寶安網站制作公司更省心,省錢,快速模板網站建設找我們,業(yè)務覆蓋寶安地區(qū)。費用合理售后完善,十載實體公司更值得信賴。文章目錄
  • 前言
  • 一、高級宏定義
    • 1、#define M(y) y*y+3*y
    • 2、#define MAX(X,Y) (((x)>(y))?(x):(y))
    • 3、用帶參數宏定義多個語句
    • 4、宏定義嵌套
    • 5、#define ABC "abc"
    • 6、用#將宏參數轉換為字符串
    • 7、##用于在宏定義中進行連接
    • 8、復雜宏定義1
    • 9、復雜宏定義2
  • 二、答疑
    • 1、宏定義占用內存嗎?
    • 2、宏定義作用域
    • 3、define和typedef的區(qū)別
    • 4、條件編譯中的#define和宏定義中的#define
  • 參考資料


一、高級宏定義 1、#define M(y) yy+3y

這個宏定義中有一個參數,使用時傳入參數即可,

k=M(5);  //宏調用

經過替換,變?yōu)?/p>

k=5*5+3*5
2、#define MAX(X,Y) (((x)>(y))?(x):(y))

機器很笨,為了防止機器理解錯誤,需要將參數以及整個表達式都加上括號。

調用

MAX(5,3)

會被替換為:

(((5)>(3))?(5):(3))
3、用帶參數宏定義多個語句
#define SSSV(s1, s2, s3, v) s1 = length * width; s2 = length * height; s3 = width * height; v = width * length * height;

看完整例子:

#include#define SSSV(s1, s2, s3, v) s1 = length * width; s2 = length * height; s3 = width * height; v = width * length * height;
int main(){int length = 3, width = 4, height = 5, sa, sb, sc, vv;
    SSSV(sa, sb, sc, vv);
    printf("sa=%d, sb=%d, sc=%d, vv=%d\n", sa, sb, sc, vv);
    return 0;
}

sa=12, sb=15, sc=20, vv=60

替換為:

#include#define SSSV(s1, s2, s3, v) s1 = length * width; s2 = length * height; s3 = width * height; v = width * length * height;
int main(){int length = 3, width = 4, height = 5, sa, sb, sc, vv;
    sa = length * width; 
    sb = length * height; 
    sc = width * height; 
    vv = width * length * height;
    printf("sa=%d, sb=%d, sc=%d, vv=%d\n", sa, sb, sc, vv);
    return 0;
}

sa=12, sb=15, sc=20, vv=60
4、宏定義嵌套

下面的宏定義將天,小時,分鐘,秒轉化為ms

#define SECOND 1000UL//ul為無符號長整形,不加默認為int,可存儲數據小
#define MINUTE (SECOND *60)
#define HOUR (MINUTE *60)
#define DAY (HOUR *24)
5、#define ABC “abc”

用宏定義除了定義數字還可以定義字符串

6、用#將宏參數轉換為字符串
#include#define STR(s) #s
int main() {printf("%s\n", STR(c.biancheng.net));
    printf("%s\n", STR("c.biancheng.net"));
    return 0;
}

會被替換為

#include#define STR(s) #s
int main() {printf("%s\n", "c.biancheng.net");
    printf("%s\n", "\"c.biancheng.net\"");
    return 0;
}

c.biancheng.net
"c.biancheng.net"

注意轉義字符"表示"

7、##用于在宏定義中進行連接
#include#define CON1(a, b) a##e##b
#define CON2(a, b) a##b##00
int main() {printf("%f\n", CON1(8.5, 2));
    printf("%d\n", CON2(12, 34));
    return 0;
}

會被替換為

#include#define CON1(a, b) a##e##b
#define CON2(a, b) a##b##00
int main() {printf("%f\n", 8.5e2);
    printf("%d\n", 123400);
    return 0;
}

850.000000
123400
8、復雜宏定義1
#define osTimerStaticDef(name, function, control)  \
const osTimerDef_t os_timer_def_##name = \
{(function), (control) }

該宏定義是用

osTimerStaticDef(name, function, control)

替換

const osTimerDef_t os_timer_def_##name = \
{(function), (control) }

osTimerDef_t 是一個結構體別名,我們可以看一下它的定義

typedef struct os_timer_def  
{os_ptimer                 ptimer;    ///< start address of a timer function
#if( configSUPPORT_STATIC_ALLOCATION == 1 )
  osStaticTimerDef_t        *controlblock;      ///< control block to hold timer's data for static allocation; NULL for dynamic allocation
#endif
} osTimerDef_t;

用osTimerDef_t定義一個結構體變量,變量名中包含參數name,用##與os_timer_def_連接,達到自動修改結構體變量名的目的。

結構體包含兩個成員。

9、復雜宏定義2
#define IS_TICKFREQ(FREQ) (((FREQ) == HAL_TICK_FREQ_10HZ)  ||   ((FREQ) == HAL_TICK_FREQ_100HZ) ||  ((FREQ) == HAL_TICK_FREQ_1KHZ))

先看看HAL_TICK_FREQ_10HZ的定義

typedef enum
{HAL_TICK_FREQ_10HZ         = 100U,
  HAL_TICK_FREQ_100HZ        = 10U,
  HAL_TICK_FREQ_1KHZ         = 1U,
  HAL_TICK_FREQ_DEFAULT      = HAL_TICK_FREQ_1KHZ
} HAL_TickFreqTypeDef;

傳入FREQ,只要FREQ100U或FREQ10U或FREQ==1U,就返回true

二、答疑 1、宏定義占用內存嗎?

宏定義只是一個預處理命令,在程序編譯之前做一個簡單的替換,不會占用內存空間,因此宏定義中的參數不用指定數據類型。

2、宏定義作用域

從定義位置開始到當前文件末尾

3、define和typedef的區(qū)別

宏定義只是簡單的字符串替換,由預處理器來處理;
而 typedef 是在編譯階段由編譯器處理的,它并不是簡單的字符串替換,而是給原有的數據類型起別名,將它作為一種新的數據類型。

這里給個例子體驗一下:

typedef struct node
{int a;
	char b;
}Node;

這里就是用typedef給結構體node取一個別名Node,以后用它定義結構體變量,就可以直接用Node

Node node1;

而不需要使用下面這種方式定義:

struct node node2;

完整代碼如下:

#includetypedef struct node
{int a;
	char b;
}Node;

int main()
{Node node1;	
	node1.a=10;
	node1.b='a' ;
	printf("node1.a=%d,node1.b=%c\r\n",node1.a,node1.b);
	struct node node2;
	node2.a=20;
	node2.b='b' ;
	printf("node2.a=%d,node2.b=%c\r\n",node2.a,node2.b);
	return 0;
}

node1.a=10,node1.b=a
node2.a=20,node2.b=b

可以看到,typedef就是給這個結構體取一個別名,不是簡單替換。

再看一個例子:

#define PIN1 int*
typedef int* PIN2;//注意;不要忘記

下面用PIN1定義兩個變量

PIN1 a,b;

經過預處理器替換后,代碼變?yōu)椋?/p>

int* a,b;

其中a是一個指向整型的指針變量,b是一個整型變量。

同樣,用PIN2定義兩個變量

PIN2 a,b;

a,b均為指向整型的指針變量。


4、條件編譯中的#define和宏定義中的#define

預處理命令包括:宏定義、文件包含、條件編譯

(1) 一般宏定義的格式為 #define 宏名 被替換字符串;

(2) C語言的文件包含,就是以 #Include開頭之后,引用的文件;

(3) 條件編譯可以作為頭文件衛(wèi)士

#ifndef FILE_H // 判斷FILE_H宏是否正在,不存在則條件為真

#define FILE_H // 定義FILE_H宏,注意與普通宏定義的區(qū)別!??!

#endif // FILE_H   // #ifndef的結尾

這種固定寫法,一般在頭文件中使用,它能防止頭文件被重復包含。
參考資料

1、http://c.biancheng.net/view/1982.html
2、https://blog.csdn.net/m0_37689444/article/details/88852630

你是否還在尋找穩(wěn)定的海外服務器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調度確保服務器高可用性,企業(yè)級服務器適合批量采購,新人活動首月15元起,快前往官網查看詳情吧


網站欄目:【C語言】高級宏定義-創(chuàng)新互聯(lián)
標題網址:http://weahome.cn/article/pscjp.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部