標(biāo)題: Char型變量與Bit型變量,如何進(jìn)行”或運(yùn)算”。 [打印本頁]
作者: ≯叁界∝爵ャ 時(shí)間: 2018-12-2 00:03
標(biāo)題: Char型變量與Bit型變量,如何進(jìn)行”或運(yùn)算”。
大神們,本人C語音小白。學(xué)習(xí)金沙工作時(shí)宋雪松老師《手把教你學(xué) 51 單片機(jī) -C語音版》遇到不同變量直接的運(yùn)算問題。
小人看C語言描述 :運(yùn)算時(shí) 都是短字節(jié)向長字節(jié)轉(zhuǎn)換。如char型變量 & int型變量,進(jìn)行運(yùn)算時(shí),是編譯器強(qiáng)制將char 轉(zhuǎn)換成int型。
但宋雪松老師講的如下:連續(xù)將key4值通過T0中斷,一位一位用“或運(yùn)算“寫入char 型變量keybuf中。這與其他地方對(duì)不同變量的運(yùn)算描述不符,請(qǐng)大神們賜教。小弟拜謝。
void InterruptTimer0() interrupt 1
{ static unsigned char keybuf = 0xFF; //按鍵掃描緩沖區(qū),保存一段時(shí)間內(nèi)的掃描值
TH0 = 0xF8; TL0 = 0xCD;
keybuf = (keybuf << 1) | KEY4; //只取KEY4為例,緩沖區(qū)左移一位,并將當(dāng)前掃描值移入最低位
if (keybuf == 0x00)
{ //當(dāng)連續(xù)8次掃描值都為0,即16ms內(nèi)都只檢測(cè)到按下狀態(tài)時(shí),可認(rèn)為按鍵已按下
KeySta = 0; //按鍵狀態(tài)值為按下
}
else if (keybuf == 0xFF)
{ //當(dāng)連續(xù)8次掃描值都為1,即16ms內(nèi)都只檢測(cè)到彈起狀態(tài)時(shí),可認(rèn)為按鍵已彈起
KeySta = 1; //按鍵狀態(tài)值為彈起
}
作者: 聆煙雨 時(shí)間: 2018-12-2 02:38
char 變量與 bit 變量 或運(yùn)算,也是把 bit 轉(zhuǎn)換成 char
看程序發(fā)現(xiàn),這是個(gè)定時(shí)器中斷,中斷間隔為 2ms
KEY4 是個(gè) bit,按下為0,彈起為1
keybuf 是個(gè)局部靜態(tài)變量,其值在函數(shù)退出后仍能保存。
程序執(zhí)行流程:
1,當(dāng)key被按下后,進(jìn)入中斷,keybuf 當(dāng)前值為 0xFF
2,由于機(jī)械按鍵存在抖動(dòng),所以要去抖,程序中采用了檢測(cè)8次的方法來去抖
3,keybuf = (keybuf << 1) | KEY4;
假定這次讀出的 KEY4 為0, keybuf 左移一位變成 b1111 1110 然后與 KEY4 或運(yùn)算
注意此處進(jìn)行了轉(zhuǎn)換,將 KEY4 的 bit 類型值轉(zhuǎn)換成 char, 二進(jìn)制 b0000 0000
運(yùn)算結(jié)束后, keybuf 結(jié)果為 0xFE ,用二進(jìn)制表示為 1111 1110
2ms 后,第二次進(jìn)中斷,如果 KEY4 還是 0 ,那么 keybuf 的值為 b1111 1100
4,如果進(jìn)入中斷 8 次,讀出的 KEY4 都為 0, 那么 keybuf 的值就變成 0x00
5,由于抖動(dòng)期間, KEY4 的值會(huì)變化 01,所以如果存在抖動(dòng),keybuf 的值就不是 b0000 0000
有可能是 b1100 0001 這樣的
作者: jll586 時(shí)間: 2018-12-2 16:16
10.1 數(shù)字秒表實(shí)驗(yàn)10.1.1 不同數(shù)據(jù)間的類型轉(zhuǎn)換
在C語言中,不同數(shù)據(jù)類型之間是可以混合運(yùn)算的。當(dāng)表達(dá)式中的數(shù)據(jù)類型不一致時(shí),首先轉(zhuǎn)換為同一種類型,然后再進(jìn)行計(jì)算。C語言有兩種方法實(shí)現(xiàn)類型轉(zhuǎn)換,一是自動(dòng)類型轉(zhuǎn)換,另外一種是強(qiáng)制類型轉(zhuǎn)換。這塊內(nèi)容是比較繁雜的,因此我們根據(jù)我們常用的編程應(yīng)用來講部分相關(guān)內(nèi)容。
當(dāng)不同數(shù)據(jù)類型之間混合運(yùn)算的時(shí)候,不同類型的數(shù)據(jù)首先會(huì)轉(zhuǎn)換為同一類型,轉(zhuǎn)換的主要原則是:短字節(jié)的數(shù)據(jù)向長字節(jié)數(shù)據(jù)轉(zhuǎn)換。
比如:unsigned char a ; unsigned int b; unsigned int c; c = a *b;
在運(yùn)算的過程中,程序會(huì)自動(dòng)全部按照unsigned int型來計(jì)算。比如a=10,b=200,c的結(jié)果就是2000。那當(dāng)a=100,b=700,那c是70000嗎?新手最容易犯這種錯(cuò)誤,大家要注意每個(gè)變量的數(shù)據(jù)類型,c的數(shù)據(jù)類型是unsigned int型,取值范圍是0~65535,70000超過65535溢出了,所以最終c的結(jié)果是(70000 - 65536) = 4464。
那要想讓c正常獲得70000這個(gè)結(jié)果,需要把c定義成一個(gè)unsigned long型。我們?nèi)绻麑懗桑簎nsigned char a=100; unsigned int b=700; unsigned long c=0; c = a *b;如果有做過實(shí)驗(yàn)的同學(xué),會(huì)發(fā)現(xiàn)這個(gè)c的結(jié)果還是4464,這個(gè)是個(gè)什么情況呢?
大家注意,C語言不同類型運(yùn)算的時(shí)候數(shù)值會(huì)轉(zhuǎn)換同一類型運(yùn)算,但是每一步運(yùn)算都會(huì)進(jìn)行識(shí)別判斷,不會(huì)進(jìn)行一個(gè)總的分析判斷。比如我們這個(gè)程序,a和b相乘的時(shí)候,是按照unsigned int類型運(yùn)算的,運(yùn)算的結(jié)果也是unsigned int類型的4464,只是最終把unsigned int類型4464賦值給了一個(gè)unsigned long型的變量而已。我們?cè)谶\(yùn)算的時(shí)候如何避免這類問題的產(chǎn)生呢?可以采用強(qiáng)制類型轉(zhuǎn)換的方法。
在一個(gè)變量前邊加上一個(gè)變量類型,并且這個(gè)變量類型用小括號(hào)括起來,表示把這個(gè)變量強(qiáng)制轉(zhuǎn)換成括號(hào)里的變量類型。如 c = (unsigned long)a * b;由于強(qiáng)制類型轉(zhuǎn)換運(yùn)算優(yōu)先級(jí)高于*,所以這個(gè)地方的運(yùn)算是先把a(bǔ)轉(zhuǎn)換成一個(gè)unsigned long型的變量,而后與b相乘,根據(jù)C語言的規(guī)則b會(huì)自動(dòng)轉(zhuǎn)換成一個(gè)unsigned long型的變量,而后運(yùn)算完畢結(jié)果也是一個(gè)unsigned long型的,最終賦值給了c。
當(dāng)不同類型變量相互賦值時(shí),短字節(jié)的數(shù)據(jù)向長字節(jié)的變量賦值時(shí),值不變,比如unsigned char a=100; unsigned int b=700; b = a;那么最終b的值就是100了。但是如果我們的程序是unsigned char a=100; unsigned int b=700; a=b;那么a的值僅僅是取了b的低8位,我們首先要把700變成一個(gè)16位的二進(jìn)制數(shù)據(jù),然后取它的低8位出來,也就是188,這就是長字節(jié)給短字節(jié)賦值的結(jié)果。
在51單片機(jī)里邊,有一種特殊情況,就是bit類型的變量,這個(gè)bit類型的強(qiáng)制類型轉(zhuǎn)換,是不符合上邊講的這個(gè)原則的,比如bit a = 0; unsigned char b; a = (bit)b;這個(gè)地方要特別注意,使用bit做強(qiáng)制類型轉(zhuǎn)換,不是取b的最低位,而是他會(huì)判斷b這個(gè)變量是0還是非0的值,如果b是0,那么a的結(jié)果就是0,如果b是任意非0的其他數(shù)字,那么a的結(jié)果都是1。
這是咱們站里的學(xué)習(xí)資料或許對(duì)你有幫助
歡迎光臨 (http://www.torrancerestoration.com/bbs/) |
Powered by Discuz! X3.1 |