C言語まとめ

C language, c.

演算子

bit 演算

代表的な演算子.

  • AND: A&B
  • OR: A|B
  • XOR: A^B <=> (A&~B)|(~A&B)
  • NOT: ~A
  • DeMorgan’s Low: ~(A|B) = ~A&~B

Two’s Complement Arithmetic

2 の補数. 2 の補数 - Wikipedia Integer の negative を得るためには, 以下の関係がなりたつ.

~x + 1 = -x
x + 1 = ~x

これからいろいろな定理が導ける.

/* マイナス 1 (2) */
+ ~0
 
(!A) = (A ^ 1)
(A ^ 1) ^ 1= (!A) ^ 1 = A

Bit 演算 Tips

/* N ビット目を取り出す */
(n >> N) & 1
 
/* N ビット目に 1 をセットする */
n = n | (1 << N);
 
/* N ビット目に 0 をセットする */
n = n & ~(1 << N);
 
/* N ビット目を反転 */
n = n ^ (1 << N);
 
/* 0 ビット目から N-1 ビット目までがすべて 1 である列の生成 */
n = (1 << N) - 1;
 
/* 全ビットの反転 (1) */
n = ~n
 
/* 全ビットの反転 (2) */
n = n ^ ~0
 
/* unsigned int の最上位ビットの値 (1) */
1 << ( sizeof (unsigned) * 8 - 1 )
 
/* unsigned int の最上位ビットの値 (2) */
~(~0U >> 1)
 
/* 1 である最も下位のビットの値を抽出 */
-n & n
 
/* 奇数かどうかの判定 */
if ( n & 1 ) { /* 奇数 */ }

絶対値を求める.

/* 絶対値 */
int r = (v + mask) ^ mask;
int r = (v ^ mask) - mask;
 
inline int fastabs (int a)
{
 int mask = a >> 31;
 return (a ^ mask) - mask;
}
 
/* 2 整数の max, min */
inline int fastmax (int a, int b)
{
 int t = (a-b);
 return a - (t & (t >> 31));
}
 
inline int fastmin (int a, int b)
{
 int t = (a-b);
 return b + (t & (t >> 31));
}

if 文を置き換え.

/* x が 0 or 1 と仮定すると */
if (x) a=y else a=z;
a = x ? y : z;
a = ((x<<31) >> 31)& y + ((!x) << 31) >> 31) & z

フラグ制御 Tips

イベントフラグの制御として, C 言語ではビット演算が大活躍!

/* フラグの取得 get */
x & y
/* フラグを立てる set */
x | y
/* フラグを解除 clear */
x & ~y
x &= 0x10;
x |= 0x10;
x &= ~0x10;

シフト演算

乗算・除算

/* 2 の i 乗倍する */
n <<= i;
y = x << 1; // y = x * 2;
 
/* 2 の i 乗で割る */
n >>= i;
y = x >> 1; // y = x / 2;
 
/* 2 の i 乗で割った剰余 */
n & ((1 << i) - 1)

算術シフトと論理シフト

論理シフトは符号ビット (先頭ビット, 第 15 ビット, 最も左のビット) を含めてシフトするもので, 空いたビット位置すべてに 0 が入ります.

算術シフトは符号ビットを除いてシフトするもので, 空いたビット位置すべてに左シフトの時は 0, 右シフトの時は符号ビットと同じものが入ります.

int logicalShift (int x, int n) {
  int mask = ((1 << 31) >> n) << 1;
  return (x >> n) & ~mask;
}

論理演算

論理演算子 Tips

if を論理演算で置き換える.

/* if (A) B */
A && B;
 
/* if (!A) B */
A || B;

算術演算

構造体

構造体のサイズは, コンパイルが決める. double, int は char よりも先に宣言したほうが, メモリ効率かよい.

📝構造体(Stateful ADT)

📝ポインタ(C)

Topics

👨デニス・リッチー

  • ベル研究所
  • C言語のパパ.

📚プログラミング言語C - ブライアン・カーニハン/デニス・リッチー

K&Rと略す.

歴史的プログラミング言語の名著. 🔖Hello worldはここから始まった.

わたしも持ってたけど売却した.

🦊C言語with me

わたしのはじめて学んだプログラミング言語

🔵プログラミングの勉強で高2の夏休みにC言語を学んだ(2003/08)