はじめての構造体とか
ロベールのC++教室 第1部68章くらいまでざざっと。
コンパイル時に色々教えてくれるの、割と性にあっているかもしれない。
- 関数名は関数のアドレスを返す。
int main() { printf("%p", main); // => 0x10a23eee0 }
- 配列変数名は先頭の要素のアドレスを返す。
int array[] = {1, 2, 3, 4, 5}; printf("%p", array); // => 0x7ffeeb482a80 printf("%p", &array[0]); // => 0x7ffeeb482a80
アドレス[インデックス]
と*(アドレス+インデックス)
は同じ。
int array[] = {10,20,30,40,50}; printf("%d\n", array[3]); // => 40 printf("%d\n", *(array+3)); // => 40
- signedは符号付き、unsignedは符号なし
接頭辞sz: string zero terminated
sizeof
sizeof 変数名
でその変数のバイト数を返すsizeof(型名)
でその型のバイト数を返すsizeof array
でその配列全体のバイト数を返す- 「原則的に、式中の配列オブジェクトはその配列の先頭要素へのポインタ値を返すが、配列がsizeofのオペランドである場合は例外である。」
- 参考:sizeof演算子について - Qiita
sizeof *array
でその配列の最初の要素のバイト数を返す- よって、配列の要素数を求めたければ
sizeof array / sizeof *array
とする。 - size_of 演算子の返却値はsizeof_tという特殊な型であり、printfではunsigned longと同様
%lu
を用いる。 - 配列の要素数を求めるだけでこんなに面倒なのかとびっくりする。rubyならarray.sizeで済むのにな。
int array[] = {1, 2, 3, 4, 5}; printf("%lu\n", sizeof array); // => 20 printf("%lu\n", sizeof *array); // => 4 printf("%lu\n", sizeof array / sizeof *array); // => 5
- 値渡し/参照渡し
- 基本的に関数に引数を渡すときは値渡しになる。
- しかし配列は変数名の正体がポインタなので、ポインタを渡す(参照渡し)になる。
- 構造体も原則値渡しになってしまうが、サイズがでかくなりがちな構造体をばんばん値渡ししてメモリ上のそこらじゅうにコピーをつくるのは嫌なので、以下のように参照渡しするのがベター。
struct SStudent { char szName[16]; int nEnglish; int nMath; int nScience; }; void Disp(SStudent& student) { // この"&"で参照渡し printf("%s\n", student.szName); printf("%d\n", student.nMath); } int main() { SStudent students[] = { {"yamada", 67, 49, 84}, // 構造体の初期化子は"{ }"で囲む {"tanaka", 90, 65, 69} }; for(int i=0; i<(sizeof students/sizeof *students); i++) Disp(students[i]); }