Microsoft Word - Cプログラミング演習(7)

Similar documents
Microsoft Word - Cプログラミング演習(10)

Microsoft Word - Cプログラミング演習(12)

バイオプログラミング第 1 榊原康文 佐藤健吾 慶應義塾大学理工学部生命情報学科

演算増幅器

Microsoft Word - Cプログラミング演習(11)

Microsoft PowerPoint - lec10.ppt

問 2 ( 型変換 ) 次のプログラムを実行しても正しい結果が得られない 何が間違いかを指摘し 正しく修正せよ ただし int サイズが 2 バイト long サイズが 4 バイトの処理系での演算を仮定する #include <stdio.h> int main( void ) { int a =

Taro-リストⅠ(公開版).jtd

Prog1_10th

char int float double の変数型はそれぞれ 文字あるいは小さな整数 整数 実数 より精度の高い ( 数値のより大きい より小さい ) 実数 を扱う時に用いる 備考 : 基本型の説明に示した 浮動小数点 とは数値を指数表現で表す方法である 例えば は指数表現で 3 書く

Microsoft PowerPoint - 12.ppt [互換モード]

計算機プログラミング

プログラミング方法論 II 第 14,15 回 ( 担当 : 鈴木伸夫 ) 問題 17. x 座標と y 座標をメンバに持つ構造体 Point を作成せよ 但し座標 は double 型とする typedef struct{ (a) x; (b) y; } Point; 問題 18. 問題 17 の

Taro-ポインタ変数Ⅰ(公開版).j

Microsoft PowerPoint - 12.ppt [互換モード]

kiso2-09.key

Microsoft Word - Cプログラミング演習(9)

Microsoft Word - Cプログラミング演習(8)

Microsoft PowerPoint - 13.ppt [互換モード]

Prog1_15th

Microsoft Word - no12.doc

Microsoft PowerPoint - CproNt02.ppt [互換モード]

Microsoft Word - 3new.doc

Microsoft Word - no15.docx

gengo1-2

(2) 構造体変数の宣言 文法は次のとおり. struct 構造体タグ名構造体変数名 ; (1) と (2) は同時に行える. struct 構造体タグ名 { データ型変数 1; データ型変数 2;... 構造体変数名 ; 例 : struct STUDENT{ stdata; int id; do

RX ファミリ用 C/C++ コンパイラ V.1.00 Release 02 ご使用上のお願い RX ファミリ用 C/C++ コンパイラの使用上の注意事項 4 件を連絡します #pragma option 使用時の 1 または 2 バイトの整数型の関数戻り値に関する注意事項 (RXC#012) 共用

プログラミング実習I

PowerPoint プレゼンテーション

Microsoft Word - no206.docx

cp-7. 配列

PowerPoint プレゼンテーション

Microsoft Word - no205.docx

02: 変数と標準入出力

Microsoft Word - no103.docx

Microsoft Word - Cプログラミング演習(3)

プログラミングI第10回

02: 変数と標準入出力

プログラミング基礎

1. 入力した正の整数を降順に並べ換えて出力するプログラムを作成せよ プログラムは個別にコンパイルし make コマンドで実行すること 入力データは 50 以下とし 以下の数が混在しているとする 16 進数 : 先頭 1 文字が x または X( エックスの小文字か大文字 ) 8 進数 : 先頭 1

Taro-リストⅢ(公開版).jtd

Microsoft Word - no13.docx

Microsoft Word - no11.docx

Microsoft PowerPoint - exp2-02_intro.ppt [互換モード]

Microsoft Word - no202.docx

Microsoft PowerPoint - 説明2_演算と型(C_guide2)【2015新教材対応確認済み】.pptx

Taro-スタック(公開版).jtd

gengo1-8

PowerPoint Presentation

memo

program7app.ppt

Microsoft PowerPoint - 13th.ppt [互換モード]

Microsoft Word - no02.doc

/*Source.cpp*/ #include<stdio.h> //printf はここでインクルードして初めて使えるようになる // ここで関数 average を定義 3 つの整数の平均値を返す double 型の関数です double average(int a,int b,int c){

Microsoft PowerPoint - 5Chap15.ppt

Microsoft Word - Training10_プリプロセッサ.docx

02: 変数と標準入出力

Microsoft PowerPoint pptx

Microsoft PowerPoint - 11.ppt [互換モード]

PowerPoint プレゼンテーション

gengo1-11

02: 変数と標準入出力

PowerPoint Presentation

02: 変数と標準入出力

JavaプログラミングⅠ

PowerPoint プレゼンテーション

Microsoft PowerPoint - 計算機言語 第7回.ppt

ポインタ変数

第3回 配列とリスト

講習No.9

第2回

プログラミング基礎

プログラミング基礎

Microsoft PowerPoint pptx

PowerPoint プレゼンテーション

memo

02: 変数と標準入出力

PowerPoint Template

<4D F736F F D20438CBE8CEA8D758DC03389F0939A82C282AB2E646F63>

C 資料 電脳梁山泊烏賊塾 構造体 C++ の構造体 初めに 此処では Visual Studio 2017 を起動し 新しいプロジェクトで Visual C++ の Windows デスクトップを選択し Windows コンソールアプリケーションを作成する 定義と変数宣言 C++ に

Microsoft PowerPoint - handout07.ppt [互換モード]

Microsoft PowerPoint - 09.pptx

Microsoft PowerPoint - 説柔5_間勊+C_guide5ï¼›2015ã•’2015æŒ°æŁŽæš’å¯¾å¿œç¢ºèª“æ¸‹ã†¿ã•‚.pptx

Microsoft Word - Cプログラミング演習(1)_2012

講習No.12

Prog1_6th

1. 関数 scanf() 関数 printf() は変数の値を画面に表示しますが それに対し関数 scanf() はキーボードで入力した値を変数に代入します この関数を活用することで対話式 ( ユーザーの操作に応じて処理を行う ) プログラムを作ることができるようになります 整数の和

02: 変数と標準入出力

memo

PowerPoint プレゼンテーション

C プログラミング演習 1( 再 ) 2 講義では C プログラミングの基本を学び 演習では やや実践的なプログラミングを通して学ぶ

02: 変数と標準入出力

Microsoft PowerPoint - kougi7.ppt

PowerPoint プレゼンテーション

Taro-再帰関数Ⅱ(公開版).jtd

第2回講義:まとめ

数値計算

次に示す数値の並びを昇順にソートするものとする このソートでは配列の末尾側から操作を行っていく まず 末尾の数値 9 と 8 に着目する 昇順にソートするので この値を交換すると以下の数値の並びになる 次に末尾側から 2 番目と 3 番目の 1

プログラミング実習I

プログラミング基礎

Transcription:

第 7 回 (6/4) 2. 構造体 構造体とは, 同じ型に限定されない複数の関連するデータメンバの集合である 構造体の宣言構造体指定子 struct を用いて struct 構造体タグ名 { メンバ 1 の宣言 ; メンバ 2 の宣言 ; メンバ n の宣言 ; }; 注 ) 構造体タグ名は構造体の型名で, 内容を定義するものでオブジェクトではなく, 論理的なテンプレートである 構造体の変数の宣言実際の記憶領域を占める物理的実体を確保する struct 構造体タグ名変数リスト ; または構造体の宣言と合わせて struct 構造体タグ名 { メンバ 1 の宣言 ; メンバ 2 の宣言 ; メンバ n の宣言 ; } 変数リスト ; あるいは struct { メンバ 1 の宣言 ; メンバ 2 の宣言 ; メンバ n の宣言 ; } 変数リスト ;

例. 構造体の宣言と初期化 struct sintai { char *name; int sinchou; int taijuu; }; struct sintai a = {"Jack", 180, 66 }, b = {"Betty", 172, 59 }; 構造体の参照ドット演算子を用いて 構造体の変数名. メンバ名 構造体配列の要素. メンバ名 ex. a.taijuu ex. constel[i].name 構造体に対する演算同じ型を持った構造体間では代入演算子が使用できてメンバ全部の複写ができる ex. sa = sb; 関数との関係構造体は, ほかの型の値とまったく同じように, 関数への仮引数として渡すことができる また, 関数の戻り値として, 構造体を返すこともできる

例. 構造体のメンバにアクセスするいくつかの方法を示す #include <stdio.h> struct s_type { int i; char ch; double d; char str[80]; } s; int main() { printf(" 整数を入力して下さい :\n"); scanf("%d", &s.i); printf(" 文字を入力して下さい :\n"); scanf("\n%c, &s.ch); printf(" 浮動小数点数を入力して下さい :\n"); scanf("%lf", &s.d); printf(" 文字列を入力して下さい :\n"); scanf("%s", s.str); printf("%d %c %f %s\n", s.i, s.ch, s.d, s.str); } return 0;

例. 構造体のサイズを調べる #include <stdio.h> struct s_type { int i; char ch; int *p; double d; } s; int main() { printf("s_type は %d バイトの長さである \n", sizeof(struct s_type)); } return 0; s_type のサイズを求めるのに,sizeof(struct s_type) 以外の書き方は?

構造体へのポインタの宣言構造体にアクセスするにはポインタを利用するのが一般的な方法である 構造体を指すポインタを用いて構造体のメンバにアクセスするときは, アロー演算子 ( -> ) を使用する 例. 構造体を指すポインタの扱い方を示す #include <stdio.h> #include <string.h> struct s_type { int i; char str[80]; } s, *p; int main() { p = &s; s.i = 10; p->i = 15; strcpy(p->str, "I like structure"); printf("%d %d %s\n", s.i, p->i, p->str); } return 0;

ビットフィールド構造体の便利な機能として, ビット単位でデータを取り扱うことができるビットフィールドがある 構造体メンバとしてビットフィールドを定義するには次の書式を用いる 型名前 : サイズ ; 但し, 型 は int または unsigned signed の場合, 最上位ビットは符号ビットと見なされる 移植可能にするには,signed あるいは unsigned と明示的に指定すべきである サイズ はフィールドでのビット数ビットフィールドを参照するには, 通常の構造体と同じように. または -> 演算子によってメンバを指定する 例. ビットフィールドと他の型を混在させることが可能であり, またバイトやワードのすべてのビットが埋まるように定義する必要はない struct b_type { char name[40]; /* 品目名 */ unsigned int instock: 1; /* 在庫があれば 1, 在庫切れなら 0 */ unsigned int backordered: 1; /* 未納注文であれば 1, 納品済みなら 0 */ unsigned int lead_time: 3; /* 発注から納品までの月数 (7 ヶ月まで ) */ } inv[max_item]; 注 ) メモリのアドレス可能な最小単位はバイトであるため, ビットフィールド変数のアドレスを得ることはできない ビットフィールドには, ブール ( 真 / 偽 ) 型のデータを格納することがよくある 1 バイトに 8 個のブール型の値を格納できる

補足例題 a, b, c の3つのビットフィールドを持つ構造体 ( タグ名 b_type, 変数名 bvar) を使ったプログラムを作りなさい a と b は 3 ビットの長さとし,c は 2 ビットの長さとする また, すべて signed 変数とする 次に,bvar の a, b, c にそれぞれ値 -1, 3, 1 を代入し, その値を表示しなさい #include <stdio.h> main() { struct b_type { signed int a: 3; /* a, b, c それぞれ表現できる値の範囲は? */ signed int b: 3; signed int c: 2; } bvar; } bvar.a = -1; /* -5 を代入するとどうなるか */ bvar.b = 3; bvar.c = 1; /* 3 を代入するとどうなるか */ printf("%d %d %d\n", bvar.a, bvar.b, bvar.c); printf("size of b_type = %d\n", sizeof(struct b_type));

共用体複数のメンバが同じメモリの領域を共通して使用するように配置された単一のメモリ領域のことを指す メモリを共用する変数は, 型が異なってもいいが, 一度に1つの変数しか使用できない 共用体指定子 union を用いて次の書式で宣言する union 共用体タグ名 { メンバ 1 の宣言 ; メンバ 2 の宣言 ; メンバ n の宣言 ; } 変数名 ; 注 ) タグ名, 変数名のいずれかを省略することができる 例. union u_type { int i; char c[4]; double d; } sample, *p; d c[0] c[1] c[2] c[3] i 共用体のメンバを参照するには, 構造体と同様, ドット演算子もしくはアロー演算子を使用する

注意 共用体のサイズは, 最も大きいメンバのサイズとなるが, コンパイラがワード境界でそろえることがあり,sizeof 演算子で確認した方がよい また, 一度に1つの変数しか使用できないことに注意しよう #include <stdio.h> main() { union u_type { int i; char c[4]; double d; } sample, *p; } p = &sample; sample.i = 1234; printf("int i : %d\n", sample.i); p->c[0] = 'O'; p->c[1] = 'K'; p->c[2] = '\0'; printf("char c[4] : %s\n", sample.c); p->d = 12.34; printf("double d : %f\n", sample.d); printf("size of b_type = %d\n", sizeof(union u_type));

例題 3-2 生まれた月と日を入力し, 星座が何であるかを出力するプログラムをつくりなさい ただし, 誕生日と星座の関係は次のとおりである 山羊 (12/13~1/20), 水瓶 (~2/18), 魚 (~3/20), 牡羊 (~4/20), 牡牛 (~5/21), 双子 (~6/21), 蟹 (~7/23), 獅子 (~8/23), 乙女 (~9/23), 天秤 (~10/23), さそり (~11/22), 射手 (~12/22) 出力結果 3-2 何月生まれですか? 3 何日生まれですか? 26 3 月 26 日生まれのあなたは, 牡羊座です

プログラム 3-2 01 /* E3-2 */ 02 /* 星座調べ */ 03 #include <stdio.h> 04 05 struct { 06 char name[9]; 07 int date; 08 } constel[] = { " 山羊 ", 120, " 水瓶 ", 218, " 魚 ", 320, 09 " 牡羊 ", 420, " 牡牛 ", 521, " 双子 ", 621, 10 " 蟹 ", 723, " 獅子 ", 823, " 乙女 ", 923, 11 " 天秤 ", 1023, " さそり ", 1122, 12 " 射手 ", 1222, " 山羊 ", 1231 }; 13 14 main() 15 { 16 int i, month, day, nconstel; 17 18 printf("\n 何月生まれですか?\n"); 19 scanf("%d", &month); 20 printf(" 何日生まれですか?\n"); 21 scanf("%d", &day); 22 nconstel = sizeof constel / sizeof constel[0]; /* 配列の要素数 */ 23 for (i = 0; i < nconstel; i++) { 24 if (month * 100 + day <= constel[i].date) 25 break; 26 } 27 printf("\n%d 月 %d 日生まれの ", month, day); 28 printf(" あなたは,%s 座です \n", constel[i].name); 29 }

練習問題 25 1. 例題 3-2のプログラムでは,12 月 32 日などが入力されると正しい結果が得られない これを防止するため, 誤った月日のデータが入力された場合は再度入力させるようにプログラムを変更しなさい ヒント 各月が何日まであるかを格納した配列を用意して利用しなさい 2. 前問 1. において, 構造体のメンバに対して, constel[i].data constel[i].name と記述しているのを,-> 演算子によって記述するようにプログラムを変更しなさい ヒント 構造体へのポインタを宣言して, これを用いなさい

3. 姓, 名, 年齢, 郵便番号, 電話番号の各データをメンバとする構造体配列を下記のように宣言し, その構造体配列にキーボードからデータを逐次入力して, 最大 100 名のデータを格納できるようにしなさい 但し, 入力の終了は, 姓入力の際に null と入力することによって判定しなさい また, 入力が終了した時点で, 格納された複数名のデータをすべて出力するようにしなさい #define MAXREC 100 struct namelist { char last_name[21], first_name[21]; int age; char zip[9], tel[13]; } meibo[maxrec]; 出力例 Last name( 終了は null 入力 )> Natsume First name > Soseki Age > 49 Zip code > 123-4567 Telephone > 0120-1234567 Last name( 終了は null 入力 )> null Name : Soseki Natsume Age : 49 Zip code : 123-4567 Telephone: 0120-1234567

4. 前問において, 入力が終了した時点で, 格納された複数名のデータを郵便番号順に出力するようにプログラムを変更しなさい ヒント 構造体 struct namelist へのポインタおよび格納した人数を仮引数として, 郵便番号順にデータの並べ替えを行う次のような関数 void namelist_sort(struct namelist *pnt, int count) を作りなさい 以前に解いた次の問題が参考になります ================================================================================ [ 参考 ] 練習問題 20 ポインタの配列 (*name[10]) を宣言し, 次のような名前を 10 個セットしなさい "taro", "jiro", "hanako", "hirosi", "keiko" この名前をアルファベット順に整列 ( 並べ換え ) させるプログラムをポインタへのポインタを使ってつくりなさい ヒント 文字列の比較にはライブラリ関数の strcmp(s1, s2) を利用すればよい この関数の戻り値は, 次のようになる s1 > s2 のとき, 0 より大きい整数 s1 = s2 のとき, 0 s1 < s2 のとき, 0 より小さい整数 ================================================================================

5.( 難問 ) 共用体を用いて,2 バイト整数の上下バイトを入れ換えて暗号化する関数 short encode(short) を作り, キーボードから入力した整数を暗号化 / 復号化するプログラムを作りなさい 但し,main 関数の部分は次のコードを用いなさい /* 関数のプロトタイプ宣言 */ short encode(short); main() { int n, m, k; } while (1) { printf(" 整数を入力して下さい ( 終了は 0) = "); scanf("%d", &n); if (n == 0) break; m = encode(n); /* 暗号化 */ printf("\n\t%d を暗号化すると %d になります \n", n, m); k = encode(m); /* 復号化 */ printf("\n\t%d を復号化すると %d になります \n\n", m, k); } 出力例 整数を入力して下さい ( 終了は 0)= 123 123 を暗号化すると 31488 になります 31488 を復号化すると 123 になります 整数を入力して下さい ( 終了は 0)= -123-123 を暗号化すると-31233 になります -31233 を復号化すると-123 になります 整数を入力して下さい ( 終了は 0)= 0

6.( 超難問 ) 整数係数の多項式について, その次数と係数をキーボードから入力して連結リストに格納してみましょう 次に, 格納された多項式を画面に出力します 最後に,X の実数値をキーボードから入力して多項式の値を求めてみましょう 多項式の次数と係数を表現する構造体, および必要な関数のプロトタイプ宣言を次に示します 出力例を参考にして, プログラムを完成してみましょう typedef struct Node { int pow; /* 次数 */ int coe; /* 整数係数 */ struct Node *next; /* 次のノードを指すポインタ */ } node; node *start = NULL; /* 先頭ノードを指すポインタで最初は空, 外部変数 */ void insert(int pow, int coe); /* 次数と係数をノードとして挿入 */ void show_poly(); /* 連結リストに格納された多項式の表示 */ double horner(double x); /* 実数 x に対する多項式の値の算出 */ 出力例 整数次数の多項式を入力します! 最大次数を入力してください :5 小さい次数から整数係数を順に入力してください X^0 の整数係数 :-1 X^1 の整数係数 :2 X^2 の整数係数 :3 X^3 の整数係数 :0 X^4 の整数係数 :0 X^5 の整数係数 :-1

多項式は次の通り -X^5+3X^2+2X-1 X の値を入力してください :0.8 多項式の値は 2.192320 です ヒント 次のプログラムは, キーボードから整数を順に読み込んで, それらを連結リストに格納して, 最後にそれらを入力と逆順に表示するものです これを参考に, 連結リストの扱いを理解して, 上記問題のプログラムを作成してみなさい /* キーボードから整数を読み, 連結リストに格納 */ #include <stdio.h> #include <stdlib.h> typedef struct Node { int num; struct Node *next; } node; node *start = NULL; void ins(int x); main() { int x; node *p; printf(" 整数を空白で区切って入力してください \n"); printf(" 終了には数字以外の文字を入力します \n\n"); while (scanf("%d", &x) == 1) ins(x); printf("\n 入力された数字を逆順に表示します \n");

} for (p = start; p!= NULL; p = p->next) printf("%5d\n", p->num); void ins(int x) { node *p = start; start = (node *)malloc(sizeof(node)); if (start == NULL) puts(" メモリ不足です \n"), exit(1); start->num = x; start->next = p; }