🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

Q&A

2回答

870閲覧

リストの合計を求める関数

yoshi_1192

総合スコア0

C

C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

0グッド

0クリップ

投稿2021/01/27 09:54

前提・実現したいこと

ここに質問の内容を詳しく書いてください。
リストのすべての要素の値を合計して返却する関数を再帰
処理と非再帰処理により実装
• 再帰版: sunR()
• 非再帰版: sumNR()
■■な機能を実装中に以下のエラーメッセージが発生しました。

発生している問題・エラーメッセージ

【長さnのリストを作成】 n: 16 作成されたリスト: [16,15,14,13,12,11,10,9,8,7,6,5,4,3,2,1] 【動作確認】

該当のソースコード

#include <stdio.h> /* 定数の定義 */ #define True 1 #define False 0 /* nilはNULL(空リスト)を表す */ #define nil NULL /* データ型の定義 */ typedef int Bool; typedef int Data; /* データ構造の定義 */ typedef struct Cell { Data value; struct Cell *next; } * List; /* 関数プロトタイプの定義 */ List cons(Data n, List L); Data first(List L); List rest(List L); void writeData(Data v); void writeList(List L); List readList(void); int length(List L); int sumR(List L); int sumNR(List L); /* cons(d,L): リストLの先頭にデータdを加えたリストを返す */ List cons(Data d, List L) { List newList; newList = (List)malloc(sizeof(struct Cell)); newList->value = d; newList->next = L; return newList; } /* first(L): リストLの先頭のデータを返す */ Data first(List L) { return L->value; } /* rest(L): リストLの先頭を除いた残りのリストを返す */ List rest(List L) { return L->next; } /* データ1個分を出力 */ void writeData(Data n) { printf("%d", n); } /* リスト全体を出力するための再帰関数 */ void writeRest(List L) { if(L != nil) { printf(","); writeData(first(L)); writeRest(rest(L)); } } /* リスト全体を出力するための関数 */ void writeList(List L) { printf("["); if(L != nil) { writeData(first(L)); writeRest(rest(L)); } printf("]"); } /* リストのデータ読み込み関数 */ List readList(void) { int n, i; List L; Data d; printf("リストの要素数="); scanf("%d", &n); L = nil; for(i = 0; i < n; i++) { printf("リストの第%d要素=", i); scanf("%d", &d); L = cons(d, L); } return (L); } /* リストの長さを求める関数 */ int length(List L) { if(L == nil) return 0; else return 1 + length(rest(L)); } /* リストの合計を求める関数(再帰版) */ /* ここにソースコードを書く */ int sumR(List L) { int goukei; while (goukei = goukei + L->value); L = rest(L); if(L==nil) return(0); else return sumR(rest(L)) + L->value; } /* リストの合計を求める関数(非再帰版) */ /* ここにソースコードを書く */ int sumNR(List L) { int goukei; while (goukei = goukei + L->value); L = rest(L); L != nil;ri return goukei; } /* メイン関数 */ int main(int argc, char **argv) { int i, n; Data v; List L = nil; printf("【長さnのリストを作成】\n"); printf("n: "); scanf("%d", &n); for(i = 1; i <= n; i++) { Data v; v = i; L = cons(v, L); } printf("作成されたリスト:\n"); writeList(L); /* 動作確認 */ printf("\n【動作確認】\n"); printf("Lの合計値(再帰版): %d\n", sumR(L)); printf("Lの合計値(非再帰版): %d\n", sumNR(L)); return 0; }

試したこと

上記のようにプログラムを作成していますが、うまく実行までたどり着くことが出来ません
訂正などお願いします。

補足情報(FW/ツールのバージョンなど)

ここにより詳細な情報を記載してください。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

再帰が上手く動かない、、とは以下の箇所でしょうか?

C

1int sumR(List L) { 2 3int goukei; 4while (goukei = goukei + L->value); 5L = rest(L); 6if(L==nil) return(0); 7else 8return sumR(rest(L)) + L->value; 9}

他の箇所に較べて、インデントもなく、書式も不統一ですね。
多分、終わらないのは、while (goukei = goukei + L->value); の箇所でしょう。
まず、goukeiが初期化されていないので、値が不定。で、同じ値を加算してるので、整数がオーバーフローして 0に戻るまで抜けないでしょうか。

やりたい事は? と考えて書き換えてみると、

C

1int sumR(List L) 2{ 3 return (L == nil) ? 0 : (L->value + sumR(rest(L))); 4}

ということでしょうか?

なお、同様の問題は、int sumNR(List L)もありますね。
また、提示のコードはゴミがあるため、コンパイルが通りません。テストしたコードなのでしょうか。

投稿2021/01/27 12:10

pepperleaf

総合スコア6385

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yoshi_1192

2021/01/27 12:52

ご回答ありがとうございます。 int sumNR(List L)について、初期値などを考慮し、変更したところ int sumNR(List L) { int goukei=0; while (L != nil){ L = rest(L); L != nil; goukei = goukei + L->value; } return goukei; } と書き直しました。
pepperleaf

2021/01/31 09:03

今更のコメントですが、上記のコードで正しく動いたでしょうか? > L = rest(L); // ループの最初で、枝に入っているので、最初の値は? > L != nil; // L が nilの判定のみで、何もしません。
guest

0

C言語のコードを書くなら、デバッグできる環境を整えましょう。
Eclipseや、WindowsならVisualStudioなど。
コードの任意の場所で実行を止め、変数のナカミを見ることができます。そこから1行づつ実行して、コードの流れを見れるようになります
そうすれば、アテズッポでコードを書かなくて済むようになります。

投稿2021/01/27 10:01

y_waiwai

総合スコア88038

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問