普段思ったことや、雑記。

Menu & Search

C言語のmain関数の引数(コマンドライン引数)についてなんとなく面白いと思ってしまった

2019年5月3日

2019年5月3日 追記

C#やJavaも同じ仕様とのコメントがあったので、特に意味のない記事になってしまった…。

恥ずかしながら、私はこれまでC言語については学生時代を最後に、int main(void)…(おまじない)とずっとやっており、C言語のメイン関数の引数について一切の理解がなかった。現在、ふつうのLinuxプログラミング 第2版 Linuxの仕組みから学べるgccプログラミングの王道という本でLinuxについて学習を進めており、そこでCのメイン関数の引数について知ることがあって、この仕様が個人的に面白いと思った。

メイン関数の第一引数と第二引数は必ずコマンドライン引数の値が格納される

まずは、サンプルコードを見たほうが早いと思うので、サンプルコードを示す。下記は「ふつうのLinuxプログラミング 第2版 p18」に掲載されているarg.cのコードを引用した。

#include <stdio.h>
#include <stdlib.h>

int main(int argc, char const *argv[])
{
  int i;

  printf("argc=%d\n", argc);
  for(i = 0; i < argc; i  ) {
    printf("argv[%d]=%s\n", i, argv[i]);
  }
  
  return 0;
}

このコードをgccでコンパイルし、実行すると下記のような実行結果が得られる。

$ ./args.o abc def
argc=3
argv[0]=./args.o
argv[1]=abc
argv[2]=def

メイン関数の第一引数はコマンドライン引数の配列の長さの値が格納される。第二引数にはコマンドライン引数が配列として格納される。また、第二引数の注意点として、必ず実行元となるファイル名が配列の0番目に格納される。

メイン関数の仕様で面白いと思ったポイント

1. 指定した関数名「main」とした場合に設定される引数が設定されている

「この関数名で関数を宣言したときには引き数は必ずある決まった形になる」みたいな仕組みは他言語で見たことがなかった。なので、この仕様は私にとって新鮮だった。モバイルアプリ開発(Objective-C, Swift)でメソッドは、継承元クラスのメソッドに則るために、そういうふうにしないとならないみたいなシチュエーションは当然あったが、このC言語のメイン関数の仕様はそれより厳格な規約というか、制限に思えた。

2.コマンドライン引数はメイン関数で取得、という厳密なルール

他言語では、コマンドライン引数を受け取るAPIが用意されていて、そのAPIを使用すればどの箇所でも呼べるが、どうやら調べた感じC言語ではメイン関数で取得するというルールになっているようだった。ちなみにさっと調べた他言語でのAPIの例は下記となっている。

Node.js
https://nodejs.org/docs/latest/api/process.html#process_process_argv

Go
https://golang.org/pkg/flag/

感想

なぜこのようにC言語はコマンドライン引数をメイン関数で取得する設計になっているのか、いずれは知りたい。

Article Tags
mmiyauchi

プログラムを書きながらTranceを聴くのが良いですね。みなさんも聴いたほうがいいですよ、Trance。EDMよりハードトランスでしょ。

Related article

Redux(react-redux)における適切な配列要素の更新

2021年8月23日…

CloudFlareの『SSL/TLS 暗号化モード(HTTPS通信設定)』を使用したとき、『ERR SSL VERSION OR CIPHER MISMATCH』のエラーでChromeで発生し、接続できない場合の対処

英語の記事は見当たっ…

Dart(Flutter)についての所見

Dart(Flutter)についての所見

第一印象では、クロス…

Discussion about this post

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください

Type your search keyword, and press enter to search