【C】初めてのC言語（21. コマンドライン引数と二重ポインタ）

# はじめに

* これまでの学習に続いて、今回はコマンドライン引数と二重ポインタについて学んだ結果をまとめてみました。


# 学習環境

* 今回は[paiza.io](https://paiza.io/ja/projects/new)のC言語のエディタを使いました。

# main関数の定義

* これまでmain関数の引数は`void`でしたが、これとは異なる`int`と`char**`を引数に持つmain関数を宣言することもできます。
* 2つの引数はそれぞれ以下の値となります。
  * argc：コマンドライン引数の数
  * argv：コマンドライン引数の中身

```c:これまでのmain関数の書き方
#include <stdio.h>
int main(void){
    // 処理を書く
}
```

```c:main関数の異なる書き方
#include <stdio.h>
int main(int argc, char** argv){
    // 処理を書く
}
```

# 二重ポインタ

* 2つ目の引数の`argv`のデータ型は`char**`となっており、これは二重ポインタと呼ばれます。
  * `argv`の指す先には、コマンドライン引数が配列として格納されているそうです。
  * この時、1つ目のコマンドライン引数を表す`argv[0]`は、1つ目のコマンドライン引数の文字列を「char型の配列」として格納されているそうです。
* 文章で説明するのは難しいので実際に以下のコードを動かしてみると、「配列の中にchar型配列が入っているイメージ」なのが分かります。
 * paiza.io上ではCのエディタ上でコマンドライン引数を付けて実行できないため、bashエディタ上でMain.cをコンパイルした上で、出来上がった実行ファイルに引数を渡して実現しています。

```c:Main.c
#include <stdio.h>
int main(int argc, char** argv){
    printf("argc=%d\n", argc);
    
    for(int i=0; i<argc; i++) {
        char* addr = argv[i];
        printf("%d番目のコマンドライン引数：%s\n", i, addr);
    }
}
```

```bash:Main.sh（※Main.cの実行用スクリプト）
# paiza.io上でMain.cをコマンドライン引数付きで実行するためのスクリプト
gcc Main.c -o Main.o
./Main.o Hello world
```

```text:実行結果
argc=3
0番目のコマンドライン引数：./Main.o
1番目のコマンドライン引数：Hello
2番目のコマンドライン引数：world
```

```text:argvの構造（※イメージ）
argv(char**型)
  ├─argv[0](char*型)
  │   ├─.
  │   ├─/
  │   ├─M
  │   ├─a
  │   ├─i
  │   ├─n
  │   ├─.
  │   └─o
  ├─argv[1](char*型)
  │   ├─H
  │   ├─e
  │   ├─l
  │   ├─l
  │   └─o
  └─argv[2](char*型)
      ├─w
      ├─o
      ├─r
      ├─l
      └─d
```




# 補足：これまでの学習の歩み

* [【C】初めてのC言語（1. Hello world）](https://qiita.com/nkojima/items/518c1a4ec06861d74b3c)
* [【C】初めてのC言語（2. 四則演算とフォーマット指定子）](https://qiita.com/nkojima/items/36ea93b7296ce9e8a55b)
* [【C】初めてのC言語（3. ポインタ）](https://qiita.com/nkojima/items/825bb9f931016faccd68)
* [【C】初めてのC言語（4. 構造体）](https://qiita.com/nkojima/items/40a1101f2f6f5800bc2d)
* [【C】初めてのC言語（5. 関数）](https://qiita.com/nkojima/items/1fa3317c04f25fe24276)
* [【C】初めてのC言語（6. 配列）](https://qiita.com/nkojima/items/eda3ff6675b47e7ab5f0)
* [【C】初めてのC言語（7. for文）](https://qiita.com/nkojima/items/a5659098f7e5275a96ec)
* [【C】初めてのC言語（8. 2次元配列）](https://qiita.com/nkojima/items/f5eb25a4f8d1725faa89)
* [【C】初めてのC言語（9. 関数のプロトタイプ宣言）](https://qiita.com/nkojima/items/57318d74bdfa670bf72e)
* [【C】初めてのC言語（10. 構造体配列）](https://qiita.com/nkojima/items/75530a3ca63924a14397)
* [【C】初めてのC言語（11. ヘッダファイル）](https://qiita.com/nkojima/items/a10cd943ed66e0cea7fd)
* [【C】初めてのC言語（12. 3つのからくり構文＋ポインタ演算）](https://qiita.com/nkojima/items/83cb40ec01cd6a6e6a87)
* [【C】初めてのC言語（13. メモリを扱う標準関数）](https://qiita.com/nkojima/items/13c8d942f282beb3c212)
* [【C】初めてのC言語（14. ヒープの利用）](https://qiita.com/nkojima/items/837557cc86ce9697611a)
* [【C】初めてのC言語（15. sizeofの注意点）](https://qiita.com/nkojima/items/6c9a3ba04c6348219578)
* [【C】初めてのC言語（16. 文字列の基本）](https://qiita.com/nkojima/items/d87ce0cb15dd1a26f21a)
* [【C】初めてのC言語（17. 文字列リテラル）](https://qiita.com/nkojima/items/527ef37d84cf9b201dc5)
* [【C】初めてのC言語（18. 文字列の受け渡し）](https://qiita.com/nkojima/items/a07ac9a9bb3b41296f1e)
* [【C】初めてのC言語（19. 文字列とバッファオーバーフロー）](https://qiita.com/nkojima/items/4d9cec9e686aee41eec2)
* [【C】初めてのC言語（20. 文字列を扱う標準関数）](https://qiita.com/nkojima/items/12ac7b9b64baae1a67d1)

# 参考URL

* [スッキリわかるC言語入門 第2版](https://www.amazon.co.jp/dp/4295012785/)
  * p.427～p.432