C言語で、「自然数nを入力し、nの約数をすべて求めて出力後、その個数と合計を出力をする。尚、nとして0(ゼロ)以下が入力されるまで、何度も繰り返す」という問題をやっています。
出力例は、(3を入力したとして)
「3の約数は 1 3
約数の個数は2個
約数の和は4」というものです。
そこで、コーディングをしたのですが、先生が開発したコンパイラで運用したところ、フリーズが起きて強制終了してしまいました。先生は、「そんなことはない。フリーズが起きるときはそのプログラムにバグがあるときだ」と言ってました。
そこでコーディングしたプログラムは以下の通りです。
#include <stdio.h>
main()
{int i,j,n,cnt,sum;
printf("自然数=");scanf("%d",&n);
while(n>=0){
printf("%dの約数は",n);
for(i=1;i<=n;i++){
if(n/i>=0){
j=n/i;
printf(" %d",j);
sum=sum+j;
cnt++;
j=0;}
}
printf("\n");
printf("約数の個数は%d個",cnt);
printf("約数の和は%d",sum);
}}
どこかに間違いがありますか?
IF文の中でいちいちめんどくさいことをしていますが、気にしないでください。
No.11ベストアンサー
- 回答日時:
少なくともif(n/i>=0)のところはif(n%i==0)の間違いでないかと思います.
しかしそう考えるとjに関する処理は不要なはず.
jに関する処理は約数を逆順にしているだけということになり,質問の
意味と矛盾しますね.
あとj=0;は無駄な処理のように見えます.
No.10
- 回答日時:
> 先生は、「そんなことはない。
フリーズが起きるときはそのプログラムにバグがあるときだ」と言ってました。バグのあるプログラムのソースファイルを入力してフリーズするのであれば、そのコンパイラのバグだと思います。
No.9
- 回答日時:
> もしよかったらどこで抜け出すための終了条件を定義すればいいのか教えてください。
。。scanf を while の中に、判定は、scanf の後、その他は他の方が指摘しているとおり、、、書いたほうが早いか。
main()
{
int i, n, cnt, sum;
while (1) {
printf("自然数="); scanf("%d",&n);
if (n <= 0) { print("done\n"); break; }
cnt = 0; sum = 0;
for (i = 1; i <= n; ++i) {
if (n % i==0) {
sum += i;
cnt++;
}
}
printf("%dの約数は\n", n);
printf("約数の個数は%d個\n", cnt);
printf("約数の和は%d\n\n", sum);
}
return -1;
}
No.8
- 回答日時:
(1)
sumやcntの初期値として、0をセットすることを忘れています。
(2)
jは、n ÷ i の商です。
printfしたりsumに加算するのは、jではなく、iですね。
(3)
約数かどうかの判定は、n ÷ iの余りが0かどうかで調べます。
if (n % i == 0) が正解。
No.7
- 回答日時:
#include <stdio.h>
#include <stdlib.h>
void calc_divisor(void);
void find_by_divisor(struct st_divisor divisor);
unsigned int get_natural_number();
void disp_start(unsigned int number);
void disp_progress(unsigned int find_divisor);
void disp_result(struct st_divisor divisor);
unsigned int str2num(char *str);
struct st_divisor{
unsigned int sum;
unsigned int cnt;
unsigned int (*get_number)(void);
void (*disp_start)(unsigned int);
void (*disp_progress)(unsigned int);
void (*disp_result)(struct st_divisor);
};
int main( void ){
calc_divisor();
return 0;
}
void calc_divisor(void){
struct st_divisor divisor = {
0,
0,
get_natural_number,
disp_start,
disp_progress,
disp_result
};
find_by_divisor(divisor);
}
void find_by_divisor(struct st_divisor divisor){
unsigned int i = 1;
unsigned int n = divisor.get_number();
if(divisor.disp_start){divisor.disp_start(n);}
for( ; i<=n ; i +=1 ) {
if(n % i == 0 ){
if(divisor.disp_progress){divisor.disp_progress(i);};
divisor.sum += i;
divisor.cnt += 1;
}
}
if(divisor.disp_result){divisor.disp_result(divisor);};
}
unsigned int get_natural_number(){
char buffer[10] ={0};
unsigned int number = 0;
fgets(buffer, 10, stdin);
number = str2num(buffer);
if(number <= 0 ){
printf("不正な入力です。");
exit(1);
}
return number;
}
void disp_start(unsigned int number){
printf("自然数=%u\n",number);
printf("%uの約数は",number);
}
void disp_progress(unsigned int find_divisor){
printf(" %u",find_divisor);
}
void disp_result(struct st_divisor divisor){
printf("\n");
printf("約数の個数は%u個\n",divisor.cnt);
printf("約数の和は%uです。\n",divisor.sum);
}
unsigned int str2num(char *str){
unsigned int number = 0;
while(*str){
if('0' <= *str && *str <= '9'){
number = number * 10 + *str - '0';
}else{
return number;
}
str++;
}
return number;
}
No.6
- 回答日時:
> for(i=1;i<=n;i++){
> if(n/i>=0){
1≦i≦n の条件では常に
1 ≦ |n/i|
です。(証明省略)
Cで整数同士の割り算の結果は整数(小数点以下切り捨て)なので、 プログラム中のn/iは 数学の|n/i|になります。
つまり、 n/i は常に1以上(ということは0以上)なんで、このif文は常に真です。
よって、if文は必要ありません。自然数n以下の全ての自然数iについて、|n/i|が約数となります。
....って、これ、おかしいですよね?
No.5
- 回答日時:
>どこかに間違いがありますか?
約数というのは、ある整数を割りきることができる数のことですね。
ところが、今のソースコードには「割り切れる(つまり、余りがゼロ)」という
判断をしている箇所が見当たりません。これは致命的です。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# C言語階乗の総和を求める 2 2023/03/04 23:31
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分 1 2022/07/19 17:03
- C言語・C++・C# 至急お願いします。プログラミングの問題です。 最初に正の整数nの入力を受け付け、次に分数の分子と分母 3 2022/07/19 17:09
- C言語・C++・C# 至急教えてください。プログラミングの問題です。 malloc関数を使ってください!お願いします! 最 1 2022/07/21 09:28
- C言語・C++・C# C言語 3 2022/10/04 15:07
- C言語・C++・C# C言語 プログラミング 4 2022/05/22 11:53
- C言語・C++・C# 至急教えてください!プログラミングの問題です。 割られる整数と割る整数を受け取って、商と余りを出力す 3 2022/07/05 10:23
- C言語・C++・C# 10個の実数に対する降順ソート結果を出力するプログラムを作りたいのですが、以下のプログラムをどう直せ 1 2022/07/09 22:16
- C言語・C++・C# C言語プログラム変更 2 2022/12/21 15:03
- C言語・C++・C# プログラミングの授業の課題です 1 2023/01/17 22:15
このQ&Aを見た人はこんなQ&Aも見ています
関連するカテゴリからQ&Aを探す
おすすめ情報
このQ&Aを見た人がよく見るQ&A
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
既約分数の表示プログラム
-
10個出力で改行したいのですが...
-
ホームページをC言語で作りたい...
-
コンパイルエラーについて
-
8人分のテストの点数を入力し、...
-
%P と %X の違い
-
c言語でAからZまでを表示する...
-
Cのdoubleの浮動小数点表示につ...
-
三角形の判別
-
printf で二進表示を行いたい。
-
入力したお金の金額からお札の...
-
分数を表示するプログラム(長...
-
strcmp
-
4の倍数を論理演算で表す。。
-
アドレスの比較について
-
再帰処理 変換
-
C++ 二次関数の重解、虚数解が...
-
球の体積と表面積を表示するプ...
-
C言語で連立一次方程式
-
なぜgccはstdio.hをインクルー...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
C言語について
-
printf で二進表示を行いたい。
-
cshの文字列操作(0埋め)
-
10個出力で改行したいのですが...
-
コンパイルエラーについて
-
テキストカーソル位置の取得
-
strcmp
-
unsigned int型について
-
c言語でAからZまでを表示する...
-
printf( " %2d", p * q );
-
コマンドラインに出力した文字...
-
printfの出力内の文字をdefine...
-
ホームページをC言語で作りたい...
-
コマンドプロンプトがすぐ消える
-
小数点切捨て表示
-
【C言語教えてください】sin波...
-
switch分のケースを範囲数?に...
-
二つの整数値の大小比較
-
4の倍数を論理演算で表す。。
-
defineで定数が置き換えられな...
おすすめ情報