構造体2

課題5

下記のプログラムでは、学生の成績データを構造体として取り扱っている。 構造体1の課題1と異なり、ここでは、

点であるが、実行結果は構造体1の課題1と同じになる。下記のプログラムを struct5.cとして保存しコンパイルして、 実行結果の通り正しく実行されるか確認せよ。

#include <stdio.h>
#define NUM 4

int main(void)
{
  int i;
  typedef struct student{
	char name[20];
	int english;
	int math;
	int japanese;
  }STUDENT;

  STUDENT data[]={{"佐藤", 82, 72, 58},
		{"秋山", 77, 82, 79}, 
		{"永田", 52, 62, 39}, 
		{"藤田", 61, 82, 88}}; 
  STUDENT *p;


  /* ポインタ変数pにdataの先頭のアドレスを渡す */
  p = data;

  for(i=0; i<NUM; i++){

    printf("%10s: 英語=%3d   数学=%3d   国語=%3d\n", p->name, p->english, p->math, p->japanese);

    /* アドレスの移動 */
    p++;
  }

  return 0;
}
(実行結果)
hp3225[susaki]502:~/program% ./a.out
      佐藤: 英語= 82   数学= 72   国語= 58
      秋山: 英語= 77   数学= 82   国語= 79
      永田: 英語= 52   数学= 62   国語= 39
      藤田: 英語= 61   数学= 82   国語= 88

課題6

上記の課題5において、ポインタが参照するアドレスを表示したい。下記の プログラムをstruct6.cとして保存しコンパイルして、実行結果を確認せよ。

#include <stdio.h>
#define NUM 4

int main(void)
{
  int i;
  typedef struct student{
	char name[20];
	int english;
	int math;
	int japanese;
  }STUDENT;

  STUDENT data[]={{"佐藤", 82, 72, 58},
		{"秋山", 77, 82, 79}, 
		{"永田", 52, 62, 39}, 
		{"藤田", 61, 82, 88}}; 
  STUDENT *p;
  int adr_name, adr_english, adr_math, adr_japanese;


  /* ポインタ変数pにdataの先頭のアドレスを渡す */
  p = data;

  for(i=0; i<NUM; i++){

    printf("%10s: 英語=%3d   数学=%3d   国語=%3d\n", p->name, p->english, p->math, p->japanese);

    adr_name = (int)&p->name;
    adr_english = (int)&p->english;
    adr_math = (int)&p->math;
    adr_japanese = (int)&p->japanese;

    printf("(アドレス)名前=%X: 英語=%X  数学=%X   国語=%X\n", adr_name, adr_english, adr_math, adr_japanese);

    printf("(アドレス): 英語のアドレス-名前のアドレス=%d\n", adr_english-adr_name);
    printf("(アドレス): 数学のアドレス-英語のアドレス=%d\n", adr_math-adr_english);
    printf("(アドレス): 国語のアドレス-数学のアドレス=%d\n\n", adr_japanese-adr_math);

    /* アドレスの移動 */
    p++;
  }

  return 0;
}
(実行結果)
hp3225[susaki]504:~/program% ./a.out
      佐藤: 英語= 82   数学= 72   国語= 58
(アドレス)名前=BFFFFB18: 英語=BFFFFB2C  数学=BFFFFB30   国語=BFFFFB34
(アドレス): 英語のアドレス-名前のアドレス=20
(アドレス): 数学のアドレス-英語のアドレス=4
(アドレス): 国語のアドレス-数学のアドレス=4

      秋山: 英語= 77   数学= 82   国語= 79
(アドレス)名前=BFFFFB38: 英語=BFFFFB4C  数学=BFFFFB50   国語=BFFFFB54
(アドレス): 英語のアドレス-名前のアドレス=20
(アドレス): 数学のアドレス-英語のアドレス=4
(アドレス): 国語のアドレス-数学のアドレス=4

      永田: 英語= 52   数学= 62   国語= 39
(アドレス)名前=BFFFFB58: 英語=BFFFFB6C  数学=BFFFFB70   国語=BFFFFB74
(アドレス): 英語のアドレス-名前のアドレス=20
(アドレス): 数学のアドレス-英語のアドレス=4
(アドレス): 国語のアドレス-数学のアドレス=4

      藤田: 英語= 61   数学= 82   国語= 88
(アドレス)名前=BFFFFB78: 英語=BFFFFB8C  数学=BFFFFB90   国語=BFFFFB94
(アドレス): 英語のアドレス-名前のアドレス=20
(アドレス): 数学のアドレス-英語のアドレス=4
(アドレス): 国語のアドレス-数学のアドレス=4

課題7

ファーストフード店において、セットメニューの価格を計算するプログラムを作成した い。セット価格は、セットに含まれる単品価格の合計の1割引し、 10円未満を切り捨てた金額としたい。 その価格の計算部分が*******で隠されている。

また、この課題ではセットBの価格だけを計算するが、ポインタを使用した 構造体の接続部分も*******で隠されている。 *******で隠された部分を補ってstruct7.cとして保存し、 実行結果の通り正しく実行されるか確認せよ。

#include <stdio.h>

int main(void)
{
  int i, total=0;

  struct tanpin{
	char		*name;
	int		price;
	struct tanpin	*p;
  };

  struct set{
	char		*set_name;
	int		set_price;
	struct tanpin	*p;
  };

  struct set s[]={{"セットA", 0, NULL},
		  {"セットB", 0, NULL},
		  {"セットC", 0, NULL},
		  {"セットD", 0, NULL}};

  struct tanpin burger[] = {{"ハンバーガー", 130, NULL},
		       {"チーズバーガー", 150, NULL},
		       {"チキンバーガー", 200, NULL}};

  struct tanpin drink = {"ドリンク", 130, NULL};
  struct tanpin potato = {"ポテト", 120, NULL};
  struct tanpin ice = {"アイスクリーム", 150, NULL};

  struct tanpin *pt;



  /* セットB:チーズバーガー,ドリンク,ポテト */
  /* セットBの単品をポインタで接続させることで,セットBを構成する */
  *****************************
  *****************************
  *****************************
  *****************************
  *****************************


  printf("***** %s *****\n", s[1].set_name);


  /* セットBの単品の価格をポインタで参照し、セットBの価格を計算する */
  for(pt = s[1].p; pt != NULL; pt = pt->p){
    total += pt->price;
    printf("%15s: %5d円\n", pt->name, pt->price);
  }
  printf(" ---------------------------\n");
  printf("       単価合計: %5d円\n", total);

  s[1].set_price = *****************************;      <- ここを補う
  printf("     セット価格: %5d円\n", s[1].set_price);

  return 0;
}
(実行結果)

hp3225[susaki]506:~/program% ./a.out
***** セットB *****
 チーズバーガー:   150円
       ドリンク:   130円
         ポテト:   120円
 ---------------------------
       単価合計:   400円
     セット価格:   360円

課題8

課題7においては、セットBのみのセット価格を計算した。選択されたセットの価格 をswitch文を用いて計算したい。課題7のプログラム中に示されたヒントを参考にし て、下記の******で隠された部分を補ってstruct8.cとして保存し、 実行結果の通り正しく実行されるか確認せよ。

#include <stdio.h>

int main(void)
{
  int i, total=0, select_num;

  struct tanpin{
	char		*name;
	int		price;
	struct tanpin	*p;
  };

  struct set{
	char		*set_name;
	int		set_price;
	struct tanpin	*p;
  };

  struct set s[]={{"セットA", 0, NULL},
		  {"セットB", 0, NULL},
		  {"セットC", 0, NULL},
		  {"セットD", 0, NULL}};

  struct tanpin burger[] = {{"ハンバーガー", 130, NULL},
		       {"チーズバーガー", 150, NULL},
		       {"チキンバーガー", 200, NULL}};

  struct tanpin drink = {"ドリンク", 130, NULL};
  struct tanpin potato = {"ポテト", 120, NULL};
  struct tanpin ice = {"アイスクリーム", 150, NULL};

  struct tanpin *pt;


  printf("お好きなセットを選んでください。0-3の数字でお答え下さい。\n");
  printf("  0:  セットA:ハンバーガー,ドリンク,ポテト\n");
  printf("  1:  セットB:チーズバーガー,ドリンク,ポテト\n");
  printf("  2:  セットC:チキンバーガー,ドリンク,ポテト\n");
  printf("  3:  セットD:チキンバーガー,ドリンク,ポテト,アイスクリーム\n");

  scanf("%d", &select_num);

  switch(select_num){

    case 0:	/* セットA:ハンバーガー,ドリンク,ポテト */
      *****************************
      *****************************
      *****************************
      *****************************
      *****************************

    case 1:	/* セットB:チーズバーガー,ドリンク,ポテト */
      *****************************
      *****************************
      *****************************
      *****************************
      *****************************

    case 2:	/* セットC:チキンバーガー,ドリンク,ポテト */
      *****************************
      *****************************
      *****************************
      *****************************
      *****************************

    case 3:	/* セットD:チキンバーガー,ドリンク,ポテト,アイスクリーム */
      *****************************
      *****************************
      *****************************
      *****************************
      *****************************
  }

  
  printf("***** %s *****\n", s[select_num].set_name);

  for(pt = s[select_num].p; pt != NULL; pt = pt->p){
    total += pt->price;
    printf("%15s: %5d円\n", pt->name, pt->price);
  }
  printf(" ---------------------------\n");
  printf("       単価合計: %5d円\n", total);

  s[select_num].set_price = *****************************;
  printf("     セット価格: %5d円\n", s[select_num].set_price);

  return 0;
}
(実行結果)

hp3225[susaki]508:~/program% ./a.out
お好きなセットを選んでください。0-3の数字でお答え下さい。
  0:  セットA:ハンバーガー,ドリンク,ポテト
  1:  セットB:チーズバーガー,ドリンク,ポテト
  2:  セットC:チキンバーガー,ドリンク,ポテト
  3:  セットD:チキンバーガー,ドリンク,ポテト,アイスクリーム
0
***** セットA *****
   ハンバーガー:   130円
       ドリンク:   130円
         ポテト:   120円
 ---------------------------
       単価合計:   380円
     セット価格:   340円


hp3225[susaki]509:~/program% 
hp3225[susaki]509:~/program% a.out
お好きなセットを選んでください。0-3の数字でお答え下さい。
  0:  セットA:ハンバーガー,ドリンク,ポテト
  1:  セットB:チーズバーガー,ドリンク,ポテト
  2:  セットC:チキンバーガー,ドリンク,ポテト
  3:  セットD:チキンバーガー,ドリンク,ポテト,アイスクリーム
1
***** セットB *****
 チーズバーガー:   150円
       ドリンク:   130円
         ポテト:   120円
 ---------------------------
       単価合計:   400円
     セット価格:   360円


hp3225[susaki]510:~/program% 
hp3225[susaki]510:~/program% a.out
お好きなセットを選んでください。0-3の数字でお答え下さい。
  0:  セットA:ハンバーガー,ドリンク,ポテト
  1:  セットB:チーズバーガー,ドリンク,ポテト
  2:  セットC:チキンバーガー,ドリンク,ポテト
  3:  セットD:チキンバーガー,ドリンク,ポテト,アイスクリーム
2
***** セットC *****
 チキンバーガー:   200円
       ドリンク:   130円
         ポテト:   120円
 ---------------------------
       単価合計:   450円
     セット価格:   400円


hp3225[susaki]511:~/program% 
hp3225[susaki]511:~/program% a.out
お好きなセットを選んでください。0-3の数字でお答え下さい。
  0:  セットA:ハンバーガー,ドリンク,ポテト
  1:  セットB:チーズバーガー,ドリンク,ポテト
  2:  セットC:チキンバーガー,ドリンク,ポテト
  3:  セットD:チキンバーガー,ドリンク,ポテト,アイスクリーム
3
***** セットD *****
 チキンバーガー:   200円
       ドリンク:   130円
         ポテト:   120円
 アイスクリーム:   150円
 ---------------------------
       単価合計:   600円
     セット価格:   540円

課題9

情報大前のバス停に到着する時刻を与えることで、何時何分に千葉駅に 到着するのか下記 の3つのルートに関して調べ、最も早く千葉駅に到着するルートを知りたい。

ルート1 情報大 - バス -> 千葉
ルート2 情報大 -バス-> 千城台 -モノレール-> 千葉
ルート3 情報大 -バス-> 都賀 -JR総武線-> 千葉

問題を簡単にするために、下記のような条件を設けるものとする。

この課題で仮想上設定した、各交通機関の時刻表、および乗り換え所要時間は下記の通りである。

交通機関 時刻表
バス
(千城台経由千葉行:情報大発車時刻)
03, 12, 19, 25, 32, 39, 44, 51, 57
バス(都賀行:情報大発車時刻) 18
モノレール(千城台発車時刻) 05, 15, 25, 35, 45, 55
JR総武線(都賀発車時刻) 04, 17, 31, 48
交通機関と区間 所用時間(分)
バス(情報大->千葉) 38
バス(情報大->千城台) 8
バス(情報大->都賀) 27
モノレール(千城台->千葉) 24
JR総武線(都賀->千葉) 6
各交通機関間の乗り換え 所要時間(分)
(バス->モノレール、バス->JR) 1

このような設定の元で、実行結果のような出力を得るプログラムを struct9.cとして完成させ、正しく実行されるか確認せよ。

注意: 構造体を使用して課題9を達成することを 期待するが、必ずしも構造体を使用しなければいけないわけではない。

(実行例)
hp3225[susaki]501:~/program% 
hp3225[susaki]501:~/program% ./a.out
情報大前のバス停に何時何分に到着しますか?(入力例: 16 25)42 7
  入力エラー: 正しく入力してください
  [0-23]時 [0-59]分 の間の数字を入れてください
hp3225[susaki]502:~/program% 
hp3225[susaki]502:~/program% ./a.out
情報大前のバス停に何時何分に到着しますか?(入力例: 16 25)16 25

***  情報大 -バス-> 千葉  ***
バス: 情報大 -> 千葉
  出発時刻:   16 時 25 分
  到着時刻:   17 時  3 分

***  情報大 -バス-> 千城台 -モノレール-> 千葉  ***
バス: 情報大 -> 千城台
  出発時刻:   16 時 25 分
  到着時刻:   16 時 33 分
  乗り換え後: 16 時 34 分
モノレール: 千城台 -> 千葉
  出発時刻:   16 時 35 分
  到着時刻:   16 時 59 分

***  情報大 -バス-> 都賀 -総武線各駅-> 千葉  ***
バス: 情報大 -> 都賀
  出発時刻:   17 時 18 分
  到着時刻:   17 時 45 分
  乗り換え後: 17 時 46 分
JR: 都賀 -> 千葉
  出発時刻:   17 時 48 分
  到着時刻:   17 時 54 分

--- 最も早く千葉駅に着くルートは  ---
*** 情報大 -バス-> 千城台 -モノレール-> 千葉 ***
hp3225[susaki]503:~/program% 
hp3225[susaki]503:~/program% ./a.out
情報大前のバス停に何時何分に到着しますか?(入力例: 16 25)18 56

***  情報大 -バス-> 千葉  ***
バス: 情報大 -> 千葉
  出発時刻:   18 時 57 分
  到着時刻:   19 時 35 分

***  情報大 -バス-> 千城台 -モノレール-> 千葉  ***
バス: 情報大 -> 千城台
  出発時刻:   18 時 57 分
  到着時刻:   19 時  5 分
  乗り換え後: 19 時  6 分
モノレール: 千城台 -> 千葉
  出発時刻:   19 時 15 分
  到着時刻:   19 時 39 分

***  情報大 -バス-> 都賀 -総武線各駅-> 千葉  ***
バス: 情報大 -> 都賀
  出発時刻:   19 時 18 分
  到着時刻:   19 時 45 分
  乗り換え後: 19 時 46 分
JR: 都賀 -> 千葉
  出発時刻:   19 時 48 分
  到着時刻:   19 時 54 分

--- 最も早く千葉駅に着くルートは  ---
*** 情報大 -バス-> 千葉 ***
hp3225[susaki]504:~/program% 

須ア純一 京都大学大学院 工学研究科社会基盤工学専攻 空間情報学講座
[C言語 演習問題トップページ] [須ア純一ホームページ]