<199910090451.NAA56681@xxxxxxxxxxxxxx> の、
"[H8-ML(371)] 質問者:秋月Cコ ン広域変数の件" において、
"三上典秀 <robot@xxxxxxxxxxxx>"さんは書きました:
robot> 説明不足ですみません。以下問題のプログラムの一部を記入してみました。
これは変数初期化の問題ではなくて符号拡張の問題ですね。
#要らん事を長々と書いてしまって申し訳ない。
robot> char data; /* 入力データ格納変数 */
robot> char data2; /* 入力データ格納変数2 */
Cの場合、原則として演算はintで行われるので後のような比較をするには
unsigned charでないと駄目です。
余談:Cが最初に作られたPDP11にはバイト長のレジスタ/演算命令が無か
ったという歴史的経緯によります。
robot> switch ( data ){
ここでcharは符号付きなのでdataは符号拡張されます。ここでdata = 0xefなら0xffef。
robot> case ~(0x10): Up(); break; ←ここで~(0x10)を0xefに変えてみると
robot> 動かない
~0x10も符号拡張されるので0xefではなく0xffefです。0xefでは一致しません。
これは何も秋月のCに限らない初歩の初歩です。特に必要でない限りcharではなく
unsigned charを使うことをお勧めします。
余談2:大半のCでchar がsignedなのはPDP11の機械命令には当初、符号無し整数と
いう型が無かったという歴史的経緯によります。最近のCではコンパイラオプショ
ンひとつでcharをunsigned charとして扱えるものも多いのですが、そうなると今
度は符号付きをsigned charと書かないとbugになるので良く理解してない人は避け
た方が無難でしょう。
#組み込み用途でPDP11のCのスタートアップとランタイム書いた事もあったりします。
#今考えるとあれがもっとも短時間でCを理解する役に立ったのかも。
#当時はアセンブラ全盛だったので白眼視されましたけど^-^;
PS.本来は符号付きcharとして使いたいというのであれば
switch((unsigned char) data)
とキャストして使うという手もあります。
//imaizumi aka gigo