-
構造体のビットフィールド。r,b に 5bit 分が、g に 6 bit 分が割り当てられる。
struct s {
int r: 5;
int g: 6;
int b: 5;
};
-
配列の初期化。意外と知られてないみたい。
int A[4] = {0,1,2,3};
カッコはperlだと(0,1,2,3)のように丸カッコだった気がする。まぎらわしい。
-
Cの宣言は「ブロックの先頭のみで」行います。また、宣言した変数は初期化することができます。
だから、次のプログラムは文法エラーではありません。
int main(){
int i = 0;
....
for(i = 0; i > SIZE; i++){
int j;
....
実は最近まで「関数の先頭で宣言、初期化はできない」と勘違いしてました。
-
Cでは行の切れ目はあくまでセミコロン(;)だから、文字列は二行にまたがってもいい。
char *str = "Hello,
world";
この場合、strには改行コードも入ってます。
改行コードを入れない文字列は
char *str = "Hello,\
world";
としましょう。こうするとコンパイラの警告も出なくなってちょっとすっきり。
-
doubleの値をscanfしたい時は
scanf("%lf", &d);
printfしたいときは
printf("%f");
-
大規模なシミュレーションをする時、コンパイル時に謎なエラー
Error: attempt to .org backwards ignored
が出た時は、メモリの使い過ぎを疑いましょう。int A[10000][10000]なんて配列を確保しようとしてたらアウトです。
あと、実行時に何の脈絡もなく
killed
って出てプログラムが止まってしまう場合は、unlimitコマンドでメモリの制限を緩くすることで実行できる場合があります。
-
負数の除算
5 % 4 = 1
-1 % 4 = -1
-5 % 4 = -1
-
シフトに関して、1 << 2 の値は 4
1 + 1 << 2 の値は5ではなくて8。(1+1)が先に計算されて、それを2シフトするから
-
標準関数・qsortを使う。例えばintの場合。
int compare(const void *v0, const void *v1){
return (*(int*)v0 > *(int*)v1) ? 1 : (*(int*)v0 == *(int*)v1) ? 0 : -1;
}
...
qsort(A, size, sizeof(int), compare);
比較が面倒です。下のように書いてもいい
int compare(const int *i, int void *j){
return (*i > *j) ? 1 : (*i == *j) ? 0 : -1;
}
...
qsort(A, size, sizeof(int), (int(*)(const void*, const void*))compare);
関数のキャスト。こっちのがきれいか。
-
バイトオーダーの変換、とか、"ひっくり返す"処理。
buf[]という大きな配列のうち、0番目からsize個をひっくり返す。
例えば、0,1,2,3でsize=3なら を2,1,0,3って感じ。
for(i = 0, j = size - 1; i < j; i++, j--){
char c = buf[i];
buf[i] = buf[j];
buf[j] = c;
}