C++ポインタまとめ

# アドレス
・変数の値はコンピュータのメモリに保存される。
・***アドレス***は値が格納されているメモリの位置を表す。
### 変数のアドレスの取得
・変数からは 1.***アドレス(address)*** と 2.***実体、値(content, value)*** を取り出すことができる。
・アドレスを取得するには、アドレス演算子である***&***を使う。

```cpp
int num = -99;
// 実体の出力
cout << num << endl;  // -99
// アドレスの出力
cout << &num << endl;  // 0x00F4
```

# ポインタ変数

・***ポインタ変数***、または***ポインタ***とは、***アドレスを保持する変数***のこと。
・ ポインタ変数を使うことは、***メモリのアドレスを使って別のデータにアクセスする方法の一つ***。
・ポインタ（変数）の操作は、単なる値の操作よりも、低レベルな操作。
・プログラマは、ポインタ（変数）に格納したいアドレスを見つけて、それを正しく扱わなければならない。
### 宣言

```cpp
int *intptr:
```
・「`intptr`はint型のアドレスを持つことが出来る」という意味。

※宣言の時、スペースは重要ではない

```cpp
int * intptr;  // 上と同じ
int* intptr;  // 上と同じ
```

### ポインタ変数にアドレスを代入

```cpp
int *intptr;
intptr = &num;
```
・ポインタ`intptr`が、変数`num`のアドレスを指すようになる

例）

```cpp
int x = 25;  // int変数
int *ptr;  // ポインタ変数（int型へのポインタ）

ptr = &x;  // ptrにxのアドレスを代入
cout << "x の値は " << x << endl;
cout << "x のアドレスは " << &x << endl;
cout << "x のアドレスは " << ptr << endl;
```

結果）

```
x の値は 25
x のアドレスは 0x7e00
x のアドレスは 0x7e00
```

# 間接参照
・間接参照演算子(***\****)は、ポインタを***間接参照（デリファレンス）***する。
・ポインタが指している***値にアクセスできる***ようになる

```cpp
int x = 25;
int *intptr = &x;
cout << *intptr << endl;  // 25
cout << intptr << endl;  // 0x7e00
```

例）

```cpp
int x = 25;  // int型の変数
int *ptr;  // int型へのポインタ

ptr = &x;  // ｘのアドレスをポインタに代入

cout << x << endl;
cout << *ptr << endl;
cout << &x << endl;
cout << ptr << endl;

// ptrが指す場所に100を代入してみる。
// これは実際にxに100を割り当てる。(デリファレンス)
*ptr = 100;

cout << "値を変更した結果" << endl;
cout << x << endl;
cout << *ptr << endl;
cout << &x << endl;
cout << ptr << endl;

```

結果）

```text
25
25
0x7e00
0x7e00
値を変更した結果
100
100
0x7e00
0x7e00
```



# 関数に情報を渡す
## 値渡し
・普通の方法。関数内で引数に渡された値の変更ができない。

## 参照渡し
・***参照（リファレンス）***とは、ある値に対し***別名をつける***機能。

例）

```cpp
int jellyDonuts;
getOrder(jellyDonuts);

void getOrder(int &donuts)
{
  cout << "何個のドーナツがほしいですか？";
  cin >> donuts;
}
```

・ 関数`getOrder`の引数`donuts`に「***&***」を付けると、***呼び出し元の変数`jellyDonuts`の別名***となる。（束縛するとも言う。）

※ 値渡しの場合、呼び出された関数からは呼び出し元の変数は見えない(***関数内で値を変更しても、元の値は変化しない***)が、***別名であればアクセスすることができる***。

## ポインタ渡し
例)

```cpp
int number = 5;
showValue(&number);

void showValue(int *value)
{
 cout << value << endl;  // numberのアドレスが表示される
}
```
・ 関数`showValue`の引数`value`に「***\****」を付けると、***呼び出し元の変数`number`を指すポインタ（変数）***となる。
・C++は自動的に引数`value`に変数`number`の***アドレスを代入***する。

※ 値渡しの場合、呼び出された関数からは呼び出し元の変数は見えない(***関数内で値を変更しても、元の値は変化しない***)が、***ポインタであればアクセスすることができる***。

cf. [値渡し、ポインタ渡し、参照渡しの違い](http://qiita.com/Rompei/items/e70e3b453cb485858062)

# ポインタ演算
## 配列とポインタの関係
・配列名を添え字なしで使うと、配列の先頭の要素を指すポインタとなる。

### 宣言と代入

```cpp
int vals[] = { 4, 7, 11 };
int *valptr;
valptr = vals;  // 明示的に代入している。
```

・配列名`vals`は***配列の先頭の要素のアドレスを持つポインタ定数***となっている。

### 値の取得
#### `vals[i]` は `*(valptr + i)` と同じ

```cpp
// 同じ値が表示される。
cout << vals[1];  // 7が表示される。
cout << *(valptr+1);  // 7が表示される。
// 同じ値が表示される。
cout << vals[2];  // 11が表示される。
cout << *(valptr+2);  // 11が表示される。
```

### アドレスの取得
#### `&vals[i]`は`valptr + i`と同じ
```cpp
// 同じアドレスが表示される。
cout << &vals[1];
cout << valptr+1;
// 同じアドレスが表示される。
cout << &vals[2];
cout << valptr+2;
```

・`valptr + 1`とは、`(valptrのアドレス) + (1 × intのサイズ)`。
・つまり、先頭の要素からプラスした場所のアドレス。
・`*(valptr+1)`は、`valptr+1`の間接参照（デリファレンス）。

例）

```cpp
static constexpr int NUM_COINS = 5;
double coins[NUM_COINS] = { 0.05, 0.1, 0.25, 0.5, 1.0 };
double *doublePtr;  // double型へのポインタ
int count;

// doublePtrに配列coinsのアドレスを代入
doublePtr = coins;

cout << "配列coinsの値です。\n";
for (count = 0; count < NUM_COINS; count++)
  cout << doublePtr[count] << " ";

cout << "これも配列coinsの値です。\n";
for (count = 0; count < NUM_COINS; count++)
  cout << *(coins + count) << " ";
```


# 動的メモリ割り当て
## 動的メモリ割り当てとは？
・***プログラム実行中に、変数のための場所を割り当てる***ことができる。
・コンピュータは新しく割り当てられた変数のアドレスを返す。
・メモリを割り当てるには、`new`演算子を使う。

```cpp
double *dptr;
dptr = new double;
```
・`new` はメモリのアドレスを返す

## 動的配列
・`new`を、***配列のサイズを決める***ために使うこともできる。

```cpp
double *arrayPtr;
const int SIZE = 25;
arrayPtr = new double[SIZE];
```

・配列にアクセスするために、[ポインタ演算](http://qiita.com/yokoto/items/5672ff20b63815728d90#%E3%83%9D%E3%82%A4%E3%83%B3%E3%82%BF%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E5%BC%8F)で見た方法を使うことができる。

```cpp
for (i = 0; i < SIZE; i++)
  arrayPtr[i] = i * i;
```
or 

```cpp
for (i = 0; i < SIZE; i++)
  *(arrayPtr + i) = i * i;
```

・割り当てるのに十分なメモリがないとき、プログラムは終了する。

※ 静的配列と動的配列
1. 静的配列: ***コンパイル時***に大きさが決まる。
2. 動的配列: ***実行時***に大きさが決まる。

・静的配列にせよ動的配列にせよ、メモリを確保する手段に過ぎない。


例）

```cpp
#include <new>
int main(){
    int arr[5] = {};//自動変数領域にint型で要素数5つ分の連続した領域を確保し、0初期化
    arr[0] = 2;//ポインタ演算で0番目の要素にアクセスし2を代入
    int* d_arr = nullptr;
    try{
        d_arr = new int[5];//int型で要素数5つ分の連続した領域を動的に確保、失敗したら例外が飛ぶ
        d_arr[0] = 2;//ポインタ演算で0番目の要素にアクセスし2を代入
        delete[] d_arr;
    }catch(...){
        delete[] d_arr;
    }
    if(int* d_arr2 = new (std::nothrow) int[5]){//int型で要素数5つ分の連続した領域を動的に確保、失敗したらNULLポインタが帰る
        d_arr[0] = 2;//ポインタ演算で0番目の要素にアクセスし2を代入
        delete[] d_arr;
    }
}
```

## 動的なメモリの解放
・動的なメモリを開放するには`delete`を使う。
・動的な配列を開放するには、`[]`を使う。
・`delete`を使うのは、動的メモリに対してのみ。

例）

```cpp
# 売り上げの平均値を持つ配列を動的に割り当てる
double *sales, total = 0.0, average;

int numDays, count;  // 売り上げ日数となる変数。

// 売り上げ日数を得る。
cout << "何日間の売り上げを調べますか？ ";
cin >> numDays;

// 売り上げ日数を確保できるような十分大きな配列を、動的に割り当てる。
sales = new double[numDays];

// 毎日の売り上げを得る。
cout << "売り上げを入力してください。\n";
for (count = 0; count < numDays; count++)
{
  cout << (count + 1) << "日目" << " * ";
  cin >> sales[count];
}

// 売り上げの合計を計算する。
for (count = 0; count < numDays; count++)
{
  total +- sales[count];
}

// 1日の売り上げの平均を計算する。
average = total / numDays;

// 結果を表示する。
cout << fixed << showpoint << setprecision(2);
cout << "\n\n合計: $" << total << endl;
cout << "売り上げ平均: $" << average << endl;

// 動的に割り当てられたメモリを開放する。
delete [] sales;
sales = nullptr;  // salesをNULLにする。
```

結果）

```
何日間の売り上げを調べますか？ 5[入力]
売り上げを入力してください。
1日目: 898.63[入力]
2日目: 652.32[入力]
3日目: 741.85[入力]
4日目: 852.96[入力]
5日目: 921.37[入力]

合計: $4067.13
売り上げ平均: $813.43
```

※ ポインタをdeleteした後、`sales = nullptr`のように`nullptr`を代入するのはベストプラクティスの一つ。まず、プログラムが、***不本意に解放されたメモリの領域にアクセスするのを防ぐ***ことができる。次に、***そのポインタに対し`delete`がもう一度間違って呼ばれた場合、エラーが起こるのを防ぐ***。`delete`演算子は、どのデータも指さないNULLポインタに対して使われたときは、何も影響が出ないようになっている。
・もっと詳しく → [C++11スマートポインタ入門](http://qiita.com/hmito/items/db3b14917120b285112f)

# 関数からポインタを返す
・ポインタは、***関数の返り値***にもなる。

```cpp
int * newNum():
```

・関数は、その関数内にあるローカル変数へのポインタを返してはいけない。（その関数のスコープで確保された領域を指すポインタを、返さなければよい。）
・関数は以下を指すポインタのみを返すべき。
　・引数として関数に渡された値
　・動的に割り当てられたメモリ
　・static変数へのポインタ

例）

```cpp
int *getRandomNumbers(int num)
{
  int *array;  // 数を持つ配列

  // numが0かマイナスだったらnullを返す。
  if (num <= 0)
    return NULL;

  // 配列を動的に割り当てる。
  array = new int[num];

  // srandにtime(0)という値を渡して、乱数を生成する。
  srand(time(0));


  // 乱数を使って配列に値を入れる。
  for (int count = 0; count < num; count++)
    array[count] = rand();

  // 配列へのポインタを返す。
  return array;
```