当日のOHP資料です。
12.構造体
Download : sample-000.c ( SJIS 版 )
/* * [参考] list 12-1 (text p.268) */ /* * 5 人の学生の <<身長>> を昇順にソート */ #include <stdio.h> #define NUMBER 5 /* 学生の人数 */ /* x および y が指す整数の値を交換 */ void swap ( int *x, int *y ) { int temp = *x; *x = *y; *y = temp; } /* 配列 data の先頭 n 個の要素を昇順にソート */ void sort ( int data[], int size ) { /* 素直な実装 */ int sort_end; /* ソートが済でない場所の最終位置 */ int looking; /* 比較する場所 */ /* n 個のデータの隣合った二つの組み合わせは nC2 = n(n-1)/2 */ for ( sort_end = size - 1; sort_end > 0; sort_end-- ) { /* - 最初は、全然ソートが済んでいないので、sort_end の場所は、配列の最後 (size-1) - sort_end が 0 になるということは、ソートの対象が 1 個になったという事なので、 それ以上の作業は不要 ( 一個のデータはそれだけで、ソートされている ) - ソートが済んでいない場所を一通りチェックすると、一番大きいデータが、最後まで「沈んで」 来るので、sort_end は一つ減らしてよい */ for ( looking = 0; looking < sort_end; looking++ ) { /* - ソート済みでない場所 ( 0 〜 sort_end ) を先頭 (0) から眺めて (looking) ゆく - 眺めている場所(looking)が、ソート済みの最後 ( sort_end ) になったら、 一通り眺めた事になる ( その隣は調べる必要がない ) - 眺める場所は、頭から順に一つずつ */ if ( data[ looking ] > data[ looking + 1 ] ) { /* 眺めている場所 (looking) とその隣 ( looking + 1 ) が不整合ならば */ swap( &data[looking], &data[looking + 1] ); /* データを交換して、整合化する */ } } } } int main ( void ) { int i; int height[] = { 178, 175, 173, 165, 179 }; sort ( height, NUMBER ); for ( i = 0; i < NUMBER; i++ ) { printf ( "%2d : %4d\n", i + 1, height[i] ); } return 0; }
C:\usr\c\> sample-000 1 : 165 2 : 173 3 : 175 4 : 178 5 : 179 C:\usr\c\>
Download : sample-001.c ( SJIS 版 )
/* * [参考] list 12-1 (text p.268) */ /* * 5 人の学生の <<身長>> を昇順にソート */ #include <stdio.h> #define NUMBER 5 /* 学生の人数 */ /* x および y が指す整数の値を交換 */ void swap ( int *x, int *y ) { int temp = *x; *x = *y; *y = temp; } /* 配列 data の先頭 n 個の要素を昇順にソート */ void sort ( int data[], int n ) { int k = n - 1; while ( k >= 0 ) { int i, j; for ( i = 1, j = -1; i <= k; i++ ) { if ( data[ i - 1 ] > data[ i ] ) { j = i - 1; swap( &data[i], &data[j] ); } } k = j; } } int main ( void ) { int i; int height[] = { 178, 175, 173, 165, 179 }; sort ( height, NUMBER ); for ( i = 0; i < NUMBER; i++ ) { printf ( "%2d : %4d\n", i + 1, height[i] ); } return 0; }
C:\usr\c\> sample-001 1 : 165 2 : 173 3 : 175 4 : 178 5 : 179 C:\usr\c\>
Download : sample-002.c ( SJIS 版 )
/* * [参考] list 12-2 (text p.271) */ /* * 5 人の学生の <<名前と身長>> を、身長の昇順にソート */ #include <stdio.h> #include <string.h> #define NUMBER 5 /* 学生の人数 */ #define NAME_SIZE 20 /* <<名前>> の最大の長さ -1 */ /* x および y が指す整数の値を交換 */ void swap ( int *x, int *y ) { int temp = *x; *x = *y; *y = temp; } /* sx および sy が指す文字列を交換 */ void swaps ( char sx[NAME_SIZE], char sy[NAME_SIZE] ) { char temp[NAME_SIZE]; strcpy ( temp, sx ); strcpy ( sx, sy ); strcpy ( sy, temp ); } /* 配列 data と name の先頭 n 個の要素を昇順にソート */ void sort ( int data[], char name[][NAME_SIZE], int n ) { int k = n - 1; while ( k >= 0 ) { int i, j; for ( i = 1, j = -1; i <= k; i++ ) { if ( data[ i - 1 ] > data[ i ] ) { j = i - 1; swap( &data[i], &data[j] ); swaps( name[i], name[j] ); } } k = j; } } int main ( void ) { int i; int height[] = { 178, 175, 173, 165, 179 }; char name[][NAME_SIZE] = { "Sato", "Sanake", "Takao", "Mike", "Masaki" }; sort ( height, name, NUMBER ); for ( i = 0; i < NUMBER; i++ ) { printf ( "%2d : %-8s%4d\n", i + 1, name[i], height[i] ); } return 0; }
C:\usr\c\> sample-002 1 : Mike 165 2 : Takao 173 3 : Sanake 175 4 : Sato 178 5 : Masaki 179 C:\usr\c\>
Download : sample-003.c ( SJIS 版 )
/* * [参考] list 12-3 (text p.274) */ /* * 学生を表す構造体で表した佐中君 */ #include <stdio.h> #include <string.h> #define NAME_SIZE 20 /* <<名前>> の最大の長さ -1 */ /* 学生を表す構造体 */ struct gstudent { char name[NAME_SIZE]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ long schols; /* 奨学金 */ }; int main ( void ) { struct gstudent sanaka; strcpy ( sanaka.name, "Sanaka" ); /* 名前 */ sanaka.height = 175; /* 身長 */ sanaka.weight = 60.5; /* 体重 */ sanaka.schols = 70000; /* 奨学金 */ printf ( "名 前 = %s\n", sanaka.name ); printf ( "身 長 = %d\n", sanaka.height ); printf ( "体 重 = %f\n", sanaka.weight ); printf ( "奨学金 = %ld\n", sanaka.schols ); return 0; }
C:\usr\c\> sample-003 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 70000 C:\usr\c\>
Download : sample-004.c ( SJIS 版 )
/* * [参考] list 12-3 (text p.274) */ /* * 学生を表す構造体で表した佐中君の初期化 */ #include <stdio.h> #include <string.h> #define NAME_SIZE 20 /* <<名前>> の最大の長さ -1 */ /* 学生を表す構造体 */ struct gstudent { char name[NAME_SIZE]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ long schols; /* 奨学金 */ }; int main ( void ) { struct gstudent sanaka = { "Sanaka", 175, 60.5 }; printf ( "名 前 = %s\n", sanaka.name ); printf ( "身 長 = %d\n", sanaka.height ); printf ( "体 重 = %f\n", sanaka.weight ); printf ( "奨学金 = %ld\n", sanaka.schols ); return 0; }
C:\usr\c\> sample-004 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 0 C:\usr\c\>
Download : sample-005.c ( SJIS 版 )
/* * 構造体型変数の代入 : 佐中君の双子の兄弟 */ #include <stdio.h> #include <string.h> #define NAME_SIZE 20 /* <<名前>> の最大の長さ -1 */ /* 学生を表す構造体 */ struct gstudent { char name[NAME_SIZE]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ long schols; /* 奨学金 */ }; /* 佐中君と双子の兄弟 */ int main ( void ) { struct gstudent sanaka = { "Sanaka", 175, 60.5 }; /* 佐中君 */ struct gstudent twin; /* 双子 */ twin = sanaka; /* 佐中君と同じ */ twin.schols = 50000; /* 奨学金は別 */ printf ( "[佐中君の情報]\n" ); printf ( "名 前 = %s\n", sanaka.name ); printf ( "身 長 = %d\n", sanaka.height ); printf ( "体 重 = %f\n", sanaka.weight ); printf ( "奨学金 = %ld\n", sanaka.schols ); printf ( "[双子の兄弟の情報]\n" ); printf ( "名 前 = %s\n", twin.name ); printf ( "身 長 = %d\n", twin.height ); printf ( "体 重 = %f\n", twin.weight ); printf ( "奨学金 = %ld\n", twin.schols ); return 0; }
C:\usr\c\> sample-005 [佐中君の情報] 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 0 [双子の兄弟の情報] 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 50000 C:\usr\c\>
Download : sample-006.c ( SJIS 版 )
/* * 関数への構造体型の値の受渡し (No.2) */ #include <stdio.h> #include <string.h> #define NAME_SIZE 20 /* <<名前>> の最大の長さ -1 */ /* 学生を表す構造体 */ struct gstudent { char name[NAME_SIZE]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ long schols; /* 奨学金 */ }; /* 構造体で表現された学生情報の表示 */ void print_student ( struct gstudent student ) { printf ( "名 前 = %s\n", student.name ); printf ( "身 長 = %d\n", student.height ); printf ( "体 重 = %f\n", student.weight ); printf ( "奨学金 = %ld\n", student.schols ); } /* 佐中君と双子の兄弟 */ int main ( void ) { struct gstudent sanaka = { "Sanaka", 175, 60.5 }; /* 佐中君 */ struct gstudent twin; /* 双子 */ twin = sanaka; /* 佐中君と同じ */ twin.schols = 50000; /* 奨学金は別 */ printf ( "[佐中君の情報]\n" ); print_student ( sanaka ); printf ( "[双子の兄弟の情報]\n" ); print_student ( twin ); return 0; }
C:\usr\c\> sample-006 [佐中君の情報] 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 0 [双子の兄弟の情報] 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 50000 C:\usr\c\>
Download : sample-007.c ( SJIS 版 )
/* * 関数への構造体型の値の受渡し (No.2) */ #include <stdio.h> #include <string.h> #define NAME_SIZE 20 /* <<名前>> の最大の長さ -1 */ /* 学生を表す構造体 */ struct gstudent { char name[NAME_SIZE]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ long schols; /* 奨学金 */ }; /* 構造体で表現された学生情報の表示 */ void print_student ( struct gstudent student ) { printf ( "名 前 = %s\n", student.name ); printf ( "身 長 = %d\n", student.height ); printf ( "体 重 = %f\n", student.weight ); printf ( "奨学金 = %ld\n", student.schols ); } /* 構造体で表現された学生情報の情報の変更 (失敗例) */ void set_schols ( struct gstudent student, long new_schols ) { printf ( "以前の奨学金 = %ld\n", student.schols ); student.schols = new_schols; printf ( "新規の奨学金 = %ld\n", student.schols ); } /* 佐中君と双子の兄弟 */ int main ( void ) { struct gstudent sanaka = { "Sanaka", 175, 60.5 }; /* 佐中君 */ struct gstudent twin; /* 双子 */ twin = sanaka; /* 佐中君と同じ */ set_schols ( twin, 50000 ); /* 奨学金を与える事に */ printf ( "[佐中君の情報]\n" ); print_student ( sanaka ); printf ( "[双子の兄弟の情報]\n" ); print_student ( twin ); return 0; }
C:\usr\c\> sample-007 以前の奨学金 = 0 新規の奨学金 = 50000 [佐中君の情報] 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 0 [双子の兄弟の情報] 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 0 C:\usr\c\>
Download : sample-008.c ( SJIS 版 )
/* * 関数への構造体型の値の受渡し (No.3) */ #include <stdio.h> #include <string.h> #define NAME_SIZE 20 /* <<名前>> の最大の長さ -1 */ /* 学生を表す構造体 */ struct gstudent { char name[NAME_SIZE]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ long schols; /* 奨学金 */ }; /* 構造体で表現された学生情報の表示 */ void print_student ( struct gstudent student ) { printf ( "名 前 = %s\n", student.name ); printf ( "身 長 = %d\n", student.height ); printf ( "体 重 = %f\n", student.weight ); printf ( "奨学金 = %ld\n", student.schols ); } /* 構造体で表現された学生情報の情報の変更 (成功例:ポインターを利用) */ void set_schols ( struct gstudent *ptr_student, long new_schols ) { printf ( "以前の奨学金 = %ld\n", (*ptr_student).schols ); (*ptr_student).schols = new_schols; printf ( "新規の奨学金 = %ld\n", (*ptr_student).schols ); } /* 佐中君と双子の兄弟 */ int main ( void ) { struct gstudent sanaka = { "Sanaka", 175, 60.5 }; /* 佐中君 */ struct gstudent twin; /* 双子 */ twin = sanaka; /* 佐中君と同じ */ set_schols ( &twin, 50000 ); /* 奨学金を与える事に */ printf ( "[佐中君の情報]\n" ); print_student ( sanaka ); printf ( "[双子の兄弟の情報]\n" ); print_student ( twin ); return 0; }
C:\usr\c\> sample-008 以前の奨学金 = 0 新規の奨学金 = 50000 [佐中君の情報] 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 0 [双子の兄弟の情報] 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 50000 C:\usr\c\>
Download : sample-009.c ( SJIS 版 )
/* * [参考] list 12-5 (text p.277) */ /* * 超能力をもったひろ子さん */ #include <stdio.h> #include <string.h> #define NAME_SIZE 20 /* <<名前>> の最大の長さ -1 */ /* 学生を表す構造体 */ struct gstudent { char name[NAME_SIZE]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ long schols; /* 奨学金 */ }; /* 構造体で表現された学生情報の表示 */ void print_student ( struct gstudent student ) { printf ( "名 前 = %s\n", student.name ); printf ( "身 長 = %d\n", student.height ); printf ( "体 重 = %f\n", student.weight ); printf ( "奨学金 = %ld\n", student.schols ); } /* 身長を伸ばし、体重を減らしてくれるひろ子さん */ void hiroko ( struct gstudent *ptr_student ) { if ( (*ptr_student).height < 180 ) { /* 身長が低いと... */ (*ptr_student).height = 180; /* 背を伸ばしてくれる */ } if ( (*ptr_student).weight > 80.0 ) { /* 体重が重いと... */ (*ptr_student).weight = 80.0; /* 痩せさせてくれる */ } } /* ひろ子さんの超能力で、ダイエット */ int main ( void ) { struct gstudent sanaka = { "Sanaka", 175, 60.5, 70000 }; printf ( "[ダイエット前]\n" ); print_student ( sanaka ); hiroko ( &sanaka ); /* ひろ子さん.. */ printf ( "[ダイエット後]\n" ); print_student ( sanaka ); return 0; }
C:\usr\c\> sample-009 [ダイエット前] 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 70000 [ダイエット後] 名 前 = Sanaka 身 長 = 180 体 重 = 60.500000 奨学金 = 70000 C:\usr\c\>
Download : sample-010.c ( SJIS 版 )
/* * [参考] list 12-6 (text p.278) */ /* * 超能力をもったひろ子さん (その 2) */ #include <stdio.h> #include <string.h> #define NAME_SIZE 20 /* <<名前>> の最大の長さ -1 */ /* 学生を表す構造体 */ typedef struct gstudent { char name[NAME_SIZE]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ long schols; /* 奨学金 */ } Student; /* 構造体で表現された学生情報の表示 */ void print_student ( Student student ) { printf ( "名 前 = %s\n", student.name ); printf ( "身 長 = %d\n", student.height ); printf ( "体 重 = %f\n", student.weight ); printf ( "奨学金 = %ld\n", student.schols ); } /* 身長を伸ばし、体重を減らしてくれるひろ子さん */ void hiroko ( Student *ptr_student ) { if ( ptr_student -> height < 180 ) { /* 身長が低いと... */ ptr_student -> height = 180; /* 背を伸ばしてくれる */ } if ( ptr_student -> weight > 80.0 ) { /* 体重が重いと... */ ptr_student -> weight = 80.0; /* 痩せさせてくれる */ } } /* ひろ子さんの超能力で、ダイエット */ int main ( void ) { Student sanaka = { "Sanaka", 175, 60.5, 70000 }; printf ( "[ダイエット前]\n" ); print_student ( sanaka ); hiroko ( &sanaka ); /* ひろ子さん.. */ printf ( "[ダイエット後]\n" ); print_student ( sanaka ); return 0; }
C:\usr\c\> sample-010 [ダイエット前] 名 前 = Sanaka 身 長 = 175 体 重 = 60.500000 奨学金 = 70000 [ダイエット後] 名 前 = Sanaka 身 長 = 180 体 重 = 60.500000 奨学金 = 70000 C:\usr\c\>
構造体を利用したプログラムを作成する
/* * [課題] 20091211-1 */ /* * 5 人の学生の <<名前と体重>> を、体重の昇順にソート */ #include <stdio.h> #include <string.h> #define NUMBER 5 /* 学生の人数 */ #define NAME_SIZE 20 /* <<名前>> の最大の長さ -1 */ /* fx および fy が指す浮動小数点数の値を交換 */ void swapf ( float *fx, float *fy ) { /* ** この部分を完成させなさい */ } /* sx および sy が指す文字列を交換 */ void swaps ( char sx[NAME_SIZE], char sy[NAME_SIZE] ) { char temp[NAME_SIZE]; strcpy ( temp, sx ); strcpy ( sx, sy ); strcpy ( sy, temp ); } /* 配列 data と name の先頭 n 個の要素を昇順にソート */ void sort ( float data[], char name[][NAME_SIZE], int n ) { /* ** この部分を完成させなさい */ } int main ( void ) { int i; float weight[] = { 72.0, 60.5, 62.5, 85.0, 70.5 }; char name[][NAME_SIZE] = { "Sato", "Sanake", "Takao", "Mike", "Masaki" }; sort ( weight, name, NUMBER ); for ( i = 0; i < NUMBER; i++ ) { printf ( "%2d : %-8s%4f\n", i + 1, name[i], weight[i] ); } return 0; }
C:\usr\c\> 20101217-1 1 : Sanake 60.500000 2 : Takao 62.500000 3 : Masaki 70.500000 4 : Sato 72.000000 5 : Mike 85.000000 C:\usr\c\>
/* * [課題] 20091211-2 */ /* * キーボードから学生情報を入力し、構造体に収める関数 */ #include <stdio.h> #include <string.h> #define NAME_SIZE 20 /* <<名前>> の最大の長さ -1 */ /* 学生を表す構造体 */ typedef struct gstudent { char name[NAME_SIZE]; /* 名前 */ int height; /* 身長 */ float weight; /* 体重 */ long schols; /* 奨学金 */ } Student; /* 構造体で表現された学生情報の表示 */ void print_student ( Student student ) { printf ( "名 前 = %s\n", student.name ); printf ( "身 長 = %d\n", student.height ); printf ( "体 重 = %f\n", student.weight ); printf ( "奨学金 = %ld\n", student.schols ); } /* 構造体で表現された学生情報の情報の入力 (ポインターを利用) */ void scan_student ( Student *ptr_student ) { printf ( "名 前 を入力してください\n" ); /* ** この部分を完成させなさい */ printf ( "身 長 を入力してください\n" ); /* ** この部分を完成させなさい */ printf ( "体 重 を入力してください\n" ); /* ** この部分を完成させなさい */ printf ( "奨学金 を入力してください\n" ); /* ** この部分を完成させなさい */ } /* データの入力 */ int main ( void ) { Student sanaka; /* scan_student を呼び出し、佐中君のデータをキーボードから入力する */ /* ** この部分を完成させなさい */ /* 佐中君のデータを出力する */ print_student ( sanaka ); return 0; }
Sanaka 180 60.5 70000
C:\usr\c\> 20101217-2 名 前 を入力してください 身 長 を入力してください 体 重 を入力してください 奨学金 を入力してください 名 前 = Sanaka 身 長 = 180 体 重 = 60.500000 奨学金 = 70000 C:\usr\c\>