トップ 最新 追記
2003|01|02|03|04|05|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|10|12|
2009|02|03|06|07|10|11|12|
2010|01|02|03|04|07|09|10|11|12|
2011|01|03|04|05|06|07|08|10|
2012|01|06|08|09|10|12|
2013|01|02|03|04|07|09|11|12|
2014|01|03|04|05|06|09|
2015|04|
2016|01|08|
ここは旧えびめもです。えびめも2に移行します(2016/12/1)

2010年09月12日

C言語クイズ解説

いずれのパターンも gcc-4 (debian lenny等) で実験すると答えが unmatch, match, unmatch となることが確かめられます。

解説です。このクイズは char c のとりうる値が -128〜127 の範囲であることの確認です。

一問目

    int x;
    char c;
    x = 0xFF;
    c = 0xFF;
x=255 ですが、c は char型のため 255は代入できません。強引に 255 を代入すると c = -1 になります。従いまして (255 != -1) で unmatch す。

二問目

    int x;
    char c;
    x = c = 0xFF;   /* ここだけ変えた */
このように1行に記述すると右から左へと順に評価されますので
    c = 0xFF;
    x = c;
となります。さっきと同じで c = -1 です。従いまして x = -1 です。(-1 == -1) で match です。

三問目

  c = x =  0xFF;      /* ここだけ変えた */
これは
  x = 0xFF;
  c = x;
ですから、 X=255, C=-1 になります。 (255 != -1) で unmatch です。

char c は -128〜+127 までしか値をとりません。次のコードなどif文節で C==0xFFには 「絶対にならない」のでコンパイル時にif文は不成立だとコンパイラが判断し、if文は消滅してしまいます。

#include 
#include 
 
int main(void){
        char c;
        c = 0xFF;
 
        if(c==0xFF){
                printf("match\n");
        }else{
                printf("unmatch\n");
        }
        return 0;
}
$ sh4-linux-gnu-gcc -O2 test.c -c
の結果
00000000 
: 0: e6 2f mov.l r14,@-r15 2: 05 d0 mov.l 18 ,r0 ! 0
4: 22 4f sts.l pr,@-r15 6: 05 d4 mov.l 1c ,r4 ! 0
8: 0b 40 jsr @r0 a: f3 6e mov r15,r14 c: 00 e0 mov #0,r0 e: e3 6f mov r14,r15 10: 26 4f lds.l @r15+,pr 12: 0b 00 rts 14: f6 6e mov.l @r15+,r14 16: 09 00 nop ... 18: R_SH_DIR32 puts 1c: R_SH_DIR32 .rodata.str1.4
ほら、ifなんてありませんし、puts() を呼ぶだけのコードになってしまいました。

char str[] 配列を検査して 255 だったら 0 に置き換える。なんていうコードは gcc-4 では動作しませんので注意が必要です。if文節で (int) にキャストするなどしなければなりません。