こんにちは､ そしてお帰りなさい｡ ポインターをもう少し詳しく理解したところで､ 文字ポインターについて､
主に文字列を表現するために文字ポインターをどのように使用するかについてお話したいと思います｡
文字列は､ 文字配列､ 複数文字､ 単語です｡
これで､ ポインタ演算の概念において､ 配列とポインタがどのように関係しているかがわかりました｡
とても､ 便利なコンセプトですね｡
これらの概念は､ 文字列の配列に適用すると､
非常に便利です｡
配列へのポインタを使用する最も一般的な用途の1つは､ 文字列へのポインタとして使用することです｡
その理由は､ 表記上の利便性と効率性の1つです｡
そのため､ charへのポインタ型の変数を使用して文字列を参照することで､
非常に柔軟な対応が可能となります｡
そこで､ 文字配列よりも文字ポインタをできるだけ使おうとするわけですが､
具体的には文字ポインタを使って関数にデータを渡します｡
そんな素敵なことがいろいろあるんです｡
そこで､ 配列を使って文字列をコピーする例を見てみましょう｡
この例では､ 配列のパラメータは文字配列になります｡
それは関数宣言の中にちゃんと書いてあります｡
これを文字ポインタを受け取る関数と比較して､ 文字ポインタ関数の方がずっと効率的であることを示したいと思います｡
この例では､ 配列を受け取る関数とポインターを受け取る関数の2つを用意しています｡
最初の関数copy stringでは､
for loop I equals zero from sub Iを使って配列全体を通過させ､
NULL文字列が見えるまでずっと進み､ ループ制御変数をインクリメントします｡
そして､ サブIから2サブIイコールと言うだけでいいのです｡ そこでは､ 直接配属をやっているんです｡
そして最後に､ NULL文字が表示されるまでずっと処理を続けた後､
NULL文字をto配列の末尾に追加します｡
では､ ポインターを使うときはどうするのか見てみましょう｡
まず､ コピー文字列の関数宣言として､ char star から char start
from とだけ言って､ to pointers を宣言します｡
forループでは､ ポインタがあるので実際に変数を宣言する必要はなく､
fromがヌル終端を打つまで反復するだけでよいのです｡
そして､ fromとtoの両方のポインタをインクリメントすることができます｡
なぜなら､ ここでは点数計算をしているからです｡
ポインタのアドレスを1つ増やすことで､ 次の文字を取得しているのです｡
そして､ 次のforループの行では､ ポインタが指す実際の値､
つまり実際の文字をtoポインタに代入したいので､
toとfromの両方を非参照にしているだけです｡
そして最後に､ toポインタの指す先にnull文字を追加します｡
これはfromの文字列の最後のアドレスになりますが､
現在はtoアドレスを指しています｡
見た目はそれほど悪くない｡ つまり､ forループがあるんですね｡
基本的にコードの行数は同じなんですね｡
でも､ 構文が違うでしょ？
添え字を使わず､ ポインターを使うなら､ アスタリスクを使え｡
これも表記上の便宜的な問題です｡
ここに大きなアドバンテージがあるとは思えませんね｡
しかし､ 実はポインターを使うと､ もっと最適化してコードを少なくすることさえできるのです｡
つまり､ char配列をポインタとした場合､
textという文字の配列があれば､ 同様にポインタを定義して､ textの要素を利用することができるのです｡
つまり､ ここでは､ char star text pointer
と言って､ 文字ポインタを定義しているのです｡
テキストポインタがテキストという文字列の配列の先頭を指すように設定されていれば､
これらのプリインクリメントとポストインクリメントの演算子を使って､
1つずつインクリメントすればよいのです｡
つまり､ この上のプラス・プラス・テキストポインタは､ テキストの次の文字（テキストサブ1）を指しているテキストポインタを設定することになります｡
つまり､ 整数の場合と同じように次のレイを探したければ､
1 2を足せば次の文字が得られるというわけです｡
しかし､ 文字配列の場合は､ 1文字ずつ簡単に操作できるため､
より便利です｡
テキストポインタをマイナスにする（デクリメント演算子）と､ テキストポインタがテキストの先頭を指していなかったと仮定して､
ポインタはテキストの前の文字に設定されます｡
なぜなら､ もしそうなら､ このようなアンダーバウンズエラーが発生するからです｡
文字列の末尾にプラスプラスしていたら､ out of boundsエラーになります｡
整数の演算と同じように､ 配列の境界を超えないように常に注意する必要があります｡
しかし､ 非常に単純で､ 整数ポインタ演算をするときに非常に密接に関係します｡
文字ポインタ演算も同じことです｡
ただ､ 実際に添え字を使わずに個々の文字を見ることができるようになったので､ さらに便利になりました｡
そこで､ 先ほどの例を見てみると､ 実はポインターを使うことでもう少し最適化でき､
さらに少ないコード行数で済ませることができます｡
コピーした文字列の中で､ この関数宣言は前と同じで､ アスタリスクを使って2つのポインタを作成します｡
というのも､ 前の例ではループ制御変数を初期化する必要がなかったので､
forループを使うのはちょっと無意味だったからです｡
必要なのは､ ある条件でループを抜けることだけで､
実際にはforループの中でインクリメントとデクリメントの演算子を使っていますが､
それすら必要ないんです｡
というのも､ whileループを使えば､ null文字を指している場合､
そのnull文字は実際には0に等しいので､ whileループを見るだけで､
ジャンプすることができるからです｡
whileループでは､ cのブール変数は整数で表され､
1が真で､ 0が偽､ あるいは本当に0が偽で､ それ以外が真となることを思い出してください｡
この場合､ 偽であるヌル文字0が飛び出すことになります｡
つまり､ whileループの終了条件には､ からアスタリスクを付ければいいのです｡
その文字の値が何であるかを確認するために､ 何からデリファレンスしているのだろう｡
だから､ コピーしたい文字列の末尾まで来たら､ ジャンプアウトする｡
そうでなければ､ 実際にポインタの修正をそこに入れるだけです｡
プラス・プラスから2プラス・プラスです｡
さて､ これはポストインクリメント演算子です｡
つまり､ これはどういうことかというと､ プラス・プラスは変数の右側にあるということです｡
そして､ こうすると､ 文が終わってからでないと､
1つも追加しないということになります｡
つまり､ スター2イコールスタートということになります｡
そして､ その文が終わった後､ 2 1に加算され､ 1からも加算されることになるのです｡
もし変数名の前にプラスを付けていたら､ そのステートメントを実行する前にその変数に追加されてしまい､
本質的に文字列の最初の要素がコピーされるのを見逃してしまうので､ 問題です｡
しかし､ これ以上のコード行は必要ない｡ 実際にインクリメントポインタの演算と代入を同じ文の中で行っているので､
コードを1つ減らしています｡
ここでも､ 表記は非常にシンプルです｡
整数演算の割り当てをいとも簡単にやっている｡
そして最後に､ すべての文字列をコピーし終えたら､
最後にヌル文字をポインタに追加して参照解除します｡
だから､ ここはちょっとだけきれいになっているんです｡
ポインタの威力､ そしてポインタと算術を同じラインで使うことができること､
さらにインクリメントとデクリメント､ プラスとマイナスの演算子を使えば､
より速く簡単に､ より効率的に処理できることがわかります｡
もし､ これらのコピー文字列の関数を使いたければ､ 2つの文字配列を作ればよいのです｡
0の文字配列はポインタなので､ コピー文字列に直接渡すことができます｡
これらはポインターなので､ 実際に参照を解除したり､ アドレスを追加したりする必要はありません｡
文字列2､ 文字列1って言えばいいんだよ｡
そして､ これは何をするかというと､ コピーする文字列をstring2文字配列にコピーして､
printfを使って出力します｡
文字配列の代わりに文字ポインタを使う方法と､ なぜそれが好まれることがあるのか､
その例を見て行きたいと思います｡
Fortranのような以前の言語でプログラミングをしたことがある人なら､ raiseに慣れているかもしれませんが､
これはプログラマーの好みであると述べました｡
しかし､
それがあれば､ ポインターを使うことの利点がわかるはずです｡
参考になれば幸いです｡ ありがとうございます｡