当日の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\>