<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
下面的宏常數定義正確嗎?
編寫程式碼來測試:
#define ERROR -1 #define PATH1 "D:testtest.c" #define PATH2 D:testtest.c #define PATH3 D:test test.c int main() { int err = ERROR; char* p1 = PATH1; char* p2 = PATH2; char* p3 = PATH3; }
先使用gcc -E Test.c -o Test.i 進行預編譯,預編譯沒有報錯,結果如下:
# 1 "Test.c" # 1 "<built-in>" # 1 "<command-line>" # 1 "Test.c" int main() { int err = -1; char* p1 = "D:testtest.c"; char* p2 = D:testtest.c; char* p3 = D:testtest.c; }
直接進行編譯,發現 char* p2 = PATH2; char* p3 = PATH3; 報錯
這說明宏定義是正確的,但是編譯是過不了的,只是
#define PATH2 D:testtest.c
#define PATH3 D:test
不符合語法規範。
強大之處其中之一就是可以求陣列的大小,這是不能編寫函數辦到的。
下面看一段宏表示式的程式碼:
#include <stdio.h> #define _SUM_(a, b) (a) + (b) #define _MIN_(a, b) ((a) < (b) ? (a) : (b)) #define _DIM_(a) sizeof(a)/sizeof(*a) int main() { int a = 1; int b = 2; int c[4] = {0}; int s1 = _SUM_(a, b); int s2 = _SUM_(a, b) * _SUM_(a, b); int m = _MIN_(a++, b); int d = _DIM_(c); printf("s1 = %dn", s1); printf("s2 = %dn", s2); printf("m = %dn", m); printf("d = %dn", d); return 0; }
下面為輸出結果,但是 s2 我們預期的結果應該是 9,m 的值我們預期的結果應該是 1,這是怎麼回事呢?
下面進行預編譯看看程式碼到底是怎麼執行的,輸入 gcc -E Test.c -o Test.i
int main() { int a = 1; int b = 2; int c[4] = {0}; int s1 = (a) + (b); int s2 = (a) + (b) * (a) + (b); int m = ((a++) < (b) ? (a++) : (b)); int d = sizeof(c)/sizeof(*c); printf("s1 = %dn", s1); printf("s2 = %dn", s2); printf("m = %dn", m); printf("d = %dn", d); return 0; }
通過上面宏定義的替換,我們很容易知道為什麼結果跟我們想的不一樣。
所以,下面遞迴定義就是錯誤的:
宏定義的常數或表示式是否有作用域限制?(沒有)
下面看一個宏作用域分析的程式碼:
#include <stdio.h> void def() { #define PI 3.1415926 #define AREA(r) r * r * PI } double area(double r) { return AREA(r); } int main() { double r = area(5); printf("PI = %fn", PI); printf("d = 5; a = %fn", r); return 0; }
下面為輸出結果:
作用域的概念是針對 C 語言中的變數和函數,不針對宏。宏表示式被前處理器處理,編譯器不知道宏表示式的存在。
宏 | 含義 | 範例 |
_FILE_ | 被編譯的檔名 | file1.c |
_LINE_ | 當前行號 | 25 |
_DATE_ | 編譯時的日期 | Jan 31 2021 |
_TIME_ | 編譯時的時間 | 17:01:01 |
_STDC_ | 編譯器是否遵循標準C規範 | 1 |
下面看一個宏使用的綜合範例:
#include <stdio.h> #include <malloc.h> #define MALLOC(type, x) (type*)malloc(sizeof(type)*x) #define FREE(p) (free(p), p=NULL) #define LOG(s) printf("[%s] {%s:%d} %s n", __DATE__, __FILE__, __LINE__, s) #define FOREACH(i, m) for(i=0; i<m; i++) #define BEGIN { #define END } int main() { int x = 0; int* p = MALLOC(int, 5); LOG("Begin to run main code..."); FOREACH(x, 5) BEGIN p[x] = x; END FOREACH(x, 5) BEGIN printf("%dn", p[x]); END FREE(p); LOG("End"); return 0; }
下面為輸出結果:
可以看到宏定義是很強大的,可以列印出日期,檔名,行號,不使用宏定義很難實現。
到此這篇關於C語言深入講解宏的定義與使用方法的文章就介紹到這了,更多相關C語言 宏的定義內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45