0

逆関数へのポインタを使用すると、逆関数を呼び出そうとするとエラーが発生し、それを出力します。ポインタ送信エラーメッセージ。だから私はいくつかのコードを変更しようとしましたが、それは無力です.

#include <string.h> 
#include <stdio.h>

char *strrev(char *str)
{
    char *p1, *p2;

    if(!str) {return NULL;}
    printf("%s",__LINE__); //checking
    for (p1 = str, p2 = str + strlen(str) - 1; p2 > p1; ++p1, --p2)
    {
        *p1 ^= *p2;
        *p2 ^= *p1;
        *p1 ^= *p2;
    }
    printf("%s",str);  //checking
    return str;
}

int main(void)
{
    char *str ;
    printf(" Please enter string \n");
    scanf("%s",&str);
    printf("%s\n", strrev(*str));
    return 0;
}
4

2 に答える 2

4
char *str ;
scanf("%s", &str);
  1. にメモリを割り当てることはありませんstr。試してみるmallocか、もっと良いのは、最初に配列を使用することです
  2. ライン&からをドロップする必要がありますscanf
于 2012-05-07T03:21:27.720 に答える
2

そこにはかなりの問題があります。

1/まず、文字列にストレージを割り当てません。char str[128];これは、サイズ要件に応じて簡単に修正できます。これはまた、NULL チェックが不要であることを意味し、後で NULL ポインターを出力する (または出力しようとする) ことを心配する必要はありません。これが明示的に禁止されるように関数契約を変更してください。

2/次に、絶対に使用しないでください(つまり、無制限の文字列書式指定子を使用して)。これscanf("%s")は、バッファ オーバーフローの問題を簡単に引き起こします。オーバーフロー チェックを備えた堅牢な入力関数が必要な場合は、この回答を参照してください。

いずれにせよ、は行ではなく単語%sをスキャンするので、 (スペースを入れて) 入力すると が表示されます。"Hello Pax"Hello

3/第三に、strが の場合char**str文字であり、C 文字列ではありません。ではなく、strに渡す必要があります。これは、上記のポイント 1 の修正があっても当てはまります。strrev*str

4/マクロは整数型に展開されるため、書式指定子__LINE__に従って文字ポインターとして扱われることは好ましくありません。代わり%sに使用することもできます。%d

5/ ISO 規格では、C11strにあるように、小文字で始まるすべての名前を独自の使用のために予約しています。7.31.13 Future library directions実際strrevには良い考えではありません。

6/最後に、XOR-swap トリックは時代錯誤であり、今日の現代環境には存在しません。一時変数ソリューションの単純な動きではなく計算を考えると、それは不要であり、遅くなる可能性があります。変数にスワップする正しい方法は次のとおりです。

int t = a;
a = b;
b = t;

自分に有利に働き、そのトリックを捨ててください。ダフのデバイスと同じバケットに属します:-)


他にもいくつかの問題がありますが、プログラミングを教えてきたかなりの年数に基づいて、これは他の何よりも文体的です (私はこのスタイルが好きです)。

7/私が遭遇したほとんどの人は、任意のメモリ位置よりも文字列内の文字について考える方が簡単であるため、ポインターよりも配列インデックスを理解しやすいと感じています。ベテランの C プログラマーは、違いがないことを知っています (機能と、今日のコンパイラーのパフォーマンスの両方の点で)。したがって、次のように、ポインターではなくインデックスを使用する傾向があります。

char *reverseStr (char *str) {
    char tmpchar;
    int front = 0;
    int back = strlen (str) - 1;
    while (front < back) {
        tmpchar = str[front];
        str[front++] = str[back];
        str[back--] = tmpchar;
    }
    return str;
}

8/frontまた、別のことにbackも気付くでしょうtmpchar。コンパイラは、(妥当な範囲内で) 識別子の大きさを気にしません。これにより、コードがはるかに読みやすくなります。

于 2012-05-07T03:50:05.753 に答える