第28回
データ構造(7)~ポインタの配列とポインタのポインタ

ポインタの配列とポインタのポインタ

先に紹介したコマンドライン・パラメータを扱うための「ポインタの配列」は「ポインタのポインタ」としても扱えることになります。

示す先はどちらも同じ

「第26回 データ構造(5)~ポインタを使った文字列処理関数を作る」で紹介した『配列はポインタを介することで効率的に扱える』というメリットを思い出してください。

「ポインタのポインタ」と、言葉で表現すると何だか難しい印象を受けますが、「ポインタの配列」の「配列」の部分をポインタを介して扱う──ということです。

main関数の第2引数を“*argv[]”と記述してきましたが、これは“**argv”と記述することも可能です。[]を使えばポインタの配列、**とすればポインタのポインタとなりますが、その指し示す先はどちらの場合も同じです。

ポインタのポインタとして扱う

図3は、先のポインタの配列に対して、その先頭アドレス(=配列名)をポインタとして扱った場合の表現です。これが、ポインタのポインタです。このようにすれば、先の“search”のパラメータは、以下のようにして取り出せます。

代入式に注目してください。文字列を扱うためのポインタ変数filenameとwordの先頭には*が付いていませんが、=の右(右辺式)にあるargvの先頭には*が付いています。これは、各パラメータを示す文字列の配列をポインタとして扱っているためです。

演算子の優先順位により、
*(argv+1)
のようにargvに1を加算した値に対して*でアドレスを取り出しています。

このソースを単独のプログラムとしたものを、サンプルに“ex2802.c”として収録しておきます。

  char *filename, *word;
  filename = *(argv+1);
  word = *(argv+2);


パラメータをすべて加算するプログラム

コマンドライン・パラメータを取得する例として、以下のようなプログラムを作ってみましょう。

・仕様
入力されたコマンドラインパラメータを数値とみなし、すべてを加算してその答えを表示する。

・プログラム名
addall

・書式例
addall 1 2 3 4 5

・出力
answer : 15

コマンドラインパラメータをポインタの配列として扱えば、リスト1のようなソースが考えられます。ポインタのポインタとして扱えば、ポインタ変数のインクリメントを使ってリスト2のように記述できます。

atoi関数は引数に指定した文字列をint型の整数に変換します。数値以外の文字列は0に変換されます。この関数を使うには“stdlib.h”を取り込まなければなりません。

・atoi関数の宣言
int atoi(const char *str);

リスト1:ポインタの配列を使ってパラメータを取り出すプログラム(ex2803.c, ex2803.exe)
#include <stdio.h>
#include <stdlib.h>

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

  ans = 0;
  for (i=1; i<argc; i++) {
    ans += atoi(argv[i]);
  }

  printf("addall = %d\n", ans);
  return (0);
}

リスト2:ポインタのポインタを使ってパラメータを取り出すプログラム(ex2804.c, ex2804.exe)
#include <stdio.h>
#include <stdlib.h>

int main(int argc, char ** argv)
{
  int i, ans;

  ans = 0;
  argv++;
  for (i=1; i<argc; i++) {
    ans += atoi(*argv++);
  }

  printf("addall = %d\n", ans);
  return (0);
}

あとがき

hiropの『ちょっと気になる専門用語』~《引数》

ユーザーがプロンプトに対して与える『プログラムへの指示』を、本文では「コマンドライン・パラメータ」と表記しました。この他に「コマンドライン・オプション」という表記もよく目にします。

基本的に、どちらも同じ意味です。ただ厳密に言えば、言語的に以下のような違いがあります。

・パラメータ(parameter)
動作の仕方などを指示するもので、省略はできない。
数学では「媒介変数」など、統計学では「母数」など。

・オプション(option)
動作の指示が必要な場合に追加するもので、省略可能。
「選択肢」「付加機能、付加部品」など。

このように、パラメータは数値的な、オプションは付加的なニュアンスを持っています。つまり
パラメータはプログラムに対して
 どの程度処理するのか
オプションは
 どのように処理するのか
を指示するものだと言えるでしょう。

しかしコンピュータでは、コマンドラインに入力された文字列──プログラムへの指示に関して、そこまで厳密に規定されているわけではありません。

コンピュータとかプログラムとかと言えば、なんだか非常に厳密な仕組みのような気がします。もちろん、プログラムは厳密な仕組みなのですが、それを扱う人間の側に対しては、「どのようにも受け取れる」曖昧な解釈が存在します。用語に関しては、案外『どんぶり勘定的』なのです。