コード:
void back(char *str1, int n, char *str2)
{
int i;
for (i = 0; i < n; i++) {
str2[i] = str1[strlen(str1) - 1 - i];
}
str2[i] = '\0';
}
具体的な例で説明する方がわかりやすいと思います。
まず、back関数の仕様は、第1引数str1の後ろの方から第2引数n文字分だけ取ってきて
第3引数str2に格納する、というものです。
例えば、str1が"abcdefg"で、nが3だとします。このとき、str2に入ってほしいのは"gfe"ですね。
str2には3文字分(=n文字分)だけ入ってほしいので、ループを3回(=n回)回します。これが、
29行目(すぐ上のコードでは5行目)の意味です。
さて、back関数の肝は30行目(すぐ上のコードでは6行目)にあります。
ここで、str1の長さは7であることを覚えておいてください。
str1とnを用いてstr2にどういう風に格納しているかというと、
・str2[0]には、str1[6]であるところの'g'を格納する
・str2[1]には、str1[5]であるところの'f'を格納する
・str2[2]には、str1[4]であるところの'e'を格納する
ということを行なっています。
格納先の[0]には元の文字列の[6]を格納
格納先の[1]には元の文字列の[5]を格納
格納先の[2]には元の文字列の[4]を格納
という規則で動いています。
ここで、[0]と[6]、[1]と[5]、[2]と[4]という組合せについて、何か規則性を見いだせないでしょうか。
いずれの場合も、加えると6になっていて、6というのは元の文字列の長さである7より1だけ小さいのです。
上記を一般化すると、
格納先の
には元の文字列の[元の文字列の長さ - 1 - i]を格納
ということになり、これをC言語で書いたのが30行目(すぐ上のコードでは6行目)です。
for文のループを抜けたときのiの値はnに等しく、3になっています。
str2[0]~str2[2]には正しい結果が入っていますので、str2を文字列として
正しく終端させるためにstr2[3]に'\0'を格納します。これが32行目(すぐ上のコードでは8行目)です。