C言語 配列 (動作確認)

sys
記事: 27
登録日時: 14年前

C言語 配列 (動作確認)

投稿記事 by sys » 14年前

個人的備忘録
配列型への*演算子、&演算子の結果を確認。
[環境:Xcode 3.2.5 64bti]

CODE:

#include
#include
#include
#include

int main(void) {
  printf("------- 前置き -------\n");
  printf("・等角フォントで体裁は整えている。\n");
  printf("・配列型の読み方\n");
  printf(" char *hoge[3]; → hoge is array(要素数3) of pointer to char (hogeは、charへのポインタの配列(要素数3)\n");
  printf(" char (*hoge)[3]; → hoge is pointr to array(要素数3) of char (hogeは、charの配列(要素数3)へのポインタ)\n\n");
  printf("・例外の記載は下記に対応する。\n");
  printf(" [例外1]sizeof演算子のオペランドが配列型 → 派生元の型のサイズに、配列の要素数を掛けたサイズ\n");
  printf(" [例外2]単項&演算子のオペランドが配列型 → 配列へのポインタ\n\n");
  printf("・単項&演算子は、「単項&演算子のオペランドが、単項*演算子の結果の場合(添字演算子の暗黙の*演算子も含む)、*演算子も&演算子も評価せず、両演算子とも取り除いた場合と同じ結果となる。」\n");
  printf("と定義されているが、評価したままの方が型が読みやすいので、評価した状態で記載。\n\n");
  printf("・添字演算子の、暗黙の*演算子への変換後の状態で記載\n");
  printf(" ex.)array[0][0] → (*((array)+(0)))[10] → (*((*((array)+(0)))+(0))) → (*(*(array+0))+0) → **array\n\n");
  printf("・「ポインタ」と言う言葉には、下記の意味を混同して使われている場合があるので注意。\n");
  printf("(1) pointer type...型としてのポインタ型、ポインタ変数\n");
  printf("(2) returns the address...値(address)を返すという意味のポインタ(&演算子)\n");
  printf("(3) pointer that points... 添字演算子の定義に出てくる「を指す」と言う意味のポインタ\n");
  printf("下記コードでは、(1)(2)のみポインタと記載している。\n");
  printf("※「ポインタの先頭要素を指す」は「指す(pointer that points)」とポインタ(pointer type)を区別するために「を指す」と記載。\n");
  printf("読みづらかったら「を指す」を「ポインタ」に読み替えると意味はわかりやすくなるかも\n");
  printf("※「&演算子」をポインタと記載した理由\n");
  printf(" ex.) &op1\n");
  printf("・結果の型:op1の型へのポインタ型\n");
  printf("・演算:アドレスを求める。(絶対的なものか相対的なものかは処理系依存)\n");
  printf("・演算結果:op1(が示すオブジェクト(変数)や関数)のアドレス(lvalue(オブジェクト指名子)ではない。)\n");
  printf(" と定義されており、結果の型がポインタ型であることから。\n\n");
  printf("・char array[2][3]; で具体的な解説\n");
  printf("「array」は「配列の先頭要素を指すを指す」ポインタと言う言葉を使うとすれば「配列の先頭要素へのポインタへのポインタ」となる。\n");
  printf("それぞれを分解して解説すると...\n");
  printf("(1)配列の先頭要素 → とは、char (char type)\n");
  printf("(2)を指す → とは、上記の「配列の先頭要素」を指している。array of char (要素型はchar)\n");
  printf("(3)を指す → とは、(2)の「を指す」を指している。array of array of char (要素型はarray of char)\n\n");
  printf("・個人的簡単な読み方\n");
  printf("*演算子が付いたら →「へのポインタ」「を指す」を消して読む。間接参照(結果はそのポインタが指していた物になる)\n");
  printf("&演算子が付いたら →「へのポインタ(&)」をつける。\n");
  printf("ポインタ演算 → ポインタが指す型のサイズ分増減するので、ポインタが指すものが何になるかに注目\n");
  printf("------- ------ -------\n\n");
  printf("・読み方\n");
  printf("式   ...返す値の説明 [値]\n\n");
  printf("---- main() char array[5] = \"aiue\"; ----\n");
  char array[5] = "aiue";
  printf("&array[0] [%p]\n\n", &array[0]);
  
  printf("[array] 型:char[5] :%s\n",typeid(array).name());
  printf("array         ...配列の先頭要素(char)を指す(array) [%p]\n", array);
  printf("array+1       ...配列の先頭要素(char)を指す(言い換えればポインタ)が指す型(char:%s) ×1増加 [%p → %p]\n", typeid(*array).name(), array, array+1);
  printf("sizeof(array) ...[例外1]派生元の型(char)のサイズに、配列の要素数(5)を掛けたサイズ [%zd]\n\n", sizeof(array));
  
  printf("[*array] 型:char :%s\n", typeid(*array).name());
  printf("*array        ...配列の先頭要素(char) [%c]\n", *array);
  printf("*array+1      ...ポインタ演算ではない。配列の先頭要素(char)に+1 [%c → %c]\n", *array, *array+1);
  printf("sizeof(*array)...配列の先頭要素(char)のサイズ [%zd]\n\n", sizeof(*array));
  
  printf("[&array] 型:char(*)[5] :%s\n", typeid(&array).name());
  printf("&array        ...[例外2]配列(char[5])へのポインタ(&) [%p]\n", &array);
  printf("&array+1      ...[例外2]配列(char[5])へのポインタ(&)が指す型(char[5]) ×1増加 [%p → %p]\n", array, &array+1);
  printf("sizeof(&array)...[例外2]配列(char[5])へのポインタ(& = char*)のサイズ [%zd]\n\n", sizeof(&array));
  
  printf("[&*array] 型:char* :%s\n", typeid(&*array).name());
  printf("&*array       ...配列の先頭要素へのポインタ(&) [%p]\n", &*array);
  printf("&*array+1     ...配列の先頭要素へのポインタ(&)が指す型(char) ×1増加 [%p → %p]\n", array, &*array+1);
  printf("sizeof(&*array)..配列の先頭要素へのポインタ(& = char*)のサイズ [%zd]\n\n", sizeof(&*array));
  
  printf("---- main() char two_array[2][3] = { \"ai\", \"ue\" }; ----\n");
  char two_array[2][3] = { "ai", "ue" };
  printf("&two_array[0][0] [%p]\n\n", &two_array);
  
  printf("[two_array] 型:char[2][3] :%s\n", typeid(two_array).name());
  printf("two_array           ...配列の先頭要素(char)を指す(*two_array)を指す(two_array) (先頭要素(char)へのポインタ(pointer that points)へのポインタ(pointer that points)) [%p]\n", two_array);
  printf("two_array+1         ...配列の先頭要素(char)を指す(*two_array)を指す(two_array)が指す型(char[3]:%s) ×1増加 [%p → %p]\n", typeid(*two_array).name(), two_array, two_array+1);
  printf("sizeof(two_array)   ...[例外1]派生元の型(char[3])のサイズに、配列の要素数2を掛けたサイズ [%zd]\n\n", sizeof(two_array));
  
  printf("[*two_array] 型:char[3] :%s\n", typeid(*two_array).name());
  printf("*two_array          ...配列の先頭要素(char)を指す(*two_array) (先頭要素(char)へのポインタ(pointer that points))  [%p]\n", *two_array);
  printf("*two_array+1        ...配列の先頭要素(char)を指す(*two_array)が指す型(char:%s) ×1増加 [%p → %p]\n", typeid(**two_array).name(), two_array, *two_array+1);
  printf("sizeof(*two_array)  ...配列の先頭要素(char)を指す(*two_array = char[3])のサイズ [%zd]\n\n", sizeof(*two_array));
  
  printf("[**two_array] 型:char :%s\n", typeid(**two_array).name());
  printf("**two_array         ...配列の先頭要素(char) [%c]\n", **two_array);
  printf("**two_array+1       ...アドレス演算ではない。配列の先頭要素(char)に+1 [%c → %c]\n", **two_array, **two_array+1);
  printf("sizeof(**two_array) ...配列の先頭要素(char)のサイズ [%zd]\n\n", sizeof(**two_array));
  
  printf("[&two_array] 型:char(*)[2][3] :%s\n", typeid(&two_array).name());
  printf("&two_array         ...[例外2]配列(char[2][3])へのポインタ(&) [%p]\n", &two_array);
  printf("&two_array+1        ...配列(char[2][3])へのポインタ(&)が指す型(char[2][3]) ×1増加 [%p → %p]\n", &two_array, &two_array+1);
  printf("sizeof(&two_array)  ...配列(char[2][3])へのポインタ(& = char*)のサイズ [%zd]\n\n", sizeof(&two_array));
  
  printf("[&*two_array] 型:char(*)[3] :%s\n", typeid(&*two_array).name());
  printf("&*two_array         ...配列の先頭要素(char)を指す(*two_array)へのポインタ(&) [%p]\n", &*two_array);
  printf("&*two_array+1       ...配列の先頭要素(char)を指す(*two_array)へのポインタ(&)が指す型(char[3]) ×1増加 [%p → %p]\n", &*two_array, &*two_array+1);
  printf("sizeof(&*two_array) ...配列の先頭要素(char)を指す(*two_array)へのポインタ(& = char*)のサイズ [%zd]\n\n", sizeof(&*two_array));
  
  printf("[&**two_array] 型:char * :%s\n", typeid(&**two_array).name());
  printf("&**two_array        ...配列の先頭要素(char)へのポインタ(&) [%p]\n", &**two_array);
  printf("&**two_array+1      ...配列の先頭要素(char)へのポインタ(&)が指す型(char) ×1増加[%p → %p]\n", &**two_array, &**two_array+1);
  printf("sizeof(&**two_array)...配列の先頭要素(char)へのポインタ(& = char*)の大きさ [%zd]\n\n", sizeof(&**two_array));

  return 0;
}
最後に編集したユーザー sys on 2011年5月24日(火) 14:15 [ 編集 4 回目 ]

コメントはまだありません。