2013/06/13 (木)
C言語のちょっとしたテクニックを集めていこうと思う。



----------------------------------------

・カンマ演算子
x = 5;
y = 10;
という2文を
x = 5, y = 10;
と1行にまとめて記述することができる。 これは、for文中で用いるカンマ演算子
for (i = 0, j = 0; i < n; i++) {
と同じ意味をもつ。
ところで、実はこんな用い方もできる。
a = (x = 5, y = 10);
こうすると。最終的にカッコの中身に10が残り、aに10が代入される。
初めて知った人も多いかもしれないが、
while (scanf("%d", &n), n > 0) {
上記のような用い方は知っている人も多いかもしれない。
これは、読み取った値が0以下ならループを抜けるという条件を1行で記述した例だ。

----------------------------------------

・便利な条件演算子
a = (x > y) ? x: y;
こうすると、aにxとyのうち大きい方が代入される。
row[(x > y) ? x : y]
func((x > y) ? x : y)
上記のような、配列番号や関数の引数など式しか記述できない箇所で威力を発揮する。

----------------------------------------

・配列の要素数が初期値の個数と等しい場合には、要素数を指定しなくてもよい。
int array[] = {5, 10, 15, 20}
この意味で、
main(int argc, char *argv[])
の*argv[]を理解することができる。
また、これに関連して、
char *row[] = {"Suncay", "Monday", "Thursday", …}
とすると、1単語の文字数、及び配列番号を指定せずに文字列を格納できる。

----------------------------------------

・配列で、初期値の数が配列の要素数に満たない場合、残りの要素には0が入れられる。
int array[100] = {-5, 0, 5}
例えば array[3] = 0 となる

----------------------------------------

・sizeof演算子と文字列配列
char str[100]
char *strp;

strp = str;

printf("%d %d\n", sizeof(str), sizeof(strp));
とすると、「100 4」と出力される。
sizeof演算子で配列のアドレスを指定するとその配列全ての合計バイト数が計算されるが、ポインタで間接的に配列のアドレスを指定してもポインタ変数のバイト数4byteが出力されるだけである。

----------------------------------------

・ポインタ演算子の増減の意味
int *ip;

ip++;
ip++ は sizeof(int)増えたことを表す

----------------------------------------

・ポインタの型変換
void *px;
x = *(int *)px;
とすると、整数が取り出せる。え?void型から整数? と思うかもしれないが、だいぶ前にqsort関数を用いるときにこんな使い方をしました。
 ちなみに
x = *(int *)&y;
という文は、x = yと同じ意味らしい。

----------------------------------------

・配列とポインタの関係。
Aを任意の配列とし、ポインタ変数pにAの先頭へのポインタが与えられているとする。このとき、次のいずれも同じ意味をもつ式である。
A[n]
p[n]
*(p + n)

----------------------------------------

・関数ポインタの配列化。
関数へのポインタは一見無意味に思えるが、ポインタを配列にすることでそのありがたみがわかる。
例えば、math.hライブラリの関数sin cos tanをまとめて扱いたいとき、math.hをインクルードした上で
double (*func[])(double) = {sin, cos, tan};
とすると、複数の関数を一まとめにすることができる。順番に呼び出すときは、
for (i = 0; i < 3; i++) {
    a[i] = (*func[i])(x[i]);
}
などとする。

----------------------------------------

・構造体の初期設定は2通りの書き方ができる。
struct complex {
 double real;
 double img;
}; x = {0, 0}
struct complex y = {0, 0}

----------------------------------------

・構造体は次のように構造体タグ名を省略したり、初期値の要素を省略したりできる
struct {
 double real;
 double img;
}; x = {0}
このとき、.imgには配列と同じように0が入る。

----------------------------------------

・ビットフィールド

共用体と構造体を組み合わせて、 バイト単位やビット単位への書き込みができる。
union field {
    unsigned char byte;
    struct xxx {
        unsigned char bit_0 : 1;
        unsigned char bit_1 : 1;
        unsigned char bit_2 : 1;
        unsigned char bit_3 : 1;
        unsigned char bit_4 : 1;
        unsigned char bit_5 : 1;
        unsigned char bit_6 : 1;
        unsigned char bit_7 : 1;
    } bit;
};


----------------------------------------

・エスケープシーケンス

意味 書き方
改行 '\n'
復帰 '\r'
タブ '\t'
バックスペース '\b'
ベル '\a'
\自身 '\\'
シングルクォーテーション '\''
ダブルクォーテーション '\"'
16進ビットパターン '\xhh'
8進ビットパターン '\ooo'
コメント
この記事へのコメント
コメントを投稿する
URL:
Comment:
Pass:
秘密: 管理者にだけ表示を許可する
 
トラックバック
この記事へのトラックバック
この記事のトラックバックURL
http://tochiii.blog119.fc2.com/tb.php/304-505d96f5
この記事にトラックバックする(FC2ブログユーザー)