はじめに
引き続き、C言語のポインタについて理解を深めるため、この本を読み備忘録としてまとめる
C言語ポインタ完全制覇
この本には見るたびに発見が見つかって面白い。
感謝、感謝。ありがとうございます。
3章
宣言の解読方法
- 識別子(変数名、関数名)を見つける
- 識別子に近い順でまとめる
- 宣言をまとめる括弧
- 配列の[ ] , 関数の( )
- ポインタの *
- 最後に型の指定子をまとめる
例題1
・ int (*func)(double);
- 識別子はfunc, funcはポインタ
- 関数の引数はdouble, 戻り値はint
→ funcは戻り値がint、引数がdoubleの関数へのポインタ
例題2
・ int hoge[10];
- 識別子はhoge, hogeは配列, 型はint
→ hogeはint型の配列(要素10)
例題3
・ int *hoge[10];
- 識別子はhoge, hogeは配列, hogeの配列はポインタ, 型はint
→ hogeはint型を指すポインタの配列(要素10)
例題4
・ int (*hoge)[10];
- 識別子はhoge, hogeはポインタ, hogeのポインタは配列, 型はint
→ hogeはint型の配列(要素10)を指すポインタ
例題5
・ int hoge(void (*func)(void))
- 識別子はhoge, hogeは関数,戻り値はint
- 識別子はfunc, funcはポインタ,引数はvoid,戻り値はvoid
→ hogeは関数(引数は、戻り値がvoidで引数なしの関数ポインタ)
配列へのポインタ
・配列へのポインタと、配列の先頭アドレスを表すポインタは同じ値だが、
配列か、要素を指すかで異なる
int array[3];
int (*array_p)[3];
array_p = &array; //array[3]の配列へのポインタ
//array_p = array; int型の値(array[0])へのポインタ
int *p;
int array[10];
p = array; //int型の値(array[0])へのポインタ
// array = p; すでに定義済みの配列のアドレスにポインタ変数は上書きできない
// これはint a ですでに確保した値の &a に値を入れようとしているのと同義
これと同様のことを行おうとしているのが
char str[10];
str = "abc";
これはすでに要素10の配列strを定義しているが、
配列の先頭アドレスに "abc"の先頭アドレスを入れようとしているのも同様。
アロー演算子
・構造体のメンバへのアクセスで
p->hoge は (*p).hoge と同義
const修飾子はconstの後に続く識別子が読み出し専用「読み出し専用」
・const 変数 は 変数が読み出し専用
・char * const 変数 は 変数が読み出し専用
・const char *変数 は 変数の参照先が読み出し専用
・char const *変数 は 変数の参照先が読み出し専用
typedefの使い方
・typedef char *string
charのポインタ変数をstringと定義
文字列リテラル
・次の表現はどれもお同じ
char *str = "abc";
char str[] = "abc";
char str[] = {'a','b','c','¥0'};
4章
ポインタの反則遊び その1
まずは、わかりやすい例
int a[5] = {1,2,3,4,5};
int *b = a;
printf("%d",*(b + 5));
printf("%d",a[5]);
これは、配列の要素数以上の値を指定している。
コンパイルでエラーにはならない。
ポインタの反則遊び その2
typedef struct {
int npoints;
Point *point;
}Polyline;
PolyLine *polyline;
↓↓↓↓↓↓↓ あなたの記事の内容
polyline = malloc(sizeof(Polyline) * 2);
polyline->point = malloc(sizeof(Polyline) * 5);
───────
Polyline = malloc(sizeof(Polyline) * 2);
polyline->point = malloc(sizeof(Polyline) * 5);
↑↑↑↑↑↑↑ 編集リクエストの内容
↓
typedef struct {
int npoints;
Point point[1];
}Polyline;
PolyLine *polyline;
Polyline = malloc(sizeof(Polyline) + sizeof(Point) * (npoints - 1));
ポインタの反則遊び その3
配列の添え字は「0」から始まるが、強制的に「1」から始める
int array[10] = {1,2,3,4,5,6,7,8,9,0};
int *array_p = &array[-1];
// int *array_p = array[-1] ではコンパイルエラー
printf("%d",array_p[1]);
あと書き
3,4章の読破時間・・・5h