在线看毛片网站电影-亚洲国产欧美日韩精品一区二区三区,国产欧美乱夫不卡无乱码,国产精品欧美久久久天天影视,精品一区二区三区视频在线观看,亚洲国产精品人成乱码天天看,日韩久久久一区,91精品国产91免费

<menu id="6qfwx"><li id="6qfwx"></li></menu>
    1. <menu id="6qfwx"><dl id="6qfwx"></dl></menu>

      <label id="6qfwx"><ol id="6qfwx"></ol></label><menu id="6qfwx"></menu><object id="6qfwx"><strike id="6qfwx"><noscript id="6qfwx"></noscript></strike></object>
        1. <center id="6qfwx"><dl id="6qfwx"></dl></center>

            新聞中心

            EEPW首頁 > 嵌入式系統(tǒng) > 設(shè)計(jì)應(yīng)用 > 單片機(jī)C語言中define的妙用

            單片機(jī)C語言中define的妙用

            作者: 時(shí)間:2016-11-29 來源:網(wǎng)絡(luò) 收藏
            單片機(jī)C語言define的妙用

            最近一款產(chǎn)品調(diào)試時(shí)發(fā)現(xiàn)了問題,在一起檢查一個(gè)小伙伴的C程序。問題不大,但暴露了一點(diǎn)問題。
            比如:PORTB=0x23; //他的意思是把第5和第2位置1
            可是你能一下子看出來第5和第2位置1嗎?其實(shí)應(yīng)該是0x24,他并沒有發(fā)現(xiàn)這個(gè)錯(cuò)誤,算錯(cuò)了,所以正確的是:
            PORTB=0x23;
            其實(shí),我們完全可以避免這個(gè)錯(cuò)誤。
            打開我們編譯器自帶的頭文件,比如AVR Tiny13頭文件中有如下語句:
            # define PB5 5
            # define PB4 4
            # define PB3 3
            # define PB2 2
            # define PB1 1
            # define PB0 0

            看似沒什么用,其實(shí)大有用處。
            PORTB=0x24;就可以寫為:
            PORTB=(1<這樣,是不是一下子就能看清誰跟誰了?也方便別人閱讀。

            define的妙用遠(yuǎn)不止此,但基本的用法簡(jiǎn)單,要靈活運(yùn)用,才行。
            下面是摘抄自網(wǎng)上的define用法,希望你能掌握并運(yùn)用。


            #define用法
            1.簡(jiǎn)單的define定義

            #define MAXTIME 1000

            一個(gè)簡(jiǎn)單的MAXTIME就定義好了,它代表1000,如果在程序里面寫

            if(i

            編譯器在處理這個(gè)代碼之前會(huì)對(duì)MAXTIME進(jìn)行處理替換為1000。

            這樣的定義看起來類似于普通的常量定義CONST,但也有著不同,因?yàn)閐efine的定義更像是簡(jiǎn)單的文本替換,而不是作為一個(gè)量來使用,這個(gè)問題在下面反映的尤為突出。

            2.define的“函數(shù)定義”
            define可以像函數(shù)那樣接受一些參數(shù),如下

            #define max(x,y) (x)>(y)?(x):(y);

            這個(gè)定義就將返回兩個(gè)數(shù)中較大的那個(gè),看到了嗎?因?yàn)檫@個(gè)“函數(shù)”沒有類型檢查,就好像一個(gè)函數(shù)模板似的,當(dāng)然,它絕對(duì)沒有模板那么安全就是了??梢宰鳛橐粋€(gè)簡(jiǎn)單的模板來使用而已。

            但是這樣做的話存在隱患,例子如下:
            #define Add(a,b) a+b;
            在一般使用的時(shí)候是沒有問題的,但是如果遇到如:c * Add(a,b) * d的時(shí)候就會(huì)出現(xiàn)問題,代數(shù)式的本意是a+b然后去和c,d相乘,但是因?yàn)槭褂昧薲efine(它只是一個(gè)簡(jiǎn)單的替換),所以式子實(shí)際上變成了
            c*a + b*d

            另外舉一個(gè)例子:
            #define pin (int*);
            pin a,b;
            本意是a和b都是int型指針,但是實(shí)際上變成int* a,b;
            a是int型指針,而b是int型變量。
            這是應(yīng)該使用typedef來代替define,這樣a和b就都是int型指針了。

            所以我們?cè)诙x的時(shí)候,養(yǎng)成一個(gè)良好的習(xí)慣,建議所有的層次都要加括號(hào)。

            3.宏的單行定義

            #define A(x) T_##x
            #define B(x) #@x

            #define C(x) #x
            我們假設(shè):x=1,則有:
            A(1)------〉T_1
            B(1)------〉1
            C(1)------〉"1"

            (這里參考了 hustli的文章)

            4.define的多行定義

            define可以替代多行的代碼,例如MFC中的宏定義(非常的經(jīng)典,雖然讓人看了惡心)

            #define MACRO(arg1, arg2) do { /
            /
            stmt1; /
            stmt2; /
            /
            } while(0)
            關(guān)鍵是要在每一個(gè)換行的時(shí)候加上一個(gè)"/"


            5.在大規(guī)模的開發(fā)過程中,特別是跨平臺(tái)和系統(tǒng)的軟件里,define 最重要的功能是條件編譯。

            就是:
            #ifdef WINDOWS
            ......
            ......
            #endif
            #ifdef LINUX
            ......
            ......
            #endif

            可以在編譯的時(shí)候通過#define設(shè)置編譯環(huán)境

            6.如何定義宏、取消宏

            //定義宏
            #define [MacroName] [MacroValue]
            //取消宏
            #undef [MacroName]
            普通宏
            #define PI (3.1415926)

            帶參數(shù)的宏
            #define max(a,b) ((a)>(b)? (a),(b))
            關(guān)鍵是十分容易產(chǎn)生錯(cuò)誤,包括機(jī)器和人理解上的差異等等。

            7.條件編譯

            #ifdef XXX…(#else)…#endif
            例如 #ifdef DV22_AUX_INPUT
            #define AUX_MODE 3
            #else
            #define AUY_MODE 3
            #endif
            #ifndef XXX …(#else) …#endif

            8.頭文件(.h)可以被頭文件或C文件包含

            重復(fù)包含(重復(fù)定義)
            由于頭文件包含可以嵌套,那么C文件就有可能包含多次同一個(gè)頭文件,就可能出現(xiàn)重復(fù)定義的問題的。
            通過條件編譯開關(guān)來避免重復(fù)包含(重復(fù)定義)
            例如
            #ifndef __headerfileXXX__
            #define __headerfileXXX__

            文件內(nèi)容

            #endif
            9. #define中的#、## && #@

            前些一段時(shí)間在看WinCE的Code時(shí)發(fā)現(xiàn)在宏定義中有用到##,如下所示

            #define GPEBLT_FUNCNAME(basename) (SCODE (GPE::*)(struct GPEBltParms*))&GPE::##basename

            在#define中,標(biāo)準(zhǔn)只定義了#和##兩種操作。#用來把參數(shù)轉(zhuǎn)換成字符串,##則用來連接兩個(gè)前后兩個(gè)參數(shù),把它們變成一個(gè)字符串。

            1#define ToString(a) #a

            2ToString( A b Cd ); //A b Cd

            3ToString( A/n b Cd ); //A

            4 // b Cd

            5ToString( A/ n b Cd ); //A n b Cd

            6

            7

            8#define ConCat(x, y) x ## y

            9ConCat( "ABC", "DEF" );

            10ConCat( 123, 4);

            11ConCat( 123.0, 5);

            12//=================================

            13// Cat( 123.0, 5.5);

            14// Cat( a, b );

            15// Cat( "ABC", d );

            16// Cat( a, 1234 );

            17// Cat( "ABC", 1234 );

            18//===== above cant compile =======

            19

            20

            另外,在網(wǎng)上搜到還有一種用法:#@,把參數(shù)轉(zhuǎn)換成字符



            1#define ToChar(a) #@a

            2ToChar(a); // a

            3ToChar(ab); // b

            4ToChar(abc); // c

            5ToChar(abcd); // d

            6//ToChar(abcde); // too many characters in constant

            7ToChar(1.); // .

            這個(gè)沒在標(biāo)準(zhǔn)上看到。上述測(cè)試是在VS studio環(huán)境下做的。不知道GCC中是否有同樣的用法。



            最后附上#define和typedef的區(qū)別

            1) #define是預(yù)處理指令,在編譯預(yù)處理時(shí)進(jìn)行簡(jiǎn)單的替換,不作正確性檢查,不關(guān)含義是否正確照樣帶入,只有在編譯已被展開的源程序時(shí)才會(huì)發(fā)現(xiàn)可能的錯(cuò)誤并報(bào)錯(cuò)。例如:
            #define PI 3.1415926
            程序中的:area=PI*r*r 會(huì)替換為3.1415926*r*r
            如果你把#define語句中的數(shù)字9寫成字母g 預(yù)處理也照樣帶入。

            2)typedef是在編譯時(shí)處理的。它在自己的作用域內(nèi)給一個(gè)已經(jīng)存在的類型一個(gè)別名,但是You cannot use the typedef specifier inside a functiondefinition。

            3)typedef int * int_ptr;

            #define int_ptr int *
            作用都是用int_ptr代表 int* ,但是二者不同,正如前面所說,#define在預(yù)處理時(shí)進(jìn)行簡(jiǎn)單的替換,而typedef不是簡(jiǎn)單替換,而是采用如同定義變量的方法那樣來聲明一種類型。也就是說;

            //refer to (xzgyb(老達(dá)摩))
            #define int_ptr int *
            int_ptr a, b; //相當(dāng)于int * a, b; 只是簡(jiǎn)單的宏替換

            typedef int* int_ptr;
            int_ptr a, b; //a, b 都為指向int的指針,typedef為int* 引入了一個(gè)新的助記符


            這也說明了為什么下面觀點(diǎn)成立
            //QunKangLi(維護(hù)成本與程序員的創(chuàng)造力的平方成正比)
            typedef int * pint ;
            #define PINT int *

            那么:
            const pint p ;//p不可更改,但p指向的內(nèi)容可更改
            const PINT p ;//p可更改,但是p指向的內(nèi)容不可更改。

            pint是一種指針類型 const pint p 就是把指針給鎖住了p不可更改
            而const PINT p 是constint * p 鎖的是指針p所指的對(duì)象。

            4)還應(yīng)經(jīng)注意到#define 不是語句不要在行末加分號(hào),否則會(huì)連分號(hào)一塊置換。


            關(guān)鍵詞: 單片機(jī)C語言defin

            評(píng)論


            技術(shù)專區(qū)

            關(guān)閉