C言語関係掲示板

過去ログ

No.378.文字列を反転するプログラム

[戻る] [ホームページ]
No.2513

コメント追加のお願いです。
投稿者---すず(2002/08/27 11:09:12)


こんにちは。すずです。
ともじさんに、またコメントの追加をお願いがあって投稿しました。

追加してほしい場所は、
10-2(2)のところにある演習問題の、問3の解答例です。

while ( *p1!='\0' ) { /* 文字数算出 */
p1++;
}
p1--;
while ( p1 >= str1 ) {
*p2 = *p1;
p1--;
p2++;
}
*p2='\0'; /* NULを付加 */

この部分の、 /* 文字数算出 */ 
というところの作業の意味がわかりません。
なぜこのようなことをしているのですか?
あと、その次のwhileループの作業の意味がわかりません。
お手数ですが、宜しくお願いいたします。



No.2520

Re:コメント追加のお願いです。
投稿者---かずま(2002/08/27 15:22:04)


> この部分の、 /* 文字数算出 */ 
> というところの作業の意味がわかりません。
> なぜこのようなことをしているのですか?

コメントが不適切です。「文字列の最後を探す」ぐらいでしょうか。
文字列については、「2-4.文字と文字列」をよく読んで理解してください。

> あと、その次のwhileループの作業の意味がわかりません。

コメントを書いてもわからないでしょう。図を書いてみましょう。

それから、この while ループは、規格上は許されない書き方です。
while ループを抜けるとき、p1 < str1 となっているはずですが、
ポインタは配列の先頭より前を指してはいけないことになっています。
でも、実際には、ほとんどすべての処理系で問題なく動きます。
次のように書けば、この問題を回避できます。
    /* p1--; ここでデクリメントしない */
    while ( p1 > str1 ) {
        p1--;
        *p2 = *p1;
        p2++;
    }


No.2522

Re:コメント追加のお願いです。
投稿者---ともじ(2002/08/27 17:50:37)


申し訳ありません。実は不適切なことに気が付いていたのですが
日々の多忙さにすっかり直し忘れていました。

罪滅ぼしに、図を描いてみました。

#include <stdio.h>

int main(void)
{
        char str1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
        char str2[30];
        char *p1, *p2;
        
        p1 = str1;
        p2 = str2;
        
        while (*p1!='\0')       /* (1)p1をstr1の最後まで更新 */
                p1++;
                
        while (p1 > str1) {     /* p1がstr1を指す間ループ */
                p1--;           /* (2) */
                *p2 = *p1;      /* (3)p2の指すところにp1の指す値を代入 */
                p2++;           /* (4) */
        }
        *p2 = '\0';             /* (5)'\0'の付加 */
        
        printf("str1 = %s\n", str1);
        printf("str2 = %s\n", str2);

        return (0);
}



ちなみにポインタは配列+1は指せます。


No.2528

ありがとうございました。
投稿者---すず(2002/08/28 10:48:24)


>罪滅ぼしに、図を描いてみました。

おはようございます。すずです。
コメントだけでなく、図まで描いて頂いて、本当にありがとうございます。
大変わかりやすく、とても助かりました。

かずまさんも、適切な指導、ありがとうございました。
お二方のご教授ののおかげさまで、ポインタの理解に一歩前進できたような気がしはじめてきました。
本当にありがとうございました。

No.2529

Re:コメント追加のお願いです。
投稿者---かずま(2002/08/28 11:34:39)


> 10-2(2)のところにある演習問題の、問3の解答例です。

ポインタをデクリメントすることなしに、文字列を反転するプログラムです。
再帰呼び出しを使っているので、時間とメモリーを無駄に使いますが、
お遊びですので、面白いと思う人は、面白いと思ってください。
#include <stdio.h>

char *rev(const char *p1, char *p2)
{
    if (*p1 == '\0') return p2;
    p2 = rev(p1 + 1, p2);
    *p2 = *p1;
    return p2 + 1;
}

int main()
{
    char str1[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char str2[30];

    *rev(str1, str2) = '\0';
    printf("str1 = %s\n", str1);
    printf("str2 = %s\n", str2);
    return 0;
}