2011-11-14 48 views
0

私はswitch文の使い方を学び、rand()とsrand()関数を使用していますが、このコードを実行しようとするとセグメンテーション違反が発生します。 。これが起こる原因は何でしょうか?このコードを実行すると、セグメンテーションフォルトが発生するのはなぜですか?

#include <stdio.h> 

int main(void) 
{ 

int iRandomNum = 0; 
srand(time()); 

iRandomNum = (rand() % 4) + 1; 

printf("\nFortune Cookie - Chapter 3\n"); 

    switch (iRandomNum) { 

    case 1: 
     printf("\nYou will meet a new friend today.\n"); 
     break; 
    case 2: 
     printf("\nYou will enjoy a long and happy life.\n"); 
     break; 
    case 3: 
     printf("\nOpportunity knocks softly. Can you hear it?\n"); 
     break; 
    case 4: 
    printf("\nYou'll be financially rewarded for your good deeds.\n"); 
     break; 

    } //end switch 

printf("\nLucky lotto numbers: "); 
printf("%d ", (rand() % 49) + 1); 
printf("%d ", (rand() % 49) + 1); 
printf("%d ", (rand() % 49) + 1); 
printf("%d ", (rand() % 49) + 1); 
printf("%d ", (rand() % 49) + 1); 
printf("%d\n", (rand() % 49) + 1); 

} //end main function 
+0

segフォールトの前にコンソールに何かが表示されますか?基本的に、printfステートメントのどれかを表示しますか? –

+1

[デバッグフラグでコンパイルする](http://gcc.gnu.org/onlinedocs/gcc/Debugging-Options.html)(通常は '-g')を確認してから、[' gdb']を使ってプログラムを実行してください(http://www.gnu.org/s/gdb/)を参照して、segフォルトが発生している行を正確に把握してください。 –

+0

@adamセグメンテーションフォールトの前には何も表示されません。エラーなしでコンパイルしてから、実行するとセグメンテーションフォールトが発生します。 – nastyn8

答えて

2

あなたはtime()引数なし。 time()関数は1つの引数をとりますが、オプションではありません。

ソースファイルの先頭に

#include <time.h> 

を追加し、

srand(time(NULL)); 

EDITにsrand()呼び出しを変更:また

#include <stdlib.h> 
を追加する必要が

srand()rand()の宣言を取得します。

EDIT 2:

あなたは、多くの場合、(一見)それが宣言されていた中で、ヘッダをINGの#includeせずに関数を呼び出すことで逃げることができます。 C90では

あなたが目に見える宣言で関数を呼び出す場合、コンパイラが暗黙的に関数はintを返し、呼び出しで指定された引数を取ることを想定し、そのための宣言を作成します。 srand()rand()の両方が実際にはintの結果を返します。そのため、それらの呼び出しが機能する可能性があります。しかしtime()は、タイプtime_t*の引数をとり、タイプtime_tの結果を返します。あなたが「幸運な人」であれば、宣言のないコールがうまくいくかもしれません。あるいは、あなたの顔に爆発するかもしれません。

1999年のISO C標準(C99)ではルールが変更されているため、可視宣言なしで関数を呼び出すと制約違反が発生し、コンパイラからの診断が必要になります。

C90モードでも、ほとんどのコンパイラは、宣言されていない関数について警告するように説得することができます。

要点:ライブラリ関数を呼び出す場合は、マニュアル(マニュアルページなど)を読み、それを宣言するヘッダーに#includeを追加します。 は、これを忘れた場合にあなたに思い出させるためにコンパイラにカウントされません。

+0

あなたは正しかった、私はなかった#include 今それは正常に実行 – nastyn8

+0

おかげでkeith、wtfはこの本は間違っている私は適切な方法を表示していない、それは2008年に作られた、絶対初心者のためのC "です。 – nastyn8

+0

しかし、唯一のことは#include を使用しておらず、うまくいきます、それは普通ですか? – nastyn8

5

time()は、引数、あなたがそのようなgcc -Wall -Wextra ...と同様に、すべての警告、オンにした場合、コンパイラは言うだろう何かを必要とするからです。

time.h(つまり、time()がデフォルトのプロトタイプを取得することを意味します)を含まない組み合わせで、引数なしで呼び出すことは特に問題です。

higehr警告レベルを使用する際に見つかった問題の完全なリストは、次のとおりです。

  • time()srand()rand()は何のプロトタイプを持っていない、あなたは#include両方stdlib.htime.hする必要があります。
  • time()には、srand (time (0))のような引数が必要です。
  • mainから何かを返す必要があります(非常にの最近の反復ですが、依然として良い方法です)。

次の変更が正常に動作:

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

int main (void) { 
    int iRandomNum = 0; 
    srand (time (0)); 

    iRandomNum = (rand() % 4) + 1; 

    printf("\nFortune Cookie - Chapter 3\n"); 

    switch (iRandomNum) { 
     case 1: 
      printf("\nYou will meet a new friend today.\n"); 
      break; 
     case 2: 
      printf("\nYou will enjoy a long and happy life.\n"); 
      break; 
     case 3: 
      printf("\nOpportunity knocks softly. Can you hear it?\n"); 
      break; 
     case 4: 
      printf("\nYou'll be financially rewarded for your good deeds.\n"); 
      break; 
    } //end switch 

    printf("\nLucky lotto numbers: "); 
    printf("%d ", (rand() % 49) + 1); 
    printf("%d ", (rand() % 49) + 1); 
    printf("%d ", (rand() % 49) + 1); 
    printf("%d ", (rand() % 49) + 1); 
    printf("%d ", (rand() % 49) + 1); 
    printf("%d\n", (rand() % 49) + 1); 

    return 0; 
} 
+0

私はを使用しませんでしたが、それでもまだ – nastyn8

+1

@ nastyn8で動作しましたが、それでも動作するかもしれませんが、 'rand'や' srand'のプロトタイプは持っていません。 _always_あなたが使用する関数の関連するヘッダーファイルを含める必要があります。 – paxdiablo

3

私はあなたのコードをデバッグするgdbを使用して、セグメンテーション違反がこのラインで起こる:

srand(time()); 

あなたは間違ってtime()を使用しています。あなたは結果として時間を保持するパラメータを渡す必要がありますが、NULLreturn時間に関数を発生します:

srand(time(NULL)); 

また、main()機能からreturn常にに確認してください。

このコードは正常に動作します:

#include <stdlib.h> 
#include <stdio.h> 
#include <time.h> 

int main(void) 
{ 

int iRandomNum = 0; 
srand(time(NULL)); 

iRandomNum = (rand() % 4) + 1; 

printf("\nFortune Cookie - Chapter 3\n"); 

    switch (iRandomNum) { 

    case 1: 
     printf("\nYou will meet a new friend today.\n"); 
     break; 
    case 2: 
     printf("\nYou will enjoy a long and happy life.\n"); 
     break; 
    case 3: 
     printf("\nOpportunity knocks softly. Can you hear it?\n"); 
     break; 
    case 4: 
    printf("\nYou'll be financially rewarded for your good deeds.\n"); 
     break; 

    } //end switch 

printf("\nLucky lotto numbers: "); 
printf("%d ", (rand() % 49) + 1); 
printf("%d ", (rand() % 49) + 1); 
printf("%d ", (rand() % 49) + 1); 
printf("%d ", (rand() % 49) + 1); 
printf("%d ", (rand() % 49) + 1); 
printf("%d\n", (rand() % 49) + 1); 

return 0; 
} //end main function 

ちょうどあなたが私はあなたのコードをデバッグする方法に興味がある場合には、私はデバッグシンボルと可能な警告すべてのコンパイラでそれをコンパイル:

gcc -g -Wall -Wextra test.c -o test 

そして、私は始まったgdb

gdb ./test 
(gdb) run 
Program received signal SIGSEGV, Segmentation fault. 
0x00007ffff7ffba2c in time() 
(gdb) quit 
+0

私はあなたが言ったことをしましたが、私はまだSEGフォールトに陥っています – nastyn8

+1

'#include 'を追加して 'time()'関数の宣言が見えるようにする必要があります。 'srand()'と 'rand()'には '#include 'があります。 –

+0

本当にですか?最初は、それを含めました。しかし、私はそれを省略し、コードはまだコンパイルされています。私はそれを良い尺度のために取り返します。 – Blender

関連する問題