こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

シェルソート(Cプログラミング)

シェル・ソート
基本挿入法により、データを昇順にソートする。
というプログラムを実行したいと思ったのですが、エラーがでてしまいコンパイルできません。

書いたプログラムは以下の通りです。

#include<stdio.h>
#include<math.h>

#define N 100

int main (void)
{
int a[N],i,j,t;

for (i=0;i<N;i++)
a[i]=rand();

for (i=1;i<N;i++){
for (j=j-1;j>=0;j--){
if (a[j]>a[j+1]){
t=a[j]; a[j]=a[j+1]; a[j+1]=t;
}
else
break;
}
}
for (i=0;i<N;i++)
printf("%8d",a[i]);
}

エラーメッセージは以下のようにでました。
警告 W8065 sample.c 10: プロトタイプ宣言のない関数 'rand' の呼び出し(関数 main )
警告 W8070 sample.c 22: 関数は値を返すべき(関数 main )

どうすれば出来るのでしょうか、お答えよろしくお願いします。

投稿日時 - 2007-09-07 11:20:44

QNo.3323110

すぐに回答ほしいです

質問者が選んだベストアンサー

エラーではなく警告ですので、コンパイルできています。
ただ、

> for (j=j-1;j>=0;j--){

この行に誤りがあるため、実行時に落ちます。

さらに、乱数の初期化を行なっていないため、
正しく実行できたとしても毎回同じ結果を得ます。
それでもよければかまわないのですが、srand()を使って
乱数を初期化した方が毎回違った結果を得ることができて
おもしろいでしょう。

ちなみに、2つ目の警告が出ないようにするには、
main()の最後に
return 0;
を加えてください。

投稿日時 - 2007-09-07 12:28:46

このQ&Aは役に立ちましたか?

2人が「このQ&Aが役に立った」と投票しています

回答(9)

ANo.9

>for ((j=N-1)--;j>=0;j--){
>でいくはずですが、コンパイラの違いでしょうか・・・?

j = N-1 という代入式に対してデクリメント演算子を適用しようとしていますが、
通常は代入式は lvalue を持たないのでデクリメント演算子を適用できません。
できるコンパイラがあるならそれが拡張されているかしているのでしょう。

#C++でのは扱いは覚えてません

投稿日時 - 2007-09-11 03:29:57

ANo.8

>エラー E2277 sample.c 14: 左辺値が必要(関数 main )
>*** 1 errors in Compile ***
>と出てしまいました(´;ェ;`)

for ((j=N-1)--;j>=0;j--){
でいくはずですが、コンパイラの違いでしょうか・・・?


for (j=N-2;j>=0;j--){
としてみてください。

投稿日時 - 2007-09-11 01:11:45

ANo.7

>アドバイス通りに書き換えましたら、実行することができました。
>実行結果が以下のようになってしまったのですが、これ間違ってま
>すよね?(略)

大変、失礼いたしました!(謝)

for (j=j-1;j>=0;j--){

for ((j=N-1)--;j>=0;j--){
です、すみません・・・。

>ダメです。
>main関数の戻り値は、C言語の規格でint型であると決まっています。
もちろん、既知の上です。
ただ、“void でも一応動作はする”と言うことで
「この書き方も出来ます」と言うニュアンスですので
void にしてください、ということではありません。
でもご指摘ありがとうございました!

投稿日時 - 2007-09-09 01:41:17

補足

for ((j=N-1)--;j>=0;j--){
に書き直してコンパイルしてみたら、
警告 W8065 sample.c 11: プロトタイプ宣言のない関数 'rand' の呼び出し(関数 main )

エラー E2277 sample.c 14: 左辺値が必要(関数 main )
*** 1 errors in Compile ***
と出てしまいました(´;ェ;`)

何回もすみません。

投稿日時 - 2007-09-09 21:50:15

ANo.6

> 「It(訳注:main関数のことです) shall be defined with a return type of int (以下略)」

shall は「~するべし」という意味ですので、
「int以外の型にしたとき、何が起きても知らないよ」という
ニュアンスを含んでいると思われます。

投稿日時 - 2007-09-08 08:26:40

ANo.5

> main関数の戻り値は、C言語の規格でint型であると決まっています。

「根拠を示せ」と言われる前に、提示しておきます。
ISOの規格番号「ISO/IEC 9899:1999」に、
「It(訳注:main関数のことです) shall be defined with a return type of int (以下略)」
という記述があります。

投稿日時 - 2007-09-08 08:21:36

ANo.4

> void main (void)
> でも良いですね。

ダメです。
main関数の戻り値は、C言語の規格でint型であると決まっています。

投稿日時 - 2007-09-08 07:55:55

ANo.3

int main (void)
は引数なく戻り値の必要がないので、
void main (void)
でも良いですね。
あと、
for (j=j-1;j>=0;j--){

for (j=N-1;j>=0;j--){
ですね。

あと再帰を使ったシェルソートを作ってみたので
参考にしてみてください。

#include <stdio.h>

int _SonyuSort(int S[],int t,int n,int d,int max,unsigned int *k)// ここでの n は個数
{
int r,i;

if (n<t) return t;
r=_SonyuSort(S,t,n-d,d,max,k);
if (n>max) return n;
if (S[r-1]>S[n-1])
{
S[r-1]-=S[n-1]=(S[r-1]=S[r-1]+S[n-1])-S[n-1],(*k)++;
printf("%d回目:",*k);
for (i=0;i<max;i++) printf("%d ",S[i]);printf("\r\n");
_SonyuSort(S,t,n,d,max,k);
}
else return n;
}


int ShellSort(int S[],int n,unsigned int *k)
{
int i,j;
for (i=n>>1;i;i>>=1) //i&=(~((i=n>>1)&1)) では増えることに注意
{
printf("グループ数:%d\r\n",i);
for (j=1;j<=n;j++) _SonyuSort(S,j,n-(n%i)+j,i,n,k);
}
return 0;
}


int SonyuSort(int S[],int n,unsigned int *k) // ここでの n は個数-1
{
int r;

if (!n) return 0;
if (S[(r=SonyuSort(S,n-1,k))]>S[n])
{
S[r]-=S[n]=(S[r]+=S[n])-S[n],(*k)++;
SonyuSort(S,n,k);
}
else return n;
}

int main(void)
{
int S[]={-5,-768,768,56,9,-98,45,7,509,8,-98,80,444,-1234,9800,9,-678};
unsigned int k=0; // k=挿入ソート回数
int i,n=sizeof(S)/sizeof(int);

printf("整列前:");
for (i=0;i<n;i++) printf("%d ",S[i]);printf("\r\n\r\n");
ShellSort(S,n,&k);
printf("\r\n整列後:");
for (i=0;i<n;i++) printf("%d ",S[i]);printf("\r\n\r\n");
printf("ソート回数:%d 回\r\n",k);
return 0;
}

投稿日時 - 2007-09-07 21:50:34

補足

アドバイス通りに書き換えましたら、実行することができました。
実行結果が以下のようになってしまったのですが、これ間違ってますよね?(^^;)
130 10982 1090 11656 7117 17595 6415 22948 31126 9004
14558 3571 22879 18492 1360 5412 26721 22463 25047 27119
31441 7190 13985 31214 27509 30252 26571 14779 19816 21681
19651 17995 23593 3734 13310 3979 21995 15561 16092 18489
11288 28466 8664 5892 13863 22766 5364 17639 21151 20427
100 25795 8812 15108 12666 12347 19042 19774 9169 5589
26383 9666 10941 13390 7878 13565 1779 16190 32233 53
13429 2285 2422 8333 31937 11636 13268 6460 6458 6936
8160 24842 29142 29667 24115 15116 17418 1156 4279 15008
15859 19561 8297 3755 22981 21275 29040 28690 1401 18137

投稿日時 - 2007-09-08 15:40:17

ANo.1

> 警告 W8065 sample.c 10: プロトタイプ宣言のない関数 'rand' の呼び出し(関数 main )

rand関数はstdlib.hで定義されているかと思いますので、
#include <stdlib.h>
をインクルードしてください。

お手元のリファレンスマニュアルなどでrand関数を確認してください。

投稿日時 - 2007-09-07 11:24:54

あなたにオススメの質問