daan511Word文件下载.docx
《daan511Word文件下载.docx》由会员分享,可在线阅读,更多相关《daan511Word文件下载.docx(7页珍藏版)》请在冰点文库上搜索。
}
(2)若有以下程序段:
doublea=99.99,b=11.11;
SWAP(double,a,b);
则SWAP(double,a,b)展开后有:
{doublew;
w=a;
a=b;
b=w;
};
此处w是一个局部变量,它的作为域仅在复合语句内部,与程序中任何与其同名的变量无关。
(3)请读者自编程序,调用以上带参的宏,对各种类型数据进行交换。
参数t对应的应当是类型名。
13.12【分析与解答】
(1)请编写一个swap函数,用于对两个整型变量中的值进行对调。
(2)定义3个基类型为int的指针变量p1、p2和p3。
(3)3次调用malloc函数,分别使p1、p2和p3指向三个动态分配的存储单元。
程序准备把最小数放在p1所指动态存储单元中,把最大数放在p3所指动态存储单元中。
(4)调用scanf函数给p1、p2和p3所指的3个动态分配存储单元赋值。
(5)以下语句输出p1、p2和p3所指的动态存储单元中的值:
printf(″\[KG-*3]n*[KG-*3]p1=%dp2=%dp3=%d\[KG-*3]n\[KG-*3]n″,*[KG-*3]p1,*[KG-*3]p2,*[KG-*3]p3);
(6)如果p2所指的动态存储单元中的值小于p1所指的动态存储单元中的值,则调用swap函数把这两个存储单元中的值进行交换,使大数放入p2所指的动态存储单元中,小数放入p1所指动态存储单元中:
if(*[KG-*3]p2<
*[KG-*3]p1)swap(p1,p2);
(7)如果p3所指的动态存储单元中的值小于p1所指的动态存储单元中的值,则调用swap函数把这两个存储单元中的值进行交换,使小数放入p1所指的动态存储单元中。
(8)如果p3所指的动态存储单元中的值小于p2所指的动态存储单元中的值,则调用swap函数把这两个存储单元中的值进行交换,使小数放入p2所指的动态存储单元中。
(9)以上步骤已把最小的数放入p1所指的动态存储单元中,最大的数放入p3所指的动态存储单元中。
输出这3个指针所指的存储单元中的值,以便验证结果是否正确。
(10)本题的算法应该已很熟悉,只是要求用动态存储单元来代替普通的变量。
第十四章结构体、共用体和用户定义类型习题分析与解答一、选择题
14.1【参考答案】D)14.2【参考答案】D)14.3【参考答案】D)14.4【参考答案】A)14.5【参考答案】C)14.6【参考答案】C)14.7【参考答案】C)14.8【参考答案】B)
二、填空题14.9【参考答案】structlink*next14.10【参考答案】[1]p->
next[2]m>
p->
data(或p->
data<
m)
14.11【参考答案】[1](structlist*)[2]structlist[3](structlist*)[4]structlist[5]h
三、编程题14.12【分析与解答】
(1)为了便于调试程序,定义宏名N来表示30:
#defineN30
(2)主函数中定义一个名为st的structstud类型的结构体数组,用以存放学生数据:
structstudst[N];
(3)readrec函数的首部可以写成:
voidreadrec(structstud*[KG-*3]ps)形参指针指向实参数组st的起始地址。
在函数中可以用ps[i].num、ps[i].s[j]、ps[i].ave等这样的形式引用主函数st数组元素中的成员,也可用(ps+i)->
num或(*(ps+i)).num等形式引用主函数st数组元素中的成员,因为在函数中,形参ps是一个指针变量。
(4)在readrec函数中,可以在一个for循环中输入结构体数组每个元素中的数据:
N;
i[KG-*3]+[KG-*3]+){……}在循环体中,可用gets(ps[i].num);
gets(ps[i].name);
输入学生的学号和姓名。
可用一个内嵌的for循环输入每个学生的四项成绩并同时累加成绩并求平均分:
for(j=0;
j<
4;
j[KG-*3]+[KG-*3]+){scanf(″%d″,&
ps[i].s[j]);
ps[i].ave+[KG-*3]=ps[i].s[j]/4.0;
}在scanf语句中,输入项是指针(ps+i)所指成员s[j]数组元素的地址,因此输入项也可以写成:
ps[i].s+j。
另外要注意,在进入此for循环前,应当给ps[i].ave赋0值。
注意:
在执行scanf语句读入成绩时,最后必定要按一个ENTER键,以便结束输入,但此回车符并没有被当作成绩读入,而是留在输入缓冲区内;
若下一个输入项是数值数据时,并不会影响输入,而在此处,下一次又将去调用gets函数来给num输入一个字符串,于是,回车符被自动当作字符串的结束符读入,num中被赋“空”串,程序接着要求输入name。
因此在退出以上控制变量为j的for循环后,需要有一个getchar()语句,以便“读入”一个字符,不使回车符留在输入缓冲区内。
这虽是一个细节,但它能使输入正确进行。
(5)writerec函数的首部可以写成:
voidwriterec(structstud*[KG-*3]ps)(6)在writerec函数中,可以在一个for循环中输出结构体数组每个元素中的数据:
i[KG-*3]+[KG-*3]+){……}可以用以下语句输出学号和姓名:
printf(″%s%s″,(ps+i)->
num,(*(ps+i)).name);
当然输出项也可以写成:
ps[i].num、ps[i].name。
和在readrec函数中一样,用一个内嵌的for循环输出四项成绩,最后输出ps[i].ave。
(7)在readrec函数中请添加输入提示,以便正确输入;
在writerec函数中请添加有关的输出文字,使输出内容更清晰。
(8)请自己编写主函数,写出定义语句和调用语句。
(9)总结:
本题的算法十分简单,仅是输入和输出,但要求能够掌握结构体数组在函数之间的数据传递,要求对结构体变量中成员能正确引用。
在调试程序时,为了便于输入,可把define行改为:
#defineN2这样只需输入两组数据,也同样可以对程序的正确性进行验证。
14.13【分析与解答】
(1)本题所要求编写的函数可参考本章习题14.10。
(2)为了能对链表进行操作,必须建立链表,建立链表的函数可参考本章习题14.11。
输出链表可参考教材第四章例14.7。
(3)本题第二个函数要求返回的是最大值所在结点的地址,若此函数名为maxadd,函数首部可以如下:
structnode*maxadd(structnode*head)此处,structnode是链表结点的类型。
函数的基本算法和习题14.10基本相同,只是需要另定义一个基类型为structnode的指针,假定此指针名为pmax,则每次当把最大值放入m时,同时也把此结点的地址放入pmax中,最后返回pmax即可。
基本的程序段如下:
p=head->
next;
m=p->
data;
pmax=p;
for(p=p->
p;
p=p->
next)if(m<
data){m=p->
}(4)在主函数中也需要定义一个基类型为structnode的指针,若定义该指针名为:
maxnode,则应当把函数maxadd的返回值赋给它:
maxnode=maxadd(head);
,此处head指向链表的头结点。
可用:
printf(″%d\[KG-*3]n″,maxnode->
data);
输出maxnode所指结点中的数据域,以验证maxnode是否指向链表中的最大值所在的结点。
(5)总结:
函数的类型可以是指向结构体的指针类型,也可以是结构体类型。
读者也可编写一个函数,把最大值所在的结点放在一个结构体变量中作为函数值返回。
第十五章位运算习题分析与解答一、选择题15.1【参考答案】D)15.2【参考答案】A)15.3【参考答案】B)15.4【参考答案】A)
二、填空题15.5【参考答案】11110000;
15.6【参考答案】a=a&
0;
15.7【参考答案】a=a|07777;
15.8【参考答案】a=a|0177400;
15.9【参考答案】a=012500>
>
2;
15.10【参考答案】ch=ch|32;
第十六章文件习题分析与解答一、选择题16.1【参考答案】B)16.2【参考答案】C)
二、填空题16.3【参考答案】[1]3[2]!
feof(f1)[3]f2[4]fclose(f1)[5]fclose(f2)
16.4【参考答案】[1]fopen(fname,″w″)[2]ch16.5【参考答案】[1]″r″[2](!
feof(fp))[3]fgetc(fp)16.6【参考答案】AAAABBBBCCCC
三、编程题16.7【分析与解答】
(1)因为指定为10个字符串,并假定每个字符串不会超过20个字符,为方便起见,在程序的前面定义以下命令行:
#defineN10#defineM22
(2)假定字符串输出到名为myfile.dat的文件中;
程序中字符串放在名为s的字符数组中。
(3)按照题义程序应有以下步骤:
①首先为“写”而打开文件:
fp=fopen(″myfile.dat″,″w″);
②从终端输入字符串,输入一个字符串,就立即把它输出到文件中,因为有N个字符串,因此需要放在循环中来完成:
for(i=1;
i<
[KG-*3]=N;
i[KG-*3]+[KG-*3]+){printf(″Enterastring:
″);
gets(s);
fputs(s,fp);
fputc(′\[KG-*3]n′,fp);
}函数fputs(s,fp)把刚从终端读入的字符串s输出到fp所指的文件中。
请注意函数fputs(s,fp)的输出特点:
在输出时它将只输出字符串中的字符而不输出字符串的结束标志到文件中,因此在文件中,连续输出的字符串之间将头尾相接,在文件中储存了一个接一个的字符,分不清哪是哪个字符串,其结果就使得不再可能从其中读入各个字符串了。
为了分清各个字符串,因此在每输出一个字符串时,就接着输出一个′\[KG-*3]n′符,以区分各字符串,在此由fputc(′\[KG-*3]n′,fp);
来完成。
③关闭因“写”而打开的文件:
fclose(fp);
④为“读”而打开文件:
fp=fopen(″myfile.dat″,″r″);
⑤从文件中输入字符串并把刚读入的字符串输出到终端屏幕:
fgets(s,M-1,fp);
while(!
feof(fp)){c=s[strlen(s)-1];
if(c==′\[KG-*3]n′)s[strlen(s)-1]=0;
puts(s);
fgets(s,M-1,fp);
}
fgets(s,M-1,fp)从fp所指文件中输入M-1个字符串放入s的地址中;
如果在未读满M-1个字符之前读到了一个换行符,则结束本次操作,系统在字符串最后自动加入′\0′。
注意,如果未读满M-1个字符,这时已把换行符读入,并作为字符串最后一个字符(在′\0′之前)。
在此,先判断s[strlen(s)-1]是否为′\[KG-*3]n′,若是,则用语句:
s[strlen(s)-1]=0;
来消除此换行符,把字符串结束标志前移了一个位置,strlen(s)求出字符串的长度,strlen(s)-1是最后一个字符的下标。
然后用puts(s);
进行输出。
fgets(s,M-1,fp);
作为循环体内最后的语句,当读到文件的结束标志时,函数feof(fp)的值为1,循环立即结束。
⑥关闭文件:
(4)请读者自己完成其他相关的语句和定义。
在用fgets和fputs函数进行输入和输出时,请注意它们的特点,以便使字符串的输入和输出正确进行。
16.8【分析与解答】
(1)按题意程序需要两次把数据输出到文件中,第一次是把从键盘输入的数据输出到文件中,第二次是把修改过的数据再次输出到文件中。
为此编写一个函数来完成此项任务,以避免重复编码。
同理,程序需要两次从文件中输入数据,因此也用一个函数来完成此任务。
另外程序需要两次把从文件输入的数据输出到屏幕上,因此也用一个函数来完成。
(2)因为指定为10个双精度数,为方便起见,在程序的前面定义以下命令行:
#defineN10(3)为了便于操作,无论是输入的数据还是输出的数据,程序都把它们放在一个数组中。
(4)若程序把输出的数据放在mybin.dat文件中,在函数binput中把数据输出到mybin.dat文件,binput函数的首部应是:
binput(double*a)形参a是一个基类型为double的指针,它接受存放数据的实参数组的首地址。
函数中需要包含以下步骤:
①打开输出文件:
fp=fopen(″mybin.dat″,″wb″);
fp是文件指针,mybin.dat是输出文件名,″wb″规定此次是为“写”而打开一个二进制文件。
②输出数据到二进制文件中:
i[KG-*3]+[KG-*3]+)fwrite(a+i,sizeof(double),1,fp);
fwrite是用于二进制输出的函数。
第一个参数:
a+i在内存中输出数据的首地址,第二个参数:
sizeof(double)是每个输出数据的字节数,第三个参数:
1是每执行一次fwrite时输出数据的个数,第四个参数:
fp是指向输出文件的文件指针。
语句:
fwrite(a+i,sizeof(double),1,fp);
的含义是:
每执行一次,从a+i地址开始取sizeof(double)个字节放入fp所指的文件中。
在此,for循环将把a[0]到a[9]中的数据(每个数据都是double类型)输出到fp所指的文件中。
③输出结束,关闭文件:
(5)程序若用名为binread的函数输入文件中的数据,binread函数的首部应是:
binread(double*a)形参指针a指向主函数中存放数据的数组首地址。
①打开输入文件:
fp=fopen(″mybin.dat″,″rb″);
fp是文件指针,mybin.dat是输入文件名,″rb″规定此次是为“读”而打开一个二进制文件。
②从二进制文件中输入数据:
fread(a,sizeof(double),N,fp);
此语句的含义是:
从fp所指文件中输入N个sizeof(double)字节的数据,放入a所指地址开始的存储区中。
因此,此语句一次就从文件中读入N个双精度数,并把它们放入了a所指的数组中。
③输入结束,关闭文件:
(6)程序若用名为pri的函数把数组中的数据输出到屏幕上,pri函数的首部应是:
pri(double*a)此函数十分简单,请读者自己编写。
(7)主函数中只需按本题的要求调用所需函数即可:
main(){doubles[N];
inti;
printf(″\[KG-*3]nEnter10doublenumbers:
for(i=0;
i[KG-*3]+[KG-*3]+)scanf(″%lf″,s+i);
binput(s);
binread(s);
pri(s);
s[3]=44.44;
/*改变第四个数据中的值*/binput(s);
}(8)各个函数已给出主要的步骤,需要读者自己完成应有的定义语句。
在所给的程序中,binput函数和binread函数中介绍了对fwrite和fread的不同调用方式,对于fwrite和fread函数,这两种方式都是可用的。