Head First C やら猫Cやら Web に落ちてる記事やらを参考にここ何ヶ月か C を勉強して、一区切りついたのでメモ的にまとめとく。
- 文字列
- 文字列型はない。文字型配列の最後に
'\0'
が入る。'\0'
は文字列終端文字。
- 文字列型はない。文字型配列の最後に
- メモリ
- スタック:ローカル変数。
ヒープ:動的メモリ。関数が終了しても残る。
グローバル:グローバル変数。
定数:定数。
- スタック:ローカル変数。
- ポインタ
- ポインタ宣言:
int *hoge
ポインタ実体:*hoge
変数のアドレス:&fuga
- 配列変数
char s[] = "hogegegegege"; // 配列変数、strlen(s) == 12、sizeof(s) == 13
char *t = s; // 配列ポインタ、sizeof(t) == 4 もしくは 8
は s と t は別物。(関数の引数の場合は両方共ポインタ) - ポインタ記法
hoge[2] == 2[hoge] == *(hoge + 2) - 文字列リテラル
char *s = "hoge"; //文字列リテラル 書き換えられない
char s[] = "hoge"; //これは配列なので書き換えられる
ポインタに文字列リテラルを設定するときは必ず
const char *s = "hoge";
みたいにconst
使うべし。
- ポインタ宣言:
- ファイル
- < :標準入力リダイレクト // シェル
-
:標準出力リダイレクト // シェル
- エラー表示:
$ echo $?
// シェル - パイプ
hoge | fuga
// シェル
ちなみにhoge
とfuga
は同時に動作するので、hoge
が完了するのを待ったりはしない。 int fprintf( FILE *restrict stream, const char *restrict format, ... );
-
FILE *fopen( const char *restrict filename, const char *restrict mode );
int fclose( FILE *stream );
- コマンドライン引数
- int main (int argc, char *argv[]) {…
argv[0]
は実行するプログラム名なので、実際の引数はargv[1]
から。 - コマンドラインオプション
getopt()
でオプション読み込み。オプションの引数はoptarg
で取得。最後にoptind
で調整。
ヘッダーはunistd.h
。
ちなみにunistd.h
は標準Cライブラリではなく、POSIXライブラリ。
- int main (int argc, char *argv[]) {…
- 複数ソースファイル
- ヘッダファイルで宣言分離
- プリプロセッシング
コンパイル:アセンブリ言語に変換
アセンブリ:オブジェクトコードの生成
リンク - make
インデントはタブです。
- 構造体
-
struct hoge { ~ }; //要素の区切りはセミコロン
`typedef struct hoge { ~ } fuga; //fuga は struct hoge のエイリアス。hoge は省略可。
要素のことはフィールドって呼ぶ。.記法でアクセス。
構造体の入れ子とか再帰的なのも可。 - 構造体変数の代入はデータのコピー。
- 構造体へのポインタ
struct *s
のフィールドへのアクセスはs -> hoge
。 - 共用体
typedef union { ~ } hoge; // 要素の区切りはセミコロン
hoge h = {.fuga = num};
hoge q; q.fuga = num;
みたいに値を設定。 - 列挙型
enum hoge (fuga1, fuga2, fuga3); //typedef も使える
共用体に何が格納されているかわからないので、列挙型と一緒に使うと管理しやすい。 - ビットフィールド
typedef struct { unsigned int hoge:1; } fuga;
とすると1ビットに格納する。
実際にはワード境界とかあるから、全体でグループ化されたりする。
-
- 動的メモリ
- 連結リストは再帰構造体で作成。
同じ型の構造体へのポインタを構造体の中に含めるので、typedef のエイリアスが使えない。
だからstruct hoge
の正式な名前を使わなくてはいけない。
typedef でエイリアス定義した後に、構造体の中身を定義できるため、typedef のエイリアスを使うことは可能でした。 -
void* malloc( size_t size );
void free( void* ptr );
ヘッダーはstdlib.h
- ヒープ領域での文字列コピー
char *strdup(const char *s);
free()
で解放するのを忘れずに。 - メモリリーク
Linux は valgrind とかある。mac は別途調べるべし。
- 連結リストは再帰構造体で作成。
取り急ぎ以上です。
vol.2 へ続く。