MW211 EXIT

devlog
C言語/ビット演算子と論理演算子
2013年01月11日
ビット演算子と論理演算子の組み合わせ対比表って以下みたいなのでいいのかな?
┌─────────┬─────────┬─────────┐
│                  │   ビット演算子   │    論理演算子    │
├─────────┼─────────┼─────────┤
│論理積            │  ○ & ○   → ○ │ (偽 && 偽) → 偽 │
│                  │  ○ & ●   → ○ │ (偽 && 真) → 偽 │
│                  │  ● & ○   → ○ │ (真 && 偽) → 偽 │
│                  │  ● & ●   → ● │ (真 && 真) → 真 │
├─────────┼─────────┼─────────┤
│論理和            │  ○ | ○   → ○ │ (偽 || 偽) → 偽 │
│                  │  ○ | ●   → ● │ (偽 || 真) → 真 │
│                  │  ● | ○   → ● │ (真 || 偽) → 真 │
│                  │  ● | ●   → ● │ (真 || 真) → 真 │
├─────────┼─────────┼─────────┤
│排他的論理和      │  ○ ^ ○   → ○ │ (偽 != 偽) → 偽 │
│                  │  ○ ^ ●   → ● │ (偽 != 真) → 真 │
│                  │  ● ^ ○   → ● │ (真 != 偽) → 真 │
│                  │  ● ^ ●   → ○ │ (真 != 真) → 偽 │
├─────────┼─────────┼─────────┤
│論理積の否定      │~(○ & ○)  → ● │!(偽 && 偽) → 真 │
│                  │~(○ & ●)  → ● │!(偽 && 真) → 真 │
│                  │~(● & ○)  → ● │!(真 && 偽) → 真 │
│                  │~(● & ●)  → ○ │!(真 && 真) → 偽 │
├─────────┼─────────┼─────────┤
│論理和の否定      │~(○ | ○)  → ● │!(偽 || 偽) → 真 │
│                  │~(○ | ●)  → ○ │!(偽 || 真) → 偽 │
│                  │~(● | ○)  → ○ │!(真 || 偽) → 偽 │
│                  │~(● | ●)  → ○ │!(真 || 真) → 偽 │
├─────────┼─────────┼─────────┤
│排他的論理和の否定│~(○ ^ ○)  → ● │ (偽 == 偽) → 真 │
│                  │~(○ ^ ●)  → ○ │ (偽 == 真) → 偽 │
│                  │~(● ^ ○)  → ○ │ (真 == 偽) → 偽 │
│                  │~(● ^ ●)  → ● │ (真 == 真) → 真 │
└─────────┴─────────┴─────────┘
分類:C/C++
C言語/全角判定
2013年01月10日
Shift_JISの場合、1バイト目(上位バイト)が
「0x81~0x9F、0xE0~0xFC」であれば全角文字とみてよい。
分類:C/C++
C言語/文字チェック
2013年01月09日
PHPとかJavaScriptとかの今風の言語だと、正規表現で一発で判定できたりするのだが、
C言語だと地道に一文字ずつチェックしていくしか他ない。

一文字チェック関数をまとめた。
┌─────┬────────────────────────────────┐
│isalnum() │英数字(0~9[0x30~0x39]、A~Z[0x41~0x5A]、a~z[0x61~0x7A])    │
├─────┼────────────────────────────────┤
│isalpha() │英字(A~Z[0x41~0x5A]、a~z[0x61~0x7A])                        │
├─────┼────────────────────────────────┤
│isdigit() │数字(0~9[0x30~0x39])                                          │
├─────┼────────────────────────────────┤
│islower() │英小文字(a~z[0x61~0x7A])                                      │
├─────┼────────────────────────────────┤
│isupper() │英大文字(A~Z[0x41~0x5A])                                      │
├─────┼────────────────────────────────┤
│isxdigit()│16進(0~9[0x30~0x39]、A~F[0x41~0x46]、a~f[0x61~0x66])      │
└─────┴────────────────────────────────┘
┌─────┬────────────────────────────────┐
│isascii() │ASCII文字(0x00~0x7F)                                           │
├─────┼────────────────────────────────┤
│iscntrl() │制御文字(0x00~0x1F、0x7F)                                      │
├─────┼────────────────────────────────┤
│isgraph() │表示可能文字(0x21~0x7E)                                        │
├─────┼────────────────────────────────┤
│isprint() │印字可能文字(0x20~0x7E)                                        │
├─────┼────────────────────────────────┤
│ispunct() │区切文字(0x00~0x1F、0x20、0x7F)                                │
├─────┼────────────────────────────────┤
│isspace() │空白文字                                                        │
│          │→0x09(\t)、0x0A(\n)、0x0B(\v)、0x0C(\f)、0x0D(\r)、0x20( )     │
└─────┴────────────────────────────────┘
判定が真の時に0以外を返却し、偽の時は0を返却するというややこしい仕様だが、
これは速度向上のためらしい。

とにかく、該当しなかったら0ということでエラーにしていきゃいいと覚えるか。
といっても複合条件とか絡んでくると0以外で判定する場面は多々ありそう。
分類:C/C++
C/敵の敵も敵
2012年11月15日
「char」型と「signed char」型は違う…らしい。

「char」型 vs 「signed char」型 vs 「signed char」型

で、

「char」型=「signed char」型

かと、思ったんだけどね。


「int」型はいいっぽい。

「int」型=「signed int」型≠「unsigned int」型
分類:C/C++
C/Cにおけるbool型
2012年11月14日
C言語にはbool型ってものが元々なくて、途中から追加された。

だけど、bool型ってのはそれまでに独自でそれぞれ使われていたので
「_Bool」型という控えめな名前で定義した。

これを「bool」型として使用できるように、インクルードファイル「stdbool.h」で
小細工をしている。

で、本体の「_Bool」型とは何かというと?符号無し整数型で
「0」と「1」を格納できればいいってだけで、後は機種依存らしい。

処理速度が速い「int」型を採用している場合もあれば、
サイズが小さい「char」型だったりする場合もある
(さすがにビットは扱いづらすぎてないようだが)。

だから「sizeof(bool)」は「1」だったり「4」だったりする。

それと後から追加されたものだから厳密ではないらしく
他の型と演算できてしまったりするらしい。

ただし、利点としては「0」か「1」しか値をとらないように
最低限保証はしてくれる模様。

ま、ソースコードが読みやすいってもの大きいかも。
分類:C/C++
言語/続続・アライメントサイズの確認
2012年11月13日
┌──────────────────────────────────────┐
│typedef struct {                                                            │
│    int   a1;                                                               │
│    char  a2;                                                               │
│} A;                                                                        │
│sizeof(A)  →  8(4 + 1 + 3)                                                 │
└──────────────────────────────────────┘
構造体はアライメントサイズまで末尾を埋めてくれる、上記のように。

と思っていたのだが、char型だけだとそうはいかなかった。
┌──────────────────────────────────────┐
│typedef struct {                                                            │
│    char  a1[3];                                                            │
│} A;                                                                        │
│sizeof(A)  →  3                                                            │
└──────────────────────────────────────┘
ちなみに、複数配列にしてみても状況は変わらない。
┌──────────────────────────────────────┐
│A z[2];                                                                     │
│sizeof(z)  →  6                                                            │
└──────────────────────────────────────┘

じゃ、メンバを分けてみたら…同じだ。
┌──────────────────────────────────────┐
│typedef struct {                                                            │
│    char  a1;                                                               │
│    char  a2[2];                                                            │
│} A;                                                                        │
│sizeof(A)  →  3                                                            │
└──────────────────────────────────────┘

じゃ、じゃ、int型以外にしてみたら…同じだ。
┌──────────────────────────────────────┐
│typedef struct {                                                            │
│    bool  a1;                                                               │
│    char  a2[2];                                                            │
│} A;                                                                        │
│sizeof(A)  →  3                                                            │
└──────────────────────────────────────┘

shortとかにしてみたら?
┌──────────────────────────────────────┐
│typedef struct {                                                            │
│    short a1;                                                               │
│    char  a2[3];                                                            │
│} A;                                                                        │
│sizeof(A)  →  6                                                            │
└──────────────────────────────────────┘
┌──────────────────────────────────────┐
│typedef struct {                                                            │
│    short a1;                                                               │
│    char  a2;                                                               │
│} A;                                                                        │
│sizeof(A)  →  4                                                            │
└──────────────────────────────────────┘

あ、わかった一番大きなものに追従するの?
┌──────────────────────────────────────┐
│typedef struct {                                                            │
│    longlong  a1;                                                           │
│    char      a2;                                                           │
│} A;                                                                        │
│sizeof(A)  →  8                                                            │
└──────────────────────────────────────┘
あ、でも最大でも4バイト(アライメントサイズ)までなのね。
分類:C/C++
C/フォーマット指定子(数字付)・番外編
2012年11月10日
さて、これまでのまとめを踏まえて以下はいったいなんなのか?
┌──────────────────────────────────────┐
│%0d                                                                         │
└──────────────────────────────────────┘
「整数部の最小桁数が0」と認識されるのか?
「ゼロパディングだけどその桁数は0」と認識されるのか?
はたまたどちらでもないのか?

実際に実験してみたところ「%d」と変わらなかった。

空文字になるかと思ったがそんなことはなかった。
「%2d」に「123」を入れても「123」になるのと同じだしね。

「0」の場合「0」になるのだから、ゼロパディングが効いているのか?と思ったが
「%d」でも「0」の場合は「0」だった。
だいたいゼロパディングの桁数が0なんだから、「0」とか関係ないし。。。

っていうか「%01d」でも同じじゃないか。

ということで
┌──────────────────────────────────────┐
│「%d」=「%0d」=「「%01d」                                                 │
└──────────────────────────────────────┘
と見てよろしいのでしょうか?
分類:C/C++
C/フォーマット指定子(数字付)
2012年11月09日
だいたい、以下をおさえればよい。後はこれの組み合わせ。
┌──────────────────────────────────────┐
│%2d                                                                         │
└──────────────────────────────────────┘
整数部の数字は整数部の表示領域の桁数を表す。
上記の場合だと、「12」「 1」となる。
ちなみに三桁だとこれを無視して「123」となる(切り捨てられた方が怖いか)。

┌──────────────────────────────────────┐
│%-2d                                                                        │
└──────────────────────────────────────┘
あまり使わないかもしれないが、上記における「 1」を「1 」、
つまり左詰めにしたい場合は「-」を付ける。
ちなみに負の符号(マイナス)は特に指定しなくても勝手に表示されるから
「-」という記号はこの用途に使えているようだ。

┌──────────────────────────────────────┐
│%+d                                                                         │
└──────────────────────────────────────┘
逆に正の符号(プラス)は普段は表示されないものなので、敢えて表示したい場合には
指定が必要で、そのものずばりの「+」でOK。

┌──────────────────────────────────────┐
│%02d                                                                        │
└──────────────────────────────────────┘
先頭に「0」を付けるとゼロパディングとなる。「01」とか「00」とかだ。
「12」とか「123」とかは前出同様に勝手に表示される。

┌──────────────────────────────────────┐
│%.2f                                                                        │
└──────────────────────────────────────┘
小数点以下の数字は、小数部の桁数を表す。「1.23」「4.00」みたいな感じだ。

┌──────────────────────────────────────┐
│%.0f                                                                        │
└──────────────────────────────────────┘
小数点以下はいらない、整数部だけでよいという場合は「0」を指定してしまえばよい。
ちなみに、小数部はデフォルトでゼロパディングなので
整数におけるゼロパディング指定的なものが不要ということになる。
分類:C/C++
C言語/続・アライメントサイズの確認
2012年11月08日
┌──────────────────────────────────────┐
│struct {                                                                    │
│    char  a;                                                                │
│    int   b;                                                                │
│} z;                                                                        │
│printf("%d", sizeof(z));  →8(1+空3+4)                                    │
└──────────────────────────────────────┘
のように、int型の直前にアライメント端数があると、空き地を設けてくれるわけだが
┌──────────────────────────────────────┐
│struct {                                                                    │
│    int   b;                                                                │
│    char  a;                                                                │
│} z;                                                                        │
│printf("%d", sizeof(z));  →8(4+1+空3)                                    │
└──────────────────────────────────────┘
実は、構造体の末尾でも同じことがいえる。

つまり、構造体のサイズはアライメントの倍数であることが保証されるわけだ。

よって、以下の数式で構造体配列の配列数を正しく求めることもできる。
┌──────────────────────────────────────┐
│配列数 = sizeof(配列) / sizeof(配列[0]);                                    │
└──────────────────────────────────────┘
分類:C/C++
C/sscanf()の挙動
2012年11月07日
┌──────────────────────────────────────┐
│単語数 = sscanf(対象文字列, "%d,%d,%d", 取得A, 取得B, 取得C);               │
└──────────────────────────────────────┘
上記のような感じで、対象文字列が以下の場合の結果は
  ・「1,2,3」の場合  →単語数=3、取得A-B-C=1-2-3  正常な場合
  ・「1,2」の場合    →単語数=2、取得A-B-C=1-2-0  成功したところは取得できる
  ・「1,2,」の場合   →単語数=2、取得A-B-C=1-2-0  成功したところは取得できる
  ・「1,2,a」の場合  →単語数=2、取得A-B-C=1-2-0  成功したところは取得できる
  ・「1,,3」の場合   →単語数=1、取得A-B-C=1-0-0  成功したところは取得できる
  ・「1,a,3」の場合  →単語数=1、取得A-B-C=1-0-0  成功したところは取得できる
  ・「,2,3」の場合   →単語数=0、取得A-B-C=0-0-0  冒頭でこけたら全滅する
  ・「a,2,3」の場合  →単語数=0、取得A-B-C=0-0-0  冒頭でこけたら全滅する
  ・「」の場合       →単語数=0、取得A-B-C=0-0-0  空文字は例外とはならない
  ・「a」の場合      →単語数=0、取得A-B-C=0-0-0  該当なしも例外とはならない
  ・「1,2,3,4」の場合→単語数=3、取得A-B-C=1-2-3  実は正常な場合と区別できず
  ・「(NULL)」の場合 →例外発生
※取得A-B-Cは「%d-%d-%d」で出力したものです
分類:C/C++
前へ 1 2 3 4 5 6 7 8 9 次へ