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

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

詳細はこちら
C

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

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

Q&A

1回答

1383閲覧

ポインタ参照が難しくて上手く関数化できない

peace_1

総合スコア14

C

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

ポインタ

ポインタはアドレスを用いてメモリに格納された値を"参照する"変数です。

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

0グッド

0クリップ

投稿2021/01/24 16:58

下記のコードで冗長な処理を関数化したいのですが、ポインタ参照やら配列やらで関数化に手こずってます。

処理内のコメントに記載している
0. 商品毎の売り上げ降順表示、商品リストをループ
0. 商品リストの作成
この2つを関数化したらどのような記載になりますか?
完成前後で見比べて考えたいので、見本で関数化して頂きたいです。
よろしくお願いします。

C言語

1#include <stdio.h> 2#include <stdlib.h> 3#include <string.h> 4 5#define MACHINENAME 5 6#define PRODUCT 7 7#define LINEDATAMAX 21 8#define FILEMAX 3 9#define FILENAMEMAX 30 10#define FILEDATAMAX 4 11 12typedef struct{ 13 char name[MACHINENAME]; 14 char kind[PRODUCT]; 15 int price; 16 int sales; 17}DATAin; 18 19typedef struct{ 20 char nameOut[MACHINENAME]; 21 char dammy[3]; 22 int total; 23}DATAout; 24 25void sortName(DATAin *pp,int line); 26void sortPrice(DATAout *po, int line); 27DATAin* readFile(char filename[], DATAin **pl, int *cntF); 28void productOut(DATAin *ppIn, DATAin *pl, DATAout po); 29void calcPrice(DATAin *pp, char kind[PRODUCT], DATAout *po, int *cntKind); 30void reduceMemory(DATAin *mIn, DATAin *mL, int cntF); 31 32int main(void){ 33 char fileName[FILEMAX][FILENAMEMAX] = { 34 {"vending-machine-a.txt"}, 35 {"vending-machine-b.txt"}, 36 {"vending-machine-c.txt"} 37 }; 38 int loop1 = 0; 39 int loop2 = 0; 40 int cntFile = 0; 41 int cntKind = 0; 42 43 DATAout output[FILEMAX] = { 44 {"\0", "\0", 0}, 45 {"\0", "\0", 0}, 46 {"\0", "\0", 0} 47 }; 48 49 DATAin *ppIn[FILEMAX] = {NULL, NULL, NULL}; 50 DATAin *ppL = NULL; 51 DATAout *ppO = NULL; 52 ppO = output; 53 54 /*各ファイル読み取り、商品リストを作成*/ 55 /*inputfileAから情報を抽出*/ 56 for(loop1 = 0; loop1 < FILEMAX; loop1++){ 57 ppIn[loop1] = readFile(fileName[loop1], &ppL, &cntFile); 58 if (ppIn[loop1] == NULL){ 59 printf("a"); 60 return 0; 61 } 62 } 63 /*商品毎の売り上げ降順表示、商品リストをループ*/ 64// productOut(ppIn, ppL, ppO); 65 for(loop1 = 0; strncmp((ppL + loop1)->kind , "\0", 1) != 0; loop1++){ 66 printf("\n-------------\n %s\n-------------\n",(ppL + loop1)->kind); 67 cntKind = 0; /*商品名カウンター*/ 68 for(loop2 = 0; loop2 < FILEMAX; loop2++){ 69 calcPrice(ppIn[loop2], (ppL + loop1)->kind, ppO, &cntKind); 70 } 71 /*商品毎の合計値を金額降順でソート*/ 72 sortPrice(ppO, cntKind); 73 /*商品毎の合計出力*/ 74 for(loop2 = 0; loop2 < cntKind; loop2++){ 75 printf(" %s : %5d\n",(ppO + loop2)->nameOut,(ppO + loop2)->total); 76 } 77 } 78 /*自販機名の再初期化*/ 79 for(loop1 = 0; loop1 < FILEMAX; loop1++){ 80 strncpy((ppO + loop1)->nameOut, (ppIn[loop1])->name, MACHINENAME); 81 } 82 /*合計値の再初期化*/ 83 for(loop1 = 0; loop1 < cntFile; loop1++){ 84 (ppO + loop1)->total = 0; 85 } 86 /*合計値代入*/ 87 for(loop1 = 0; loop1 < FILEMAX; loop1++){ 88 for (loop2 = 0; strncmp((ppIn[loop1] + loop2)->kind, "\0", 1) != 0; loop2++) { 89 (ppO + loop1)->total = (ppO + loop1)->total + ((ppIn[loop1] + loop2)->price * (ppIn[loop1] + loop2)->sales); 90 } 91 } 92 /*メモリ開放*/ 93 reduceMemory(ppIn[0], ppL, cntFile); 94 /*自販機毎の合計値を金額降順でソート*/ 95 sortPrice(ppO, cntFile); 96 /*Total出力*/ 97 printf("\n-------------\n Total\n-------------\n"); 98 /*自販機毎の合計出力*/ 99 for(loop1 = 0; loop1 < cntFile ; loop1++){ 100 printf(" %s : %5d\n",(ppO + loop1)->nameOut,(ppO + loop1)->total); 101 } 102 return 0; 103} 104 105/*商品毎のデータ算出*/ 106void calcPrice(DATAin *pp, char kind[PRODUCT], DATAout *po, int *cntKind){ 107 int loop1 = 0; 108 int sameProbuct = 0; /*重複商品の確認*/ 109 110 for (loop1 = 0; strncmp((pp + loop1)->kind, "\0", PRODUCT) != 0; loop1++) { 111 if(strncmp(kind, (pp + loop1)->kind, PRODUCT) == 0) { 112 if(sameProbuct < 1){ 113 (po + *cntKind)->total = (pp + loop1)->price * (pp + loop1)->sales; 114 strncpy((po + *cntKind)->nameOut, (pp + loop1)->name, MACHINENAME); 115 *cntKind = *cntKind + 1; 116 sameProbuct = 1; 117 }else{ 118 /*2つ目以降の重複商品は1つ目の商品に合算する*/ 119 (po + *cntKind - sameProbuct)->total = (po + *cntKind \ 120 - sameProbuct)->total + ((pp + loop1)->price * (pp + loop1)->sales); 121 } 122 } 123 } 124} 125 126///*商品毎の売り上げ降順表示、商品リストをループ*/ 127//関数化途中 128//void productOut(DATAin *ppIn, DATAin *pl, DATAout po){ 129// int loop1 = 0; 130// int loop2 = 0; 131// int cntKind = 0; 132// 133// for(loop1 = 0; strncmp((pl + loop1)->kind , "\0", 1) != 0; loop1++){ 134// printf("\n-------------\n %s\n-------------\n",(pl + loop1)->kind); 135// cntKind = 0; /*商品名カウンター*/ 136// for(loop2 = 0; loop2 < FILEMAX; loop2++){ 137// calcPrice(ppIn[loop2], (pl + loop1)->kind, po, &cntKind); 138// } 139// /*商品毎の合計値を金額降順でソート*/ 140// sortPrice(po, cntKind); 141// /*商品毎の合計出力*/ 142// for(loop2 = 0; loop2 < cntKind; loop2++){ 143// printf(" %s : %5d\n",(po + loop2)->nameOut,(po + loop2)->total); 144// } 145// } 146//} 147/*商品名降順ソート関数*/ 148void sortName(DATAin *pp, int line){ 149 DATAin bfData = {"\0", "\0", 0, 0}; 150 int loop1 = 0; 151 int loop2 = 0; 152 153 for(loop1 = 0; loop1 < line; loop1++){ 154 for(loop2 = loop1 + 1; loop2 < line; loop2++){ 155 if(strncmp((pp + loop1)->kind,(pp + loop2)->kind, PRODUCT) > 0){ 156 bfData = *(pp + loop1 ); 157 *(pp + loop1) = *(pp + loop2); 158 *(pp + loop2)= bfData; 159 } 160 } 161 } 162} 163 164/*金額降順ソート関数*/ 165void sortPrice(DATAout *po, int line){ 166 DATAout bfData = {"\0", "\0", 0}; 167 int loop1 = 0; 168 int loop2 = 0; 169 for (loop1 = 0; loop1 < line; loop1++) { 170 for (loop2 = loop1 + 1; loop2 < line; loop2++) { 171 if((po + loop1)->total < (po + loop2)->total) { 172 bfData = *(po + loop1); 173 *(po + loop1) = *(po + loop2); 174 *(po + loop2) = bfData; 175 } 176 } 177 } 178} 179 180/*ファイル操作関数*/ 181DATAin* readFile(char filename[], DATAin **pl, int *cntF){ 182 FILE *fp = NULL; 183 DATAin *pp = NULL; 184 int cntData = 0; 185 int loop1 = 0; 186 int cntSame = 0; 187 int ret = 0; 188 static int listCount = 0; 189 char str[LINEDATAMAX] = "\n"; 190 191 if(listCount == 0){ 192 *pl = (DATAin*)malloc(sizeof(DATAin)); 193 if (*pl == NULL){ 194 printf("malloc error「pl」\n"); 195 return NULL; 196 } 197 } 198 199 pp = (DATAin*)malloc(sizeof(DATAin)); 200 if (pp == NULL){ 201 free(*pl); 202 printf("malloc error「pp」\n"); 203 return NULL; 204 } 205 206 fp=fopen(filename, "r"); 207 if(fp == NULL){ 208 free(*pl); 209 free(pp); 210 printf("%s file not open\n",filename); 211 return NULL; 212 }else{ 213 *cntF = *cntF + 1; 214 } 215 216 /*inputfileから情報を抽出*/ 217 while(fgets(str, LINEDATAMAX, fp) != NULL){ 218 ret = sscanf(str, "%[^,],%[^,],%d,%d", (pp + cntData)->name,\ 219 (pp + cntData)->kind, &(pp + cntData)->price, &(pp + cntData)->sales); 220 if( ret == EOF ) { 221 free(*pl); 222 free(pp); 223 printf( "sscanf error\n" ); 224 fclose(fp); 225 return NULL; 226 } 227 /*商品名リスト作成*/ 228// if(listCount == 0){ 229// strncpy((*pl)->kind, (pp + cntData)->kind, PRODUCT); 230// listCount = listCount + 1; 231// *pl = realloc(*pl,sizeof(DATAin) * (listCount + 1)); 232// }else{ 233// cntSame = 0; 234// for (loop1 = 0; loop1 < listCount; loop1++) { 235// if(strncmp((*pl + loop1)->kind, (pp + cntData)->kind, PRODUCT) == 0) { 236// /* 重複している*/ 237// cntSame = 1; 238// } 239// } 240// if(cntSame == 0){ 241// 242// strncpy((*pl + listCount)->kind, (pp + cntData)->kind, PRODUCT); 243// listCount = listCount + 1; 244// *pl = realloc(*pl,sizeof(DATAin) * (listCount + 1)); 245// } 246// } 247 248 cntData = cntData + 1; 249 pp = realloc(pp,sizeof(DATAin) * (cntData + 1)); 250 } 251 /*配列の終端に\0を代入(PRODUCTNAME分)*/ 252 strncpy((*pl + listCount)->kind, "\0\0\0\0\0\0\0", PRODUCT); 253 strncpy((pp + cntData)->kind, "\0\0\0\0\0\0\0", PRODUCT); 254 255 fclose(fp); 256 return pp; 257} 258 259/*メモリ開放関数*/ 260void reduceMemory(DATAin *mIn, DATAin *mL, int cntF){ 261 int loop1 = 0; 262 263 if(mL != NULL){ 264 free(mL); 265 } 266// for(loop1 = 0; loop1 < FILEMAX; loop1++){ 267// if(&mIn[loop1] != NULL){ 268// free(&mIn[loop1]); 269// } 270// } 271 free(&mIn[0]); 272} 273

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

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

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

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

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

gentaro

2021/01/24 21:25

> 完成前後で見比べて考えたいので、見本で関数化して頂きたいです。 そういうのを「丸投げ」という。 https://teratail.com/help/avoid-asking こういうの見ると知的生産活動で食ってる人間全員をナメてんのか?と思う。 誰かに完成形のコードを書いて欲しいなら正当な報酬を用意してクラウドソーシングで依頼しよう。
退会済みユーザー

退会済みユーザー

2021/01/25 00:21 編集

> ポインタ参照が難しくて上手く関数化できない 原因がはっきりしているなら、ポインタについて勉強すれば解決しますね。基礎をすっ飛ばして結果だけ得ようとすると、今後も同じようなケースで同じような質問を繰り返す事になりますので、きちんと勉強しましょう。ポインタについてならここの短い回答欄での答えより、C言語の書籍やWebサイトを検索して調べた方が多くの情報が集まります。
dodox86

2021/01/25 01:07

更に加えれば、先の質問を片付けてから(理解できないなら、理解できるよう勉強してから)取り組みましょう。 [アドレスの一般的な使い方とは] https://teratail.com/questions/317984 回答やコメントをいただいているのにないがしろにすると、回答者はどんどん離れていきます。
guest

回答1

0

たとえば

(ppL + loop1)->kind


ppL[loop1].kind
のように、

(ポインタ+数)->メンバ を ポインタ[数].メンバ に置き換えるとこから始めてはいかがか。

投稿2021/01/24 22:11

episteme

総合スコア16612

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.36%

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

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

質問する

関連した質問