1. 程式人生 > 其它 >浙大版《C語言程式設計》第四版(何欽銘顏暉) 第9章 結構 課後習題答案

浙大版《C語言程式設計》第四版(何欽銘顏暉) 第9章 結構 課後習題答案

你也可以上程式咖(https://meta.chengxuka.com),開啟大學幕題板塊,不但有答案,講解,還可以線上答題。

一、選擇題

1.以下定義結構變數的語句中,錯誤的是( )。

A. struct student { int num; char name[ 20];} s;

B. struct { int num; char name[ 20] ;} s;

C. struct student { int num; char name[ 20] ;} ; student s;

D. struct student { int num; char name [ 20] ; } ; struct student s;

答:C

解析:

結構變數名可以在定義結構後單獨定義。也可以跟在結構後直接定義,直接寫結構變數名即可。

2.如果結構變數 s 中的生日是 “1984 年11月11日”,下列對其生日的正確賦值是( )。

struct student{
	int no; char name[20]; char sex;
	struct {
		int year; int month; int day;
	}birth;
}s;

A. year= 1984; month=11; day=11;

B. birth. year= 1984; birth. month=11; birth. day=11;

C. s. year= 1984; s. month=11; s. day=11;

D. s. birth. year= 1984; s. birth. month= 11; s. birth. day=11;

答:D

解析:

s 對應的結構為 student,birth 是它的一個成員,year,month,day 是birth的成員。所以要通過 s. birth. year= 1984; s. birth. month= 11; s. birth. day=11; 表示。

3.以下程式段的輸出結果為( )。

struct
	{
		int x, y;
	} s[2] = {{1, 3}, {2, 7}};
	printf("%d\n", s[0].y / s[1].x);

A.0

B.1

C.2

D.3

答:B

解析:

這裡列印的結果是 s[0].y / s[1].x,就是 3 / 2 的結果,是 1 。

4.沒有如下定義,則對data中的a成員的正確引用是( )。

struct sk{
	int a; double b;
}data, *p=&data;

A. (*p).data.a

B. (*p).a

C. p->data. a

D. p.data.a

答:B

解析:

這裡 *p 指向 data,想引用對應的 a,直接 (*p).a 即可。所以這裡選 B。

5.對於以下結構定義,++p->str中的++加在( )。

struct{
int len; char *str;
}*P;

A.指標 str 上

B.指標 p 上

C. str 指向的內容上

D.語法錯誤

答:D

解析:p 是指標,可以寫 p->str ,但是 (*p) 只能寫 (*p).str;

6.若有下列定義,則以下不合法的表示式是( )。

struct student
	{
		int num;
		int age;
	} stu[3] = {{101, 20}, {102, 19}, {103, 20}}, *p = stu;

A. (p++)->num

B. p++

C. (*p). num

D. p= &stu.age

答:D

解析:

p 是 struct student 型別的指標,stu.age 是 int 型變數,p 指向 stu.age 會產生型別不匹配的問題

二、填空題

1.寫出下面程式段的執行結果( )。

	struct example
	{
		struct
		{
			int x;
			int y;
		} in;
		int a;
		int b;
	} e;
	e.a = 1;
	e.b = 2;
	e.in.x = e.a * e.b;
	e.in.y = e.a + e.b;
	printf("%d,%d\n", e.in.x, e.in.y);

答:2,3

解析:

e.a = 1, e.b = 2,

e.in.x = e.a * e.b = 1 * 2 = 2

e.in.y = e.a + e.b = 1 + 2 = 3

最終列印 2 和 3。

2.時間計算。讀入時間數值,將其加 1 秒後輸出,時間格式為 "hh: mm: ss",即 "小時: 分鐘: 秒",當小時等於 24 小時,置為 0 。請填空。

#include <stdio.h>
struct
{
	int hour, minute, second;
} time;
int main()
{
	scanf("%d:%d:%d", _______________);
	time.second++;
	if ( _______________ == 60)
	{
		_______________;
		time.second = 0;
		if (time.minute == 60)
		{
			time.hour++;
			time.minute = 0;
			if ( _______________ == 24)
			{
				time.hour = 0;
			}
		}
	}
	printf("%d:%d:%d\n", time.hour, time.minute, time.second);
	return 0;
}

答:

&time.hour, &time.minute, &time.second

time.second

time.minute++

time.hour

解析:

第一空,&time.hour, &time.minute, &time.second,讀入時間的時,分,秒。然後根據題意,給秒加 1。

第二空,time.second == 60,判斷秒是否是 60。

第三空,time.minute++,如果是,那麼分鐘累加 1,秒置為 0。然後判斷分鐘是否是 60,如果是,時就累加 1,然後分鐘置為 0 。

第四空,time.hour == 24,如果時為 24,要將時置為 0 ,表示第二天了。

3."." 稱為( )運算子,"->" 稱為( )運算子。

答:分量 指向

解析:

. 叫做結構成員操作符。用於訪問結構成員。

-> 叫做指向運算子。用於訪問指標指向的結構成員。

4.寫出下面程式段的執行結果( )。

	struct example
	{
		int a;
		double b;
		char *c;
	} x = {23, 98.5, "wang"}, *px = &x;
	printf("%d,%s,%.1f,%s\n", x.a, x.c, (*px).b, px->c);

答:23,wang,98.5,wang

解析:

列印語句中,先列印 x.a ,就是 23,然後列印 x.c ,就是 wang,然後 (*px).b,這裡 px 指向 x,列印的就是 98.5,px->c,列印 wang。

5.寫出下面程式段的執行結果( )。

	struct table
	{
		int x, y;
	} a[4] = {{10, 20}, {30, 40}, {50, 60}, {70, 80}};
	struct table *p = a;
	printf("%d,", p++->x);
	printf("%d,", ++p->y);
	printf("%d\n", (a + 3)->x);

答:10,41,70

解析:

第一行列印:p++->x,最初 p 指向陣列 a 的第一個元素,列印它的 x,值為 10。然後 p指向下一個元素。

第二行列印:此時 p 指向第二個元素{30,40},++p->y,這裡表示取 p->y,40,然後 ++ ,列印 41。

第三行列印:(a + 3)->x,a+3 表示裡面下標為 3 的元素,就是 {70,80},取 x 打印出 70。

6.寫出下面程式段的執行結果( )。

struct
	{
		int a;
		int *b;
	} s[4], *p;
	int i, n = 1;
	for (i = 0; i < 4; i++)
	{
		s[i].a = n;
		s[i].b = &s[i].a;
		n = n + 2;
	}
	p = &s[0];
	printf("%d\n", ++*p->b);
	p++;
	printf("%d,%d\n", (++p)->a, (p++)->a);

答:

2

5,5

解析:

for 迴圈中主要是為了給陣列 s 中的 4 個元素賦值。

s[0] 中 a 和 b 分別是 1。

s[1] 中 a 和 b 分別是 3。

s[2] 中 a 和 b 分別是 5。

s[3] 中 a 和 b 分別是 7。

第一行列印語句,++*p->b ,這裡取 *p 指向陣列中的第一個元素,取 b 的值,就是 1。然後有個前置的 ++ ,所以列印的是 2。

第二行列印語句,(++p)->a,在這之前,上面有一行單獨的 p++,那麼 p 會指向陣列中第二個元素,這裡 (++p) 後,那麼 p 就指向了陣列第三個元素,列印 它的 a,就是 5。再列印 (p++)->a,這裡 (p++),還是先運算再累加 1,所以還是列印第三個元素的 a,然後 p 指向第四個元素。

三、程式設計題

題目1:時間換算:用結構型別表示時間內容(時間以時、分、秒錶示),輸入一個時間數值,再輸入一個秒數 n(n<60),以 h: m: s 的格式輸出該時間再過 n 秒後的時間值(超過 24 點就從 0 點開始計時)。試編寫相應程式。

答案程式碼:

#include <stdio.h>

struct time
{
	int hour;
	int minute;
	int second;
};

void add(struct time *p, int s);

int main()
{
	// 習題(9.3.1)
	/*
	時間換算:用結構型別表示時間內容(時間以時、分、秒錶示),輸入一個時間數值,
	再輸入一個秒數 n(n<60),以 h: m: s 的格式輸出該時間再過 n 秒後的時間值(超過 24 點就從 0 點開始計時)。
	*/

	struct time c;
	int n;
	printf("input time:");
	scanf("%d%d%d", &c.hour, &c.minute, &c.second);
	printf("input n:");
	scanf("%d", &n);
	add(&c, n);
	printf("%d: %d: %d\n", c.hour, c.minute, c.second);
	return 0;
}

void add(struct time *p, int s)
{
	int ho, mi, se;
	ho = p->hour;
	mi = p->minute;
	se = p->second;
	se = se + s;
	if (se < 60)
	{
		p->second = se;
		return;
	}
	else
	{
		mi = p->minute = mi + se / 60;
		se = p->second = se % 60;
		if (mi < 60)
		{
			return;
		}
		else
		{
			mi = p->minute = mi % 60;
			ho = ho + mi / 60;
			mi = p->hour = mi % 60;
		}
		if (ho < 24)
		{
			return;
		}
		else
			mi = p->hour = mi % 24;
		return;
	}
}

執行結果:

題目2:計算兩個複數之積:編寫程式,利用結構變數求解兩個複數之積。

提示:求解 (a1+a2i)x(b1+b2i), 乘積的實部為: a1xb1-a2xb2 ,虛部為: a1xb2+a2xb1。

答案程式碼:

#include <stdio.h>
struct complex
{
	int real, im;
};
struct complex cmult(struct complex, struct complex);
int main()
{
	// 習題(9.3.2)
	/*
	計算兩個複數之積:編寫程式,利用結構變數求解兩個複數之積。

	提示:求解 (a1+a2i)x(b1+b2i), 乘積的實部為: a1xb1-a2xb2 ,虛部為: a1xb2+a2xb1。
	*/

	struct complex a = {3, 4}, b = {5, 6}, c;
	c = cmult(a, b);
	printf("(%d+%di)x(%d+%di) =%d+%di\n", a.real, a.im, b.real, b.im, c.real, c.im);
	return 0;
}
struct complex cmult(struct complex a, struct complex b)
{
	struct complex w;
	w.real = a.real * b.real - a.im * b.im;
	w.im = a.real * b.im + a.im * b.real;
	return w;
}

執行結果:

題目3:平面向量加法:輸入兩個二維平面向量 V1=(x1, y1) 和 V2=(x2, y2) 的分量,計算並輸出兩個向量的和向量。試編寫相應程式。

答案程式碼:

#include <stdio.h>

struct vector
{
	double x;
	double y;
};

struct vector vector_add(struct vector v1, struct vector v2);

int main()
{
	// 習題(9.3.3)
	/*
	平面向量加法:輸入兩個二維平面向量 V1=(x1, y1) 和 V2=(x2, y2) 的分量,計算並輸出兩個向量的和向量。
	*/

	struct vector v1, v2, sum;
	double s1, s2;
	printf("input first vector:\n");
	scanf("%lf%lf", &v1.x, &v1.y);
	printf("input second vector:\n");
	scanf("%lf%lf", &v2.x, &v2.y);

	sum = vector_add(v1, v2);
	printf("(%.1lf, %.1lf)\n", sum.x, sum.y);

	return 0;
}

struct vector vector_add(struct vector v1, struct vector v2)
{
	struct vector sum;
	double s1, s2;
	s1 = v1.x + v2.x;
	s2 = v1.y + v2.y;
	sum.x = s1;
	sum.y = s2;
	return sum;
}


執行結果:

題目4:查詢書籍:從鍵盤輸入 10 本書的名稱和定價並存入結構陣列中,從中查詢定價最高和最低的書的名稱和定價,並輸出。試編寫相應程式。

答案程式碼:

#include <stdio.h>

#define NUMBER 10
struct book
{
	char name[30];
	float price;
};
int main()
{
	// 習題(9.3.4)
	/*
	查詢書籍:從鍵盤輸入 10 本書的名稱和定價並存入結構陣列中,從中查詢定價最高和最低的書的名稱和定價,並輸出。
	*/
	int i, max1, min1;
	struct book test[NUMBER];
	printf("input 10 book's name and price\n");
	for (i = 0; i < NUMBER; i++)
		scanf("%s%f", test[i].name, &test[i].price);
	max1 = min1 = 0;
	for (i = 1; i < NUMBER; i++)
	{
		if (test[max1].price < test[i].price)
			max1 = i;
		if (test[min1].price > test[i].price)
			min1 = i;
	}
	printf("Max Price: %.2f, %s\n", test[max1].price, test[max1].name);
	printf("Min Price: %.2f, %s\n", test[min1].price, test[min1].name);
	return 0;
}

執行結果:

題目5:通訊錄排序:建立一個通訊錄,通訊錄的結構記錄包括:姓名、生日、電話號碼;其中生日又包括三項:年、月、日。編寫程式,定義一個巢狀的結構型別,輸入 n(n<10)個聯絡人的資訊,再按他們的年齡從大到小的順序依次輸出其資訊。試編寫相應程式。

答案程式碼:

#include <stdio.h>
struct birth
{
	int year;
	int month;
	int date;
};

struct friends_list
{
	char name[10];		   /*姓名*/
	struct birth birthday; /*生日*/
	char phone[15];		   /*電話號碼*/
	char address[50];	   /*住址*/
};
void sort(struct friends_list s[], int n) /*按生日日期從小到大排序*/
{
	int i, j;
	struct friends_list temp;
	for (i = 1; i < n; i++)
		for (j = 0; j < n - i; j++)
			// 先判斷年份
			if (s[j].birthday.year > s[j + 1].birthday.year)
			{
				temp = s[j];
				s[j] = s[j + 1];
				s[j + 1] = temp;
			}
			else if (s[j].birthday.year == s[j + 1].birthday.year)
			{
				if (s[j].birthday.month > s[j + 1].birthday.month)
				{
					temp = s[j];
					s[j] = s[j + 1];
					s[j + 1] = temp;
				}
				else if (s[j].birthday.month == s[j + 1].birthday.month)
				{
					if (s[j].birthday.date > s[j + 1].birthday.date)
					{
						temp = s[j];
						s[j] = s[j + 1];
						s[j + 1] = temp;
					}
				}
			}
}

int main()
{
	// 習題(9.3.5)
	/*
	通訊錄排序:建立一個通訊錄,通訊錄的結構記錄包括:姓名、生日、電話號碼;
	其中生日又包括三項:年、月、日。編寫程式,定義一個巢狀的結構型別,
	輸入 n(n<10)個聯絡人的資訊,再按他們的年齡從大到小的順序依次輸出其資訊。
	*/
	int i, n;
	struct friends_list friends[10];
	printf("input n:");
	scanf("%d", &n);
	for (i = 0; i < n; i++) /*輸入 n個人的通訊資訊*/
	{
		printf("請輸入第 %d 個人的資訊: 姓名 年 月 日 手機號 地址\n", i + 1);
		scanf("%s%d%d%d%s%s", friends[i].name, &friends[i].birthday.year, &friends[i].birthday.month, &friends[i].birthday.date, friends[i].phone, friends[i].address);
	}
	printf("------------------------------------------------------------------------\n");
	printf("通訊錄資訊:\n");
	for (i = 0; i < n; i++)
		/*輸出*/
		printf("%s\t%d\t%d\t%d\t%s\t%s\n", friends[i].name, friends[i].birthday.year, friends[i].birthday.month, friends[i].birthday.date, friends[i].phone, friends[i].address);
	printf("------------------------------------------------------------------------\n");
	printf("排序後資訊:\n");
	/*按年齡從大到小排序*/
	sort(friends, n);
	for (i = 0; i < n; i++)
		/*輸出*/
		printf("%s\t%d\t%d\t%d\t%s\t%s\n", friends[i].name, friends[i].birthday.year, friends[i].birthday.month, friends[i].birthday.date, friends[i].phone, friends[i].address);

	return 0;
}

執行結果:

題目6:按等級統計學生成績:輸入 10 個學生的學號、姓名和成績,輸出學生的成績等級和不及格人數。每個學生的記錄包括學號、姓名、成績和等級,要求定義和呼叫函式set_grade(),根據學生成績設定其等級,並統計不及格人數,等級設定: 85~100 為 A ,70~84 為 B , 60~69 為 C , 0~59 為 D。試編寫相應程式。

答案程式碼:

#include <stdio.h>
#define N 10
struct student
{
	int num;
	char name[20];
	int score;
	char grade;
};

int set_grade(struct student *p);

int main()
{
	// 習題(9.3.6)
	/*
	按等級統計學生成績:輸入 10 個學生的學號、姓名和成績,輸出學生的成績等級和不及格人數。
	每個學生的記錄包括學號、姓名、成績和等級,要求定義和呼叫函式set_grade(),根據學生成績設定其等級,並統計不及格人數,
	等級設定: 85~100 為 A ,70~84 為 B , 60~69 為 C , 0~59 為 D。
	*/

	struct student stu[N], *ptr;
	int i, count;
	ptr = stu;
	printf("input the student's number, name and score: \n");
	for (i = 0; i < N; i++)
	{
		printf("No %d:", i + 1);
		scanf("%d%s%d", &stu[i].num, stu[i].name, &stu[i].score);
	}
	count = set_grade(ptr);
	printf("The count (<60): %d\n", count);
	printf("The student grade:\n");
	for (i = 0; i < N; i++)
		printf("%d\t%s\t%c\n", stu[i].num, stu[i].name, stu[i].grade);
	return 0;
}

//等級設定
int set_grade(struct student *p)
{
	int i, n = 0;
	for (i = 0; i < N; i++, p++)
	{
		if (p->score >= 85)
			p->grade = 'A';
		else if (p->score >= 70)
			p->grade = 'B';
		else if (p->score >= 60)
			p->grade = 'C';
		else
		{
			p->grade = 'D';
			n++;
		}
	}
	return n;
}

執行結果: