0

私のプログラムの実行に非常に長い時間がかかる理由、このプログラムはユーザーパスワードをチェックすることになっています。文字列が等しい場合はゼロ、等しくない場合はゼロ以外

  #include<stdio.h>
  char str_cmp(char *,char *);
  int main(void)
  {
      int i=0;
      char c,cmp[10],org[10]="0123456789"; 
      printf("\nEnter your account password\ntype 0123456789\n");
      for(i=0;(c=getchar())!=EOF;i++)
      cmp[i]=c;
      if(!str_cmp(org,cmp))
      {
          printf("\nLogin Sucessful");  
      }
      else
          printf("\nIncorrect Password");
  return 0;
  }
  char str_cmp(char *porg,char *pcmp)
  {
    int i=0,l=0;
    for(i=0;*porg+i;i++) 
    {
        if(!(*porg+i==*pcmp+i))
        {
          l++;
        }        
    }
  return l;
  }
4

2 に答える 2

3

これをはるかに簡単に行うためのライブラリがありますが、これは課題であり、いずれにせよ良い学習経験になると思います。str_cmp 関数の for ループに問題があると思います。使用している条件は「*porg+i」です。これは実際に比較を行っているわけではありません。コンパイラーがやろうとしているのは、式が 0 に等しくなるまで行くことです。これは、i が非常に大きくなり、*porg+i が "int" が格納できるものよりも大きくなり、0 にリセットされると発生します (これを 0 と呼びます)。変数のオーバーフロー)。

代わりに、文字列の長さに対応するサイズを str_cmp 関数に渡す必要があります。for ループ条件では、i < str_size であることを確認する必要があります。

ただし、これとまったく同じことを行う組み込みの strncmp 関数 ( http://www.elook.org/programming/c/strncmp.html ) があります。

また、別の問題があります。次のようにポインタの追加を行っています。

*porg+i

これは、配列の最初の要素の値を取得し、それに i を追加します。代わりに、次のことを行います。

*(porg+i)

それはポインタに追加され、それを逆参照して値を取得します。


これはポインターにとって非常に重要な概念であるため、比較をより完全に明確にするために。porg は char* として定義されます。これは、「char」のメモリアドレスを持つ変数があることを意味します。変数に対して逆参照演算子 (*、たとえば*porg) を使用すると、そのメモリに格納されている値が返されます。ただし、メモリ ロケーションに番号を追加して、別のメモリ ロケーションに移動することはできます。porg + 1porg の後にメモリ位置を返します。したがって、実行*porg + 1すると、メモリアドレスの値が取得され、それに 1 が追加されます。一方、あなたがするとき*(porg + 1)porgが指しているメモリアドレスの1つ後に値を取得しています。配列は値を次々に格納するため、これは配列に役立ちます。ただし、これを行うためのよりわかりやすい表記法は次のとおりporg[1]です。これは、「配列の先頭の後に値 1 を取得する」、つまり「配列の 2 番目の要素を取得する」ことを意味します。

C のすべての条件は、値がゼロか非ゼロかをチェックしています。ゼロは false を意味し、その他の値はすべて true を意味します。この式 ( *porg + 1) を条件に使用すると、計算 (porg の値 + 1) が実行され、それがゼロかどうかがチェックされます。

これは、C でプログラミングするためのもう 1 つの非常に重要な概念につながります。int は、特定のサイズまでの値しか保持できません。変数がその最大値よりも大きい場所に十分に追加されると、0 に循環します。したがって、int の最大値が 256 であるとしましょう (実際にははるかに大きい)。値が 256 の int に 1 を加えると、257 ではなくゼロになります。実際には、ほとんどのコンパイラで最大数は 65,536 であるため、時間がかかるのはこのためです。*porg + i が 65,536 を超えて再びゼロになるまで待機します。

于 2012-04-11T05:04:46.527 に答える
1

string.h をインクルードしてみてください:

#include <string.h>

次に、組み込みstrcmp()関数を使用します。既存の文字列関数は、ほとんどの状況で可能な限り高速になるように既に記述されています。

forまた、あなたの発言はめちゃくちゃだと思います:

for(i=0;*porg+i;i++) 

これは、ポインターを逆参照してから追加iします。for ループがこれまでに存在しないことに驚いています。

これに変更すると、動作するはずです:

for(i=0;porg[i];i++) 

元の紐も思ったより1本長いです。10 バイトを割り当てますが、実際には 11 バイトの長さです。文字列 (引用符で囲んだもの) は常にヌル文字で終わります。char 配列に対して 11 バイトを宣言する必要があります。

別の問題:

if(!(*porg+i==*pcmp+i))

に変更する必要があります

if(!(porg[i]==pcmp[i]))

上記と同じ理由で。

于 2012-04-11T05:01:00.337 に答える