MENU

Cメモ - tips5

気になったことメモ

読んだ本

  • C言語ポインタ完全制覇(前橋和弥)
  • ふつうのLinuxプログラミング(青木峰郎)

主にポインタ

  • %pに入れる時はvoid*でキャストする必要がある
#include <stdio.h>

int main(void)
{
  int hoge = 5;

  printf("&hoge : %p\n", (void*)&hoge);

  return 0;
}
  • void型のポインタ宣言注意
#include <stdio.h>

int main(void)
{
  int hoge = 5;
  void *hoge_p;

  hoge_p = &hoge;
// アドレスの値だけ渡している状態
// hoge_pのままだと型が定まっていないためエラー
// どの型で取り出していいか分からない
  printf("%d\n", *(int*)hoge_p);

  return 0;
}
  • ポインタに加算をするとそのポインタの型の大きさバイト分だけアドレスが増加する
#include <stdio.h>

main(void)
{
  int hoge;
  int *hoge_p;

  hoge_p = &hoge;

  *hoge_p++;  // +1でint分(4バイト)だけ増加する
  printf("hoge_p : %p\n", (void*)hoge_p);
  return 0;
}
  • NULLについて
int *p = 3; // これは警告、型が違う
int *p = 0; // 0という定数はポインタとして扱うべき時はヌルポインタとして扱われる
  • 配列について
    • 宣言で使われる""と式の中で使われる""は別物
    • 式の中で使われる"[]"は*(p + i)のようなポインタpからiだけずらした位置を示すシンタックスシュガー
    • 関数の仮引数の宣言においてだけ、配列の宣言はポインタに置き換えられる
int func(int a[]) → int func(int *a)
  • アライメントについて
    • 構造体のサイズを求める時にメンバーのサイズを足し算して求めるのは誤り
    • CPUによってメンバーが入るアドレスは異なる
    • 例えばcharの後のメンバーの型がdouble型でCPUがdouble型を8の倍数のアドレスにしか配置しない場合、charのうしろにはパディングが入る

  • printfについて

    • 注意点としてfgetsなどで取得した文字列の中に%が入っていると挙動がおかしくなる
  • Linux動作環境

    • ほとんどが32bitOS上→long型が32ビット *1

*1:Continue...