網(wǎng)站首頁 編程語言 正文
C語言中#define在多行宏定義出錯的原因
1.第一種錯誤
#include<stdio.h>
#define echange(a,b) {\/*宏定義中允許包含多行命令的情形,此時必須在最右邊加上"\"*/
?int t;\
?t=a;\
?a=b;\
?b=t;\
}
main()
{
?int c, d;
?c = 2;
?d = 3;
?printf("%d %d\n", c, d);
?echange(c,d)
?printf("%d %d\n", c, d);
?return 0;
}
在用#define進行多行宏定義時,注釋要放在"\"之前
2.第二種錯誤
#include<stdio.h>
#define echange(a,b) {/*宏定義中允許包含兩道衣裳命令的情形,此時必須在最右邊加上"\"*/\
?int t;\
?t=a;\
?a=b;\
?b=t;\
}/*在最后一行多加了一個"\"*/\
main()
{
?int c, d;
?c = 2;
?d = 3;
?printf("%d %d\n", c, d);
?echange(c,d)
?printf("%d %d\n", c, d);
?return 0;
}
在用#define進行多行宏定義時,在最后一行加上"\“,我們使用#define進行多行定義時,默認(rèn)最后一個”\“的下一行也屬于宏定義范圍,去掉最后一行的”\"即可
以下是代碼的正確形式
#include<stdio.h>
#define echange(a,b) {/*宏定義中允許包含兩道衣裳命令的情形,此時必須在最右邊加上"\"*/\
?int t;\
?t=a;\
?a=b;\
?b=t;\
}
main()
{
?int c, d;
?c = 2;
?d = 3;
?printf("%d %d\n", c, d);
?echange(c,d)
?printf("%d %d\n", c, d);
?return 0;
}
使用#define宏定義的幾個小技巧
1.調(diào)試開關(guān)
有時候編寫程序時為方便查找錯誤,會在很多地方加上串口打印語句直觀查看程序哪里出錯。
但是,串口的輸出是需要時間的,在項目基本完成時,就需要將這些打印關(guān)閉,但是一行一行的注釋掉費時費力,不現(xiàn)實。
這時可以使用宏來當(dāng)做一個"開關(guān)",直接操作這個宏就可以實現(xiàn)打印的開關(guān),例如:
//#define?? ?DEBUG(...)
#define?? ??? ?DEBUG?? ?printf
另外,還可以使用幾個預(yù)定義的宏進行輔助:
__FILE__?? ??? ??? ?// 文件
__FUNCTION__?? ??? ?// 函數(shù)
__LINE__?? ??? ??? ?// 行號
DEBUG("%s %s %d\n", __FILE__, __FUNCTION__, __LINE__);
2.條件編譯
當(dāng)程序為了適配更多不同的環(huán)境時,還可以使用條件宏來選擇不同的代碼模塊:
#if 1
?? ?printf("Hello!\n");
#else
?? ?printf("Hi!\n");
#endif
3.宏實現(xiàn)函數(shù)
交換兩個數(shù):
#define swap(a,b) ?? ?((a)=(a)+(b);(b)=(a)-(b);(a)=(a)-(b))
比較兩個數(shù)并且返回最小的數(shù):
#define MIN(a,b) ?? ?((a)<(b)?(a):(b))
求數(shù)組元素個數(shù):
#define LENGTH(array)?? ?(sizeof(array) / sizeof(array[0]))
4.跨行宏定義
#define?? ?SWAP(a,b)?? ?do { \
?? ??? ? ? ??? ??? ??? ?int t = 0;\
?? ??? ??? ??? ??? ??? ?t = a; \
?? ??? ??? ??? ??? ??? ?a = b; \
?? ??? ??? ??? ??? ??? ?b = t; \
?? ??? ??? ??? ??? ?} while(0)
細(xì)心的你可能已經(jīng)注意到以上宏末尾都沒有帶分號“;”
5.防止頭文件被重復(fù)包含
#ifndef __TEST_H?
#define __TEST_H?
?? ?// 頭文件內(nèi)容?
#endif
6.帶參宏與帶參函數(shù)的區(qū)別
- 1.宏會在編譯器在對源代碼進行編譯的時候進行簡單替換,不會進行任何邏輯檢測,即簡單代碼復(fù)制而已;
- 2.宏進行定義時不會考慮參數(shù)的類型;
- 3.參數(shù)宏的使用會使具有同一作用的代碼塊在目標(biāo)文件中存在多個副本,即會增長目標(biāo)文件的大小;
- 4.參數(shù)宏的運行速度會比函數(shù)快,因為不需要參數(shù)壓棧/出棧操作;
- 5.參數(shù)宏在定義時要多加小心,多加括號;
- 6.函數(shù)只在目標(biāo)文件中存在一處,比較節(jié)省程序空間;
- 7.函數(shù)的調(diào)用會牽扯到參數(shù)的傳遞,壓棧/出棧操作,速度相對較慢;
- 8.函數(shù)的參數(shù)存在傳值和傳地址(指針)的問題,參數(shù)宏不存在;
7.注意事項
- 1.宏定義不會對引號內(nèi)的參數(shù)進行替換;
- 2.若要替換,可以在參數(shù)前面加上’#’轉(zhuǎn)換成“字符串”,如:
#define dprint(expr) printf(#expr " = %d\n", expr)
使用dprint(x/y)就被替換成:
printf("x/y" " = %g\n", x/y);
即
printf("x/y = %g\n", x/y);
總結(jié)
原文鏈接:https://blog.csdn.net/qq_45158026/article/details/104025617
- 上一篇:沒有了
- 下一篇:沒有了
相關(guān)推薦
- 2022-05-20 Idea搭建一個簡單的SpringBoot項目
- 2023-07-09 SQL Server中的NULL值處理:判斷與解決方案
- 2022-03-14 Action請求后臺出現(xiàn)Response already commited異常解決方法
- 2022-08-22 pyecharts繪制時間輪播圖柱形圖+餅圖+玫瑰圖+折線圖_python
- 2022-11-30 深入了解Golang?interface{}的底層原理實現(xiàn)_Golang
- 2023-02-23 一文詳解C語言char類型中的存儲_C 語言
- 2022-08-01 OpenCV根據(jù)面積篩選連通域?qū)W習(xí)示例_python
- 2022-10-05 C++淺析數(shù)據(jù)在內(nèi)存中如何存儲_C 語言
- 欄目分類
-
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支