62347


課題について質問です。  
以下の関数は何を行うものなのかがよくわかりません。

[code]

    int pal(char *s)
    {
        char *t=s;
        while (*t!='\0'){
            t++;
        }
        t--; 
        while (s<=t){
            if(*s!=*t){
                return 0;
            }
            s++;
            t--;
        }
        return 1;
    }
    
[/code]

自分の考えでは、大文字を小文字に,小文字を大文字に変えるプログラムだと思ったのですが、（例 `pal("abcxyz")`->ABCXYZ)違いますか。


CC BY-SA 4.0
2020-01-18T07:01:17.517
62345
2020-01-18T08:36:35.153
2020-01-18T08:00:47.867
19110
36412
question
c
何をする関数なのか分からない


課題ということですので、１行１行の説明をします。

3行目 ポインターtにｓを代入しているので、この時点でsとtは同じになります。  
4行目から7行目 文字列の終わりまでtを進めています。結果として文字列の最後を示しています。  
8行目から14行目
sの値とtの値を比較し、不一致の場合0を返します。一致していた場合はｓの頭から次の文字、ｔの最後から一つ前の文字を比較します。それを真ん中の文字まで繰り返します。  
不一致が一つも無い場合、while文を抜けます。  
最後に１を返します。


CC BY-SA 4.0
2020-01-18T07:58:59.207
62346
2020-01-18T08:06:01.447
2020-01-18T08:06:01.447
24490
24490
62345
answer


大文字を小文字に、小文字を大文字に変える関数ではないです。ではどのような関数でしょうか。この回答では挙動を確かめるやり方のひとつを紹介します。

まず関数の型を見ると、文字列 `char *` を受け取って整数 `int` を返しています。

[code]

    int pal(char *s)
    
[/code]

続いて関数の中身を見ると、色々と処理をしつつ最終的に `0` か `1` を返しています。まずはこの `0` と `1`
が何なのかを考えることが理解に繋がりそうです。

この関数は危険な関数では無いので、実際に実行してみて挙動を確かめてみてください。たとえば下のような感じです。

[code]

    #include <stdio.h>
    #include <stdlib.h>
    
    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;
    }
    
[/code]

`"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" から取ったのでしょう。


CC BY-SA 4.0
2020-01-18T08:36:35.153
62347
2020-01-18T08:36:35.153
19110
62345
answer