構造体の練習課題(C言語・コンソール)
構造体を利用する練習問題を2問提示します。 どちらも「構造体を使う前のコード」を確認し、構造体で書き換える内容です。
ファイル名: shop_before.c
#include <stdio.h>
int main(void) {
char name0[20] = "ポーション";
int price0 = 50;
int stock0 = 5;
char name1[20] = "ハーブ";
int price1 = 30;
int stock1 = 3;
char name2[20] = "エーテル";
int price2 = 120;
int stock2 = 2;
int choice;
int qty;
int total = 0;
printf("=== お店 ===\n");
printf("0:%s(%dG) 在庫:%d\n", name0, price0, stock0);
printf("1:%s(%dG) 在庫:%d\n", name1, price1, stock1);
printf("2:%s(%dG) 在庫:%d\n", name2, price2, stock2);
printf("買う番号(0-2): ");
if (scanf("%d", &choice) != 1) return 0;
printf("個数: ");
if (scanf("%d", &qty) != 1) return 0;
if (choice == 0) {
if (qty > 0 && qty <= stock0) {
stock0 = stock0 - qty;
total = total + price0 * qty;
} else { printf("在庫不足\n"); }
} else if (choice == 1) {
if (qty > 0 && qty <= stock1) {
stock1 = stock1 - qty;
total = total + price1 * qty;
} else { printf("在庫不足\n"); }
} else if (choice == 2) {
if (qty > 0 && qty <= stock2) {
stock2 = stock2 - qty;
total = total + price2 * qty;
} else { printf("在庫不足\n"); }
} else {
printf("番号が不正です\n");
}
printf("合計=%dG\n", total);
return 0;
}
課題:構造体で書き換えなさい
提出ファイル名(構造体版):shop_struct.c
typedef struct { char name[20]; int price; int stock; } Item;Item items[3] に初期データを入れる(strcpy 使用・#include <string.h>)。void print_menu(Item a[], int n))。buy() 関数を定義する。引数で値渡し+戻り値で在庫更新を反映させる(例:items[i] = buy(items[i], qty);)。for (i = 0; i < 3; i++) を使うと、3商品に同じ処理を適用できます。buy() 関数の戻り値の型は Item(構造体)です。在庫を減らした後、更新済みの Item を return します。-1 が入力されたら break するなど。scanf を使うには、SDLチェックをオフにするか scanf_s を使います(詳細は08章参照)。#include <stdio.h>
#include <string.h>
typedef struct {
char name[20];
int price;
int stock;
} Item;
void print_menu(Item a[], int n) {
int i;
printf("=== お店 ===\n");
for (i = 0; i < n; i++) {
printf("%d:%s(%dG) 在庫:%d\n", i, a[i].name, a[i].price, a[i].stock);
}
}
/* 購入処理:更新後の Item を返す */
Item buy(Item it, int qty, int *total) {
if (qty > 0 && qty <= it.stock) {
it.stock = it.stock - qty;
*total = *total + it.price * qty;
} else {
printf("在庫不足\n");
}
return it;
}
int main(void) {
Item items[3];
int choice, qty, total;
strcpy(items[0].name, "ポーション"); items[0].price = 50; items[0].stock = 5;
strcpy(items[1].name, "ハーブ"); items[1].price = 30; items[1].stock = 3;
strcpy(items[2].name, "エーテル"); items[2].price = 120; items[2].stock = 2;
total = 0;
while (1) {
print_menu(items, 3);
printf("買う番号(0-2, -1で終了): ");
if (scanf("%d", &choice) != 1) break;
if (choice == -1) break;
if (choice < 0 || choice > 2) { printf("番号が不正です\n"); continue; }
printf("個数: ");
if (scanf("%d", &qty) != 1) break;
items[choice] = buy(items[choice], qty, &total);
}
printf("合計=%dG\n", total);
return 0;
}ファイル名: field_before.c
#include <stdio.h>
int main(void) {
int width = 5;
int height = 5;
int px, py; /* プレイヤー座標 */
int ex, ey; /* 敵の座標 */
char key;
int x, y;
px = 0; py = 0;
ex = 4; ey = 4;
printf("w/a/s/d で1歩移動\n");
printf("入力: ");
if (scanf(" %c", &key) != 1) return 0;
if (key == 'w') py = py - 1;
else if (key == 's') py = py + 1;
else if (key == 'a') px = px - 1;
else if (key == 'd') px = px + 1;
if (px < 0) px = 0;
if (px > width - 1) px = width - 1;
if (py < 0) py = 0;
if (py > height - 1) py = height - 1;
for (y = 0; y < height; y++) {
for (x = 0; x < width; x++) {
if (x == px && y == py) printf("P");
else if (x == ex && y == ey) printf("E");
else printf(".");
}
printf("\n");
}
if (px == ex && py == ey) {
printf("遭遇!\n");
}
return 0;
}
課題:構造体で書き換えなさい
提出ファイル名(構造体版):field_struct.c
typedef struct { int x; int y; } Pos;typedef struct { char name[16]; Pos pos; } Actor;Actor で表現し、strcpy で名前を入れる(#include <string.h>)。Actor move(Actor a, char key, int w, int h))。void draw(int w, int h, Actor p, Actor e))。Actor は Pos 型のメンバ pos を持ちます。
プレイヤーの x 座標へのアクセスは player.pos.x と2段階のドットで辿ります。
move() 関数の中で a.pos.x や a.pos.y を更新し、更新済みの a を return します。draw() 関数は Actor を2つ(プレイヤーと敵)受け取り、ネストした for ループで盤面を描きます。p.pos.x == e.pos.x && p.pos.y == e.pos.y です。#include <stdio.h>
#include <string.h>
typedef struct { int x; int y; } Pos;
typedef struct {
char name[16];
Pos pos;
} Actor;
/* 移動処理:更新後の Actor を返す */
Actor move(Actor a, char key, int w, int h) {
if (key == 'w') a.pos.y--;
else if (key == 's') a.pos.y++;
else if (key == 'a') a.pos.x--;
else if (key == 'd') a.pos.x++;
if (a.pos.x < 0) a.pos.x = 0;
if (a.pos.x > w - 1) a.pos.x = w - 1;
if (a.pos.y < 0) a.pos.y = 0;
if (a.pos.y > h - 1) a.pos.y = h - 1;
return a;
}
/* 盤面描画 */
void draw(int w, int h, Actor p, Actor e) {
int x, y;
for (y = 0; y < h; y++) {
for (x = 0; x < w; x++) {
if (x == p.pos.x && y == p.pos.y) printf("P");
else if (x == e.pos.x && y == e.pos.y) printf("E");
else printf(".");
}
printf("\n");
}
}
int main(void) {
Actor player, enemy;
char key;
int w = 5, h = 5;
strcpy(player.name, "player"); player.pos.x = 0; player.pos.y = 0;
strcpy(enemy.name, "enemy"); enemy.pos.x = 4; enemy.pos.y = 4;
printf("w/a/s/d で1歩移動\n");
printf("入力: ");
if (scanf(" %c", &key) != 1) return 0;
player = move(player, key, w, h);
draw(w, h, player, enemy);
if (player.pos.x == enemy.pos.x && player.pos.y == enemy.pos.y) {
printf("遭遇!\n");
}
return 0;
}