対象読者
- C++のポインタの理解が曖昧で理解しておきたい人
ポインタを理解する
ポインタとは
なんらかのオブジェクトを指し、オブジェクトを参照するためのもの
ポインタの宣言
char *ptr;
でptr
がchar型の値*ptr
のポインタであることになる。(「char型の値だよ、*ptr
は。つまり、*
をとったptrはそのポインタだよ。」と捉えられる。)
char* ptr;
と宣言しても同じことである。(char*
が「char型のポインタだよ、ptr
は。」と宣言してると捉えられる。)
ポインタの初期化
ptr
が、char型変数xを指す場合は、以下のように初期化できる。
char x;
char* ptr = &x;
char x;
char* ptr;
ptr = &x;
どちらの書き方でもよい。
変数ptrに実際に、xのアドレスの値が入っている。
そのptrのアドレスが指すもの(すなわちx)を取るには、
*ptr;
とすれば良い。
理解確認問題
問題
非常にありきたりな問題ですが、ポインタの理解をするのにちょうど良いです。
reverse(char* str)
という¥0
終端の文字列を逆に並び替える関数を実装せよ。
解法
"abcde"という文字列がインプットとして与えられるとして、考え方は以下です。
ポインタのアドレスを用いてメモリ上の値を実際に更新していくため、このアルゴリズム終了時点で、そのinputに入れた値自体が更新されていることになります。(したのコードでいう、char[][]
自体の値が、更新されているということ)
実装例
#include<iostream>
class Question
{
public:
static void reverse(char *str)
{
char* end = str;
char tmp;
if (str == nullptr)
{
return;
}
// 終端のnull文字時点でストップする
while (*(end+1))
{
++end;
}
// 2つのポインタがで会うまで、
// ポインタの箇所の値を交換していく
while (str < end)
{
tmp = *str;
*str = *end;
*end = tmp;
++str;
--end;
}
}
static int run()
{
char input[][10] = { "abcde", "cat" };
for (int i = 0; i < 2; i++)
{
std::cout << "reversing the string: " << input[i] << std::endl;
reverse(input[i]);
std::cout << "reverse of input string is " << input[i] << std::endl;
}
return 0;
}
};
int main()
{
Question::run();
}