第7章 C言語のポインタ2 ~charポインタとchar配列~
休憩室
今回のトピックスは、あまり休憩にならないかもしれません。
char 配列と char ポインタの続きになります。
全員が理解していなくても構いませんが、余裕のある人には是非知っておいて欲しいことです。
かなり難しいことも出てきますので、今のところ完全には理解できなくて当たり前のことです。
まず最初は、char 配列の初期化と、char ポインタについてです。
-- リスト20 --
#include <stdio.h>
#include <string.h>
void main()
{
char array[7] = "abcdef"; /* char配列の初期化 */
char *ptr = "ghijkl"; /* charポインタの初期化 */
printf("array = %s\n", array);
printf("ptr = %s\n", ptr);
}
変数の宣言時にいきなり、文字列を代入していますね。
わざわざ関数 strcpy を使うよりも、このような記述の仕方で、文字列をコピーしてくれます。
とっても便利ですね。
しかし、これは変数の初期化の時だけしか使えません
(C++やJava言語になると、いつでもこのような文字列の代入ができます)。
また、以下のように数字を省略して記述しても、
Cコンパイラが自動的に、char 配列の大きさを7個にしてくれます。
char array[] = "abcdef"; /* char配列の初期化 */
通常は、このような書き方が一般的です。
何故なら、文字列の長さが変わったとしても、[7]を[8]に変更したりする手間が省けるからです。
次に、ポインタ演算についてです。さっそく、次のように変更してみてください。
-- リスト20` --
#include <stdio.h>
#include <string.h>
void main()
{
char array[7] = "abcdef"; /* char配列の初期化 */
char *ptr = "ghijkl"; /* charポインタの初期化 */
int cnt;
/**
* char配列を、一文字ずつ表示する
*/
printf("char配列を、一文字ずつ表示する\n");
for (cnt = 0; array[cnt] != '\0'; cnt++) {
printf("%08X %c\n", &array[cnt], array[cnt]);
}
/**
* charポインタを、一文字ずつ表示する
*/
printf("charポインタを、一文字ずつ表示する\n");
for (cnt = 0; *(ptr + cnt) != '\0'; cnt++) {
printf("%08X %c\n", ptr + cnt, *(ptr + cnt));
}
}
赤字部分がポインタ演算です。
ポインタに対して、普通の数値と同様に加算をしていますね。
これは、仮に prt の箱の中に 0012ff3c というアドレスが入っているとすると、
(0012ff3c + 0)、(0012ff3c + 1)、(0012ff3c + 2)...という具合に
アドレスが加算されているということです。
もちろん、ポインタに対して他の演算を行うこともできますが、
よく使われるのは++演算子くらいで、他はあまり使いません。
以下は、char ポインタに対して、++演算子を使った例です。
-- リスト20`` --
#include <stdio.h>
#include <string.h>
void main()
{
char array[7] = "abcdef"; /* char配列の初期化 */
char *ptr = "ghijkl"; /* charポインタの初期化 */
int cnt;
/**
* char配列を、一文字ずつ表示する
*/
printf("char配列を、一文字ずつ表示する\n");
for (cnt = 0; array[cnt] != '\0'; cnt++) {
printf("%08X %c\n", &array[cnt], array[cnt]);
}
/**
* charポインタを、一文字ずつ表示する
*/
printf("charポインタを、一文字ずつ表示する\n");
for (; *ptr != '\0'; ptr++) {
printf("%08X %c\n", ptr, *ptr);
}
}
赤字部分が、なかなかすっきりしたように見えるかもしれません。
しかしこれだと、ポインタ変数である ptr が指している場所は、少しずつ移動しています。
ですから、文字列を二回表示することはできません。
char ポインタに対して++演算子を使うことは、文字列を検索したり置換したりする時など、
ごく限られた時のみです。
最後に、リスト20を以下のように変更してみてください。
-- リスト20``` --
#include <stdio.h>
#include <string.h>
void main()
{
char array[7] = "abcdef"; /* char配列の初期化 */
char *ptr = "ghijkl"; /* charポインタの初期化 */
int cnt;
/**
* char配列を、一文字ずつ表示する
*/
printf("char配列を、一文字ずつ表示する\n");
for (cnt = 0; array[cnt] != '\0'; cnt++) {
printf("%08X %c\n", &array[cnt], array[cnt]);
}
/**
* charポインタを、一文字ずつ表示する
*/
printf("charポインタを、一文字ずつ表示する\n");
for (cnt = 0; *(ptr + cnt) != '\0'; cnt++) {
printf("%08X %c\n", ptr + cnt, *(ptr + cnt));
}
/**
* char配列をcharポインタ同然に扱い、一文字ずつ表示する
*/
printf("char配列をcharポインタ同然に扱い、一文字ずつ表示する\n");
for (cnt = 0; *(array + cnt) != '\0'; cnt++) {
printf("%08X %c\n", array + cnt, *(array + cnt));
}
/**
* charポインタをchar配列同然に扱い、一文字ずつ表示する
*/
printf("charポインタをchar配列同然に扱い、一文字ずつ表示する\n");
for (cnt = 0; ptr[cnt] != '\0'; cnt++) {
printf("%08X %c\n", &ptr[cnt], ptr[cnt]);
}
}
なんだか、char 配列であるはずの array も、
char ポインタであるはずの ptr も全く同じように扱えるようですね。
確かに char ポインタは、初期化されていないと危険です。
しかし、初期化された char ポインタは、char 配列と何ら変わりがないのです。
以上です。かなり、難しいトピックスでしたので、理解できなくても落ち込まないでください。