當我宣告char變數、並把它當作整數來使用的話,我預期它的大小會是1位元組,而合法範圍是-128到127、或是0到255,因為char可能是signed或unsigned,由C語言實作決定。
但卻發現違反上述說法的例子。
程式碼如下:
char x_global = 0;
void setup(){
Serial.begin(115200);
}
void loop(){
char x_local = 0;
while(1){
Serial.print(int(x_global));
Serial.print(" ");
Serial.print(int(x_local));
Serial.println("");
x_global++;
x_local++;
delay(100);
}
}
全域變數x_global、區域變數x_local,不斷地加1並印出。
x_global的值符合預期,從0、1、2、3...到127,然後會到-128,接著是-127、-126、-125...到-1,然後又回到0。
但x_local不如預期,從0、1、2、3...到127,然後到128、129、130、一直變大、可超過幾百、幾千。
Arduino 1.0.6會有上述奇怪的行為。不過在Arduino 1.6.7就不會有。
若改成signed char,行為同上。
若改成unsigned char,那麼兩個變數都會從0、1、2、3...到255,然後回到0、1、2...。
2015/12/26
Arduino小冷門知識:char不一定是-128到127
Subscribe to:
Post Comments (Atom)
你好!
ReplyDelete最近再用ARDUINO碰到一個問題想請問大師,
我想設兩個人體紅外線感測,設定一個"人數"函數,一邊碰到人數加1,一邊人數減1,
但設定紅外線感測人時,函數+1,他會持續增加,我只想加一次,不知怎解決。
我有想過用當紅外線偵測1時在跳回0時那一剎那在+1但不知道怎寫,請問該如何是好?
紅外線PIR感測器,應有兩個旋鈕,請參閱相關文件,了解各自能夠調整什麼,這會影響程式寫法。
Delete使用時,人潮多寡與流動速率,也會影響判斷。
至於程式的部份,寫法很多種,譬如可以設時距,當紅外線偵測到1,就加1,然後暫停一小時間,此時間內不動作。那段時間通常可以取人走過通過的最短時間。
感覺很難做得精準正確,我沒完整的實際經驗,無法幫你。
宣告 char 而到底是 unsigned char 或是 signed char 是 compiler 實作來決定的, 如果你需要 signed char, 需要明確寫出 signed char x_global, int 則不會有這個問題, 只有 char 有這樣的需要。
ReplyDeletehttp://descent-incoming.blogspot.tw/2013/02/c-char-signed-unsigned.html
謝謝,很久以前應該記得這件事,後來就忘了。
Delete不過即便如此,仍無法說明這篇的疑惑。
因為x_local不僅會超過128,還會繼續增加,超過幾百、幾千。
我猜1.0.6版的C編譯器,大概讓x_local佔一個int,但是卻沒有檢查溢位的情況。
x_local有看過會再多少的時候不再加上去嗎?
ReplyDelete應該是個bug .. 但好奇他是被設成什麼了
我猜是32767吧。
Delete依照 C standard 來說, signed 變數 overflow 是 undefined behavior, 所以出什麼都不意外這樣..
ReplyDelete不過不知道 arduino 用的 C 自己是怎麼規定的...