plhのプロフィール
- ベストアンサー数
- 4
- ベストアンサー率
- 50%
- お礼率
- 0%
- 登録日2008/06/13
- 双方向リストの関数
双方向リストにデータファイルから読み込んだ氏名と成績のデータを追加し,リストの末尾から順にデータを表示するプログラムを作成したのですが、insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結するという部分をどのようにして良いのかわからず困っています。 どのように記述して良いのかわからなかった部分を/*** ***/のコメントで示してあります。 どなたかアドバイスやヒント、その他の指摘などご教授してくださる方いましたらよろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME_LENGTH 20 /* 名前を格納する文字列の長さ */ /* 双方向リストのノードとなる構造体の定義 */ typedef struct sList{ struct sList *prev; /* 前のノードのアドレス */ char name[NAME_LENGTH]; /* 名前 */ char grade; /* 成績 */ struct sList *next; /* 次のノードのアドレス */ } sNode; /* この構造体を sNode型 と定義する */ /* 双方向リストの先頭と末尾を格納するための構造体 */ typedef struct { sNode *firstNode; /* リストの先頭ノードのアドレス */ sNode *lastNode; /* リストの末尾ノードのアドレス */ } manageList; /* 双方向リストの末尾にノードを追加する関数 insertLast() 引数 manageList *list リストの先頭・末尾ノードを管理する構造体のアドレス sNode *node 末尾に追加したいノードのアドレス 返値 なし */ void insertLast(manageList *list, sNode *node ) { /*** リストの末尾にノードを追加する ***/ return; } /* 双方向リストの新しいノードを作成する関数 makeNewNode() 引数 char *aName 名前(文字列)の先頭アドレス char aGrade 成績 返値 sNode * 新しく作成したノードの先頭アドレス */ sNode *makeNewNode(char *aName, char aGrade ) { sNode *pNewData; /* sNode 型のメモリ領域を確保 */ pNewData = (sNode *) malloc( sizeof(sNode) ); /* 名前と成績のデータを設定する */ strcpy( pNewData->name, aName ); pNewData->grade = aGrade; pNewData->prev = NULL; pNewData->next = NULL; return( pNewData ); } /* main() 引数 なし 返値 int 正常終了の時 0 異常終了の時 -1 (ファイルの読み込み失敗など) */ int main( void ) { manageList list; /* リストの先頭・末尾ノードのアドレスを持つ構造体 */ sNode *pNew; /* 新しく作成したノードのアドレスを持つ変数 */ sNode *pNow; /* 現在見ているノードのアドレスを持つ変数 */ FILE *fp; /* データファイルのファイルポインタ */ char name[ NAME_LENGTH ]; /* ファイルから読み込んだ名前を一時的に保持する変数 */ char grade; /* ファイルから読み込んだ成績を一時的に保持する変数 */ /* 初期状態では先頭・末尾ノードともNULL */ list.firstNode = NULL; list.lastNode = NULL; /* データファイル exer6.txt を読み込み用に開く. ファイルが開けなかった場合,エラーメッセージを表示し異常終了する.*/ fp = fopen("exer6.txt","r"); if(NULL == firstNode){ printf( "ファイルが開けませんでした. \n" ); return( -1 ); } /* データをファイルの最後(EOF)まで読み込み,双方向リストにデータを追加する */ while( EOF != fscanf( fp, "%s %c", name, &grade ) ) { /* 新しいノードを作成 */ pNew = makeNewNode( name, grade ); /*** insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結する ***/ pNow->next = pNew ; pNew->prev = pNow ; pNow = pNew ; /* ファイルを閉じる */ fclose( fp ); /* 現在見ているノードを末尾ノードにセットする */ pNow = lastNode /* 末尾のノードから前のノードへたどりながらデータを出力する */ while( NULL != pNow ) { /* 出力 */ printf( "%s %c\n", pNow->name, pNow->grade ); /* 現在見ているノードを一つ前のノードにする */ pNow = pNow->prev; } return( 0 ); }
- 締切済み
- C・C++・C#
- iriiri_001
- 回答数8
- 双方向リストの関数
双方向リストにデータファイルから読み込んだ氏名と成績のデータを追加し,リストの末尾から順にデータを表示するプログラムを作成したのですが、insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結するという部分をどのようにして良いのかわからず困っています。 どのように記述して良いのかわからなかった部分を/*** ***/のコメントで示してあります。 どなたかアドバイスやヒント、その他の指摘などご教授してくださる方いましたらよろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME_LENGTH 20 /* 名前を格納する文字列の長さ */ /* 双方向リストのノードとなる構造体の定義 */ typedef struct sList{ struct sList *prev; /* 前のノードのアドレス */ char name[NAME_LENGTH]; /* 名前 */ char grade; /* 成績 */ struct sList *next; /* 次のノードのアドレス */ } sNode; /* この構造体を sNode型 と定義する */ /* 双方向リストの先頭と末尾を格納するための構造体 */ typedef struct { sNode *firstNode; /* リストの先頭ノードのアドレス */ sNode *lastNode; /* リストの末尾ノードのアドレス */ } manageList; /* 双方向リストの末尾にノードを追加する関数 insertLast() 引数 manageList *list リストの先頭・末尾ノードを管理する構造体のアドレス sNode *node 末尾に追加したいノードのアドレス 返値 なし */ void insertLast(manageList *list, sNode *node ) { /*** リストの末尾にノードを追加する ***/ return; } /* 双方向リストの新しいノードを作成する関数 makeNewNode() 引数 char *aName 名前(文字列)の先頭アドレス char aGrade 成績 返値 sNode * 新しく作成したノードの先頭アドレス */ sNode *makeNewNode(char *aName, char aGrade ) { sNode *pNewData; /* sNode 型のメモリ領域を確保 */ pNewData = (sNode *) malloc( sizeof(sNode) ); /* 名前と成績のデータを設定する */ strcpy( pNewData->name, aName ); pNewData->grade = aGrade; pNewData->prev = NULL; pNewData->next = NULL; return( pNewData ); } /* main() 引数 なし 返値 int 正常終了の時 0 異常終了の時 -1 (ファイルの読み込み失敗など) */ int main( void ) { manageList list; /* リストの先頭・末尾ノードのアドレスを持つ構造体 */ sNode *pNew; /* 新しく作成したノードのアドレスを持つ変数 */ sNode *pNow; /* 現在見ているノードのアドレスを持つ変数 */ FILE *fp; /* データファイルのファイルポインタ */ char name[ NAME_LENGTH ]; /* ファイルから読み込んだ名前を一時的に保持する変数 */ char grade; /* ファイルから読み込んだ成績を一時的に保持する変数 */ /* 初期状態では先頭・末尾ノードともNULL */ list.firstNode = NULL; list.lastNode = NULL; /* データファイル exer6.txt を読み込み用に開く. ファイルが開けなかった場合,エラーメッセージを表示し異常終了する.*/ fp = fopen("exer6.txt","r"); if(NULL == firstNode){ printf( "ファイルが開けませんでした. \n" ); return( -1 ); } /* データをファイルの最後(EOF)まで読み込み,双方向リストにデータを追加する */ while( EOF != fscanf( fp, "%s %c", name, &grade ) ) { /* 新しいノードを作成 */ pNew = makeNewNode( name, grade ); /*** insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結する ***/ pNow->next = pNew ; pNew->prev = pNow ; pNow = pNew ; /* ファイルを閉じる */ fclose( fp ); /* 現在見ているノードを末尾ノードにセットする */ pNow = lastNode /* 末尾のノードから前のノードへたどりながらデータを出力する */ while( NULL != pNow ) { /* 出力 */ printf( "%s %c\n", pNow->name, pNow->grade ); /* 現在見ているノードを一つ前のノードにする */ pNow = pNow->prev; } return( 0 ); }
- 締切済み
- C・C++・C#
- iriiri_001
- 回答数8
- 双方向リストの関数
双方向リストにデータファイルから読み込んだ氏名と成績のデータを追加し,リストの末尾から順にデータを表示するプログラムを作成したのですが、insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結するという部分をどのようにして良いのかわからず困っています。 どのように記述して良いのかわからなかった部分を/*** ***/のコメントで示してあります。 どなたかアドバイスやヒント、その他の指摘などご教授してくださる方いましたらよろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME_LENGTH 20 /* 名前を格納する文字列の長さ */ /* 双方向リストのノードとなる構造体の定義 */ typedef struct sList{ struct sList *prev; /* 前のノードのアドレス */ char name[NAME_LENGTH]; /* 名前 */ char grade; /* 成績 */ struct sList *next; /* 次のノードのアドレス */ } sNode; /* この構造体を sNode型 と定義する */ /* 双方向リストの先頭と末尾を格納するための構造体 */ typedef struct { sNode *firstNode; /* リストの先頭ノードのアドレス */ sNode *lastNode; /* リストの末尾ノードのアドレス */ } manageList; /* 双方向リストの末尾にノードを追加する関数 insertLast() 引数 manageList *list リストの先頭・末尾ノードを管理する構造体のアドレス sNode *node 末尾に追加したいノードのアドレス 返値 なし */ void insertLast(manageList *list, sNode *node ) { /*** リストの末尾にノードを追加する ***/ return; } /* 双方向リストの新しいノードを作成する関数 makeNewNode() 引数 char *aName 名前(文字列)の先頭アドレス char aGrade 成績 返値 sNode * 新しく作成したノードの先頭アドレス */ sNode *makeNewNode(char *aName, char aGrade ) { sNode *pNewData; /* sNode 型のメモリ領域を確保 */ pNewData = (sNode *) malloc( sizeof(sNode) ); /* 名前と成績のデータを設定する */ strcpy( pNewData->name, aName ); pNewData->grade = aGrade; pNewData->prev = NULL; pNewData->next = NULL; return( pNewData ); } /* main() 引数 なし 返値 int 正常終了の時 0 異常終了の時 -1 (ファイルの読み込み失敗など) */ int main( void ) { manageList list; /* リストの先頭・末尾ノードのアドレスを持つ構造体 */ sNode *pNew; /* 新しく作成したノードのアドレスを持つ変数 */ sNode *pNow; /* 現在見ているノードのアドレスを持つ変数 */ FILE *fp; /* データファイルのファイルポインタ */ char name[ NAME_LENGTH ]; /* ファイルから読み込んだ名前を一時的に保持する変数 */ char grade; /* ファイルから読み込んだ成績を一時的に保持する変数 */ /* 初期状態では先頭・末尾ノードともNULL */ list.firstNode = NULL; list.lastNode = NULL; /* データファイル exer6.txt を読み込み用に開く. ファイルが開けなかった場合,エラーメッセージを表示し異常終了する.*/ fp = fopen("exer6.txt","r"); if(NULL == firstNode){ printf( "ファイルが開けませんでした. \n" ); return( -1 ); } /* データをファイルの最後(EOF)まで読み込み,双方向リストにデータを追加する */ while( EOF != fscanf( fp, "%s %c", name, &grade ) ) { /* 新しいノードを作成 */ pNew = makeNewNode( name, grade ); /*** insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結する ***/ pNow->next = pNew ; pNew->prev = pNow ; pNow = pNew ; /* ファイルを閉じる */ fclose( fp ); /* 現在見ているノードを末尾ノードにセットする */ pNow = lastNode /* 末尾のノードから前のノードへたどりながらデータを出力する */ while( NULL != pNow ) { /* 出力 */ printf( "%s %c\n", pNow->name, pNow->grade ); /* 現在見ているノードを一つ前のノードにする */ pNow = pNow->prev; } return( 0 ); }
- 締切済み
- C・C++・C#
- iriiri_001
- 回答数8
- 双方向リストの関数
双方向リストにデータファイルから読み込んだ氏名と成績のデータを追加し,リストの末尾から順にデータを表示するプログラムを作成したのですが、insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結するという部分をどのようにして良いのかわからず困っています。 どのように記述して良いのかわからなかった部分を/*** ***/のコメントで示してあります。 どなたかアドバイスやヒント、その他の指摘などご教授してくださる方いましたらよろしくお願いします。 #include <stdio.h> #include <stdlib.h> #include <string.h> #define NAME_LENGTH 20 /* 名前を格納する文字列の長さ */ /* 双方向リストのノードとなる構造体の定義 */ typedef struct sList{ struct sList *prev; /* 前のノードのアドレス */ char name[NAME_LENGTH]; /* 名前 */ char grade; /* 成績 */ struct sList *next; /* 次のノードのアドレス */ } sNode; /* この構造体を sNode型 と定義する */ /* 双方向リストの先頭と末尾を格納するための構造体 */ typedef struct { sNode *firstNode; /* リストの先頭ノードのアドレス */ sNode *lastNode; /* リストの末尾ノードのアドレス */ } manageList; /* 双方向リストの末尾にノードを追加する関数 insertLast() 引数 manageList *list リストの先頭・末尾ノードを管理する構造体のアドレス sNode *node 末尾に追加したいノードのアドレス 返値 なし */ void insertLast(manageList *list, sNode *node ) { /*** リストの末尾にノードを追加する ***/ return; } /* 双方向リストの新しいノードを作成する関数 makeNewNode() 引数 char *aName 名前(文字列)の先頭アドレス char aGrade 成績 返値 sNode * 新しく作成したノードの先頭アドレス */ sNode *makeNewNode(char *aName, char aGrade ) { sNode *pNewData; /* sNode 型のメモリ領域を確保 */ pNewData = (sNode *) malloc( sizeof(sNode) ); /* 名前と成績のデータを設定する */ strcpy( pNewData->name, aName ); pNewData->grade = aGrade; pNewData->prev = NULL; pNewData->next = NULL; return( pNewData ); } /* main() 引数 なし 返値 int 正常終了の時 0 異常終了の時 -1 (ファイルの読み込み失敗など) */ int main( void ) { manageList list; /* リストの先頭・末尾ノードのアドレスを持つ構造体 */ sNode *pNew; /* 新しく作成したノードのアドレスを持つ変数 */ sNode *pNow; /* 現在見ているノードのアドレスを持つ変数 */ FILE *fp; /* データファイルのファイルポインタ */ char name[ NAME_LENGTH ]; /* ファイルから読み込んだ名前を一時的に保持する変数 */ char grade; /* ファイルから読み込んだ成績を一時的に保持する変数 */ /* 初期状態では先頭・末尾ノードともNULL */ list.firstNode = NULL; list.lastNode = NULL; /* データファイル exer6.txt を読み込み用に開く. ファイルが開けなかった場合,エラーメッセージを表示し異常終了する.*/ fp = fopen("exer6.txt","r"); if(NULL == firstNode){ printf( "ファイルが開けませんでした. \n" ); return( -1 ); } /* データをファイルの最後(EOF)まで読み込み,双方向リストにデータを追加する */ while( EOF != fscanf( fp, "%s %c", name, &grade ) ) { /* 新しいノードを作成 */ pNew = makeNewNode( name, grade ); /*** insertLast() 関数を用いて末尾ノードの後ろに新しいノードを連結する ***/ pNow->next = pNew ; pNew->prev = pNow ; pNow = pNew ; /* ファイルを閉じる */ fclose( fp ); /* 現在見ているノードを末尾ノードにセットする */ pNow = lastNode /* 末尾のノードから前のノードへたどりながらデータを出力する */ while( NULL != pNow ) { /* 出力 */ printf( "%s %c\n", pNow->name, pNow->grade ); /* 現在見ているノードを一つ前のノードにする */ pNow = pNow->prev; } return( 0 ); }
- 締切済み
- C・C++・C#
- iriiri_001
- 回答数8
- 低次元なコーディング方法について
私は一通り書籍でC言語の基礎を勉強しただけの初心者プログラマです。 もっと実力を付けるためにアルゴリズム関連の書籍をいくつか読み始めました。 これならソースを読む力も一緒に鍛えられると思ったからです。 その中で素数を表示するプログラムに興味を持ち自力で一から組んでみました。 (途中でどうしても分からず参考にする部分もあったのですが…) 私のコーディング手順は 1.UMLのアクティビティ図で大まかな処理を確認する。 2.if文だけで一通りの処理を記述。 3.while文を使って繰り返しの処理を追加する。 4.何度もうまくいかずにそのたびに修正していく。 というものです。 1.の部分は大量に書籍が出ているので勉強できるのですがUMLの性質上 それをコーディングしていく解説はどうしてもCのソースを書くこととは次元が違うようです。 かなり低次元なことだからでしょうか、解説している本にも出会えません。 前置きが長くなりました。 今回教えていただきたいのは ・アクティビティ図などで記述したものをソースコードに落とし込む というかなり低レベルな部分での方法です。 私はオブジェクト指向はまだ勉強していないので Cでその過程などを書いていただけると幸いです。 どうやったらgoto文やフラグを使わずにソースを書けるか、 コツなどあったらぜひ教えてください。 アドバイスの参考になればよいと思い、私が書いた素数表示プログラムの一部を紹介させていただきます。 /**********************************************************/ /* 素数を格納する配列を受け取り最後に-1を格納する関数 */ /* 効率的な演算のために乗除演算回数を表示もおこなう */ /**********************************************************/ #define END (-1) #define MAX 1000 void prime_assess(int a[]) { int j=0; //ループ用のカウンタ int x=3; //検証値 int element_no=1;//配列の中の素数の個数 int arithmetic_no=0;//乗除演算回数 while(x<MAX){ j=0; arithmetic_no++; while(x % a[j] !=0 && a[element_no-1] != x){ arithmetic_no++; if(a[j]-a[j] >= x){ a[element_no++] = x; }else{ j++; } } x += 2; } a[element_no] = END; printf("乗除演算回数は%dでした。\n",arithmetic_no); } 先ほどの1~4のプロセスで作りました。 できるだけ無駄な演算を避けてみたつもりですがいかかでしょうか。 フラグなどを避けるよう、かなり時間をかけて書いたプログラムです。 乗除演算回数はおそらく2636回になっています。 自分以外の方にソースを見ていただける機会がないものですから、 これはおかしいぞというところも書いていただけたらうれしいです。 皆様からのアドバイスをお待ちしております。