質問: 課題について質問です。 以下の関数は何を行うものなのかがよくわかりません。 ``` int pal(char *s) { char *t=s; while (*t!='\0'){ t++; } t--; while (s<=t){ if(*s!=*t){ return 0; } s++; t--; } return 1; } ``` 自分の考えでは、大文字を小文字に,小文字を大文字に変えるプログラムだと思ったのですが、(例 `pal("abcxyz")`->ABCXYZ)違いますか。
回答: 大文字を小文字に、小文字を大文字に変える関数ではないです。ではどのような関数でしょうか。この回答では挙動を確かめるやり方のひとつを紹介します。 まず関数の型を見ると、文字列 `char *` を受け取って整数 `int` を返しています。 ``` int pal(char *s) ``` 続いて関数の中身を見ると、色々と処理をしつつ最終的に `0` か `1` を返しています。まずはこの `0` と `1` が何なのかを考えることが理解に繋がりそうです。 この関数は危険な関数では無いので、実際に実行してみて挙動を確かめてみてください。たとえば下のような感じです。 ``` #include #include int pal(char *s) { ... } int main(void) { char *input = malloc(128); int result; sprintf(input, "%s", "abcde"); /* ここを色々と変えて挙動を確かめる */ result = pal(input); printf("input: %s\nresult: %d\n", input, result); free(input); return 0; } ``` `"abcde"` と書かれている部分を "abcd" とか "abcba" とか "aaaa" とか変えてみて、出力がどう変わるか確かめてみてください。もしかしたら挙動が推測できるかもしれません。 その上でもう一度ソースコードを見て、どういう動き方をしているのか 1 行 1 行確認してみてください。 キーポイント: * 最初の `while` ループではポインタ `t` が指し示している場所をずらしています。C 言語の文字列は最後に `\0` が入っているので、ここでは `t` を `s` の最後の 1 バイト (`\0` の直前のバイト) まで動かしています。 * 2 つ目の `while` ループが鬼門です。与えられた文字列の先頭を指しているポインタ `s` と、末尾を指しているポインタ `t` を同時に動かしています。1 回のループで、`s` は次のバイトに進み、`t` は前のバイトに戻ります。ただしもしその指し示している先が異なるバイトであれば、即座に `return 0` です。最終的に `s` が `t` を追い越せば (`s <= t` を満たさなくなれば) ループは終わりです。つまり、文字列の真ん中まで来たら終わりです。 + よく分からなければ、実際に紙の上に手で `s` と `t` がどうなっているのかを書いてみて、挙動を確認してみてください。ループが 1 回まわるごとに、どのように動いているでしょうか。 答え合わせのために、結局 `pal` は何をする関数なのかを隠して書いておきます。 > > 関数 `pal` は、与えられた ASCII 文字列 `s` が回文であれば `1` を、そうでなければ `0` を返す関数です。`pal` というのは「回文」を表す英単語 "palindrome" から取ったのでしょう。 > > >