c Primer Plus 第六版较难题目练习

在学完整本书之后,开始重头再复习难题,第一部分,先把课后的复习题中的重难题记录下来,做个笔记,以后每天要坚持写一到两个小时代码。

第八章

C的标准I/O库把不同的文件映射为统一的流来统一处理。

 

第9章第9题

给定下面的输出:

Please choose one of the following:

1)copy files      2)move files

3)remove files    4)quit

Enter the number of your choice:

a.编写一个函数,显示一份有4个选项的菜单,提示用户进行选择(输出如上所示)。

b.编写一个函数,接受两个Int 类型的参数分别显示上限和下限。该函数从用户的输入中读取整数。如果整数超出规定的上下限,函数再次打印菜单(使用a部分的函数)提示用户输入,然后获取一个新值。如果用户输入的整数在规定范围内,该函数则把该整数返回主调函数,如果用户输入一个非整数字符,该函数应返回4.

c.使用本题a和b部分的函数编写一个最小型的程序。最小型的意思是,该程序不需要实现菜单中各选项的功能,只需显示这些选项并获取有效的响应即可。

答案:

下面是一个最小的程序,showmenu()和getchoice()函数分别是A和B的答案。

#include<stdio.h>

void showmenu();

int getchoice(int,int):

int main()

{

  int res;

  showmenu();

  while((res=getchoice(1,4)!=4)

{

  printf("I like choice %d.\n",res);

  showmenu();

}

  printf("Bye!\n");

   return 0;

}

 

void showmenu()

{

printf("Please choose one of the following:\n");

printf("1)copy files       2)move files\n");

printf("3)remove files     4)quit\n");

printf("Enter the number of your choice:\n);

}

int getchoice(int low,int high)

{

   int ans;

  int good;

  good=scanf("%d",&ans);

  while(good==1&&(ans<low||ans>high))

  {

  printf("%d is not a valid choice;try again\n",ans);

  showmenu();

  scanf("%d",&ans);

   }

if(good!=1)

{

printf("Non-numeric input.");

ans=4;

}

return ans;

}

 

内容注释

在两个!之间有一个空字符,但是通常该字符不会产生任何打印的效果

*--pc的意思是把指针减1,并使用储存在该位置上的值,--*pc的意思是解引用pc指向的值,然后把该值减1(例如,H变成G)。

 

第11章第8题

#include<stdio.h>

int main()

{

char str1[]="gawsie";

char str2[]="bletonism";

char *ps;

int i=0;

for(ps=str1;*ps!='\0';ps++)

{

 if(*ps=='a'||*ps=='e')

    putchar(*ps);

else

(*ps)--;

}

putchar('\n');

while(str2[i]!='\0')

{

printf("%c",i%3?str2[i]:'*');

++i;

}

return 0;

}

 

11题:

   本章定义的s_gets()函数,可以用strchr()函数代替其中的while循环来查找换行符。请改写该函数

#include<stdio.h>

#include<string.h>

char*s_gets(char*st,int n)

{

char*ret_val;

char*find;

ret_val=fgets(st,b,stdin);

if(ret_val)

{

  find=strchr(st,'\n');

if(find)

*find='\0';

else

while(getchar()!='\n')

continue;

}

return ret_val;

}

 

第12题 设计一个函数,接受一个指向字符串的指针,返回指向该字符串第1个空格字符的指针,或如果未找到空格字符,则返回空指针。

①法:#include<stdio.h>

char*strblk(char*string)

{

while(*string !=' '&&*string !='\0')

string++;

if(*string=='\0')

return NULL;

else

return string;

}

②法可以防止函数修改字符串,但是允许使用返回值改变字符串。表达式(char*)string被称为“通过强制类型转换取消const"

#include<stdio.h>

char*strblk(const char*string)

{

while(*string !=‘ ’&&*string!='\0')

string++;

if(*string=='\0')

return NULL;

else

return(char*)string;

}

 

自动存储类别;寄存器存储类别;静态、无链接存储类别是可以成为它所在函数的局部变量。、

静态、无链接存储类别;静态、内部链接存储类别;静态、外部链接存储类别是在它所在程序的运行期一直存在

静态、外部链接存储类别可以被多个文件使用。静态、内部链接存储类别只能在一个文件中使用

关键字extern用于声明中,表明该变量或函数已定义在别处

 

第12章第8题:

#include<stdio.h>

char color='B';

void first(void);

void second(void);

int main(void)

{

extern char color;

printf("color in main() is %c\n",color);

first();

printf("color in main() is %c\n",color);

second();

printf("color in main() is %c\n",color);

return 0;

}

void first(void)

{

char color;

color ='R';

printf("color in first() is %c\n",color);

}

void second()

{

color ='G';

printf("color in second() is %c\n",color);

}

得出结论:

color in main() is B

color in first() is R

color in main() is B

color in second() is G

color in main() is G

 

第13章第4题:

编写一个程序,不接受任何命令行参数或接受一个命令行参数,如果有一个参数,将其解释为文件名,如果没有参数,使用标准输入(stdin)作为输入,假设输入完全是浮点数,该程序要计算和报告输入数字的算术平均值。

答:#include<stdio.h>

#include<stdlib.h>

int main(int argc,char*argv[ ])

{

FILE*fp;

double n;

double sum=0.0;

int ct=0;

if(argc==1)

fp=stdin;

else if(argc==2)

{

if((fp=fopen(argv[1],"r"))==NULL)

{

fprintf(stderr,"Can't open %s\n",argv[1]);

exit(EXIT_FAILURE);

}

}

else

{

fprintf(stderr,"Usage:%s [filename]\n",argv[0]);

exit(EXIT_FAILURE);

}

while(fscanf(fp,"%lf",&n)==1)

{

sum+=n;

++ct;

}

if(ct>0)

printf("Average of %d values=%f\n",ct,sum/ct);

else

printf("No valid data.\n");

return 0;

}

 

第13章第5题

编写一个程序,接受两个命令行参数,第一个参数是字符,第二个参数是文件名。要求该程序只打印文件中包含给定字符的那些行。

答:

#include<stdio.h>

#include<stdlib.h>

#define BUF 256

int has_ch(char ch,const char*line);

int main(int argc,char*argv[ ])

{

FILE*fp;

char ch;

char line [BUF];

if(argc !=3)

{

printf("Usage:%s character filename\n",argv[0]);

exit (EXIT_FAILURE);

}

while(fgets(line,BUF,fp)!=NULL)

{

if(has_ch(ch,line))

fputs(line,stdout);

}

fclose(fp);

return 0;

}

int has_ch(char ch,const char*line)

{

while(*line)

if(ch==*line++)

return 0;

}

fgets()和fputs()函数要一起使用,因为fgets()会把按下Enter键的\n留在字符串中,fputs()与puts()不一样,不会添加一个换行符。

二进制文件与文本文件的区别是,这两种文件格式对系统的依赖性不同,二进制和文本流的区别包括是在读写流时程序执行的转换(二进制流不转换,而文本流可能要转换换行符和其他字符)

a+只允许在文件的末尾添加内容,w+模式提供一个空文件,丢弃文件原来的内容,r+适合用来更改文件中已有的内容。

第14章第10题

假设有如下结构:

struct gas

{float distance;

 float gals;

float mpg;

};

a 设计一个函数,接受struct gas 类型的参数,假设传入的结构包含distance和gals信息,该函数为mpg成员计算正确的值,并把值返回该结构

b设计一个函数,接受struct gas 类型的参数,假设传入的结构包含distance和gals信息,该函数为mpg成员计算正确的值,并把值赋给合适的成员。

答:

struct gas

{float distance;

 float gals;

float mpg;

};

struct gas mpgs(struct gas trip)

{

if(trip.gals>0)

trip.mpg=trip.distance/trip.gals;

else

trip.mpg=-1.0;

return trip;

}

void set_mpgs(struct gas*ptrip)

{

if(ptrip->gals>0)

ptrip->mpg=ptrip->distance/ptrip->gals;

else

ptrip->mpg=-1.0;

}

注意,第一个函数不能直接改变其主调程序中的值,所以必须用返回值才能传递信息。

struct gas idaho={430.0,14.8};//设置前两个成员

idaho=mpgs(idaho);   //重置数据结构

但是,第2个函数可以直接访问最初的结构;

struct gas ohio={583,17.6}  //设置前两个成员

set_mpgs(&ohio);       //设置第3个成员

 

声明一个标记为choices的枚举,把枚举常量No,yes 和Maybe分别设置为0、1、2

enum choices{no,yes,maybe};

 

把下面的十进制转换为二进制

3    00000011

13   00001101

59   00111011

119  01110111

把下面二进制转换为十进制,八进制和十六进制

00010101   21, 025  0x15

01010101   85     0125   0x55

01001100    76  0114   0x4C

10011101    157   0235   0x9D

第16章第13题

假设datal是内含100个double类型元素的数组,data2是内含300个double类型元素的数组

a编写memcpy()的函数调用,用data2中的前100个元素拷贝到datal中

b编写memcpy()的函数调用,用data2中的后100个元素拷贝到datal中

a qsort((void*)scores,(size_t)1000,sizeof(double),comp);

b 下面是一个比较使用的比较函数:

int comp(const void*p1,const void*p2)

{

const int*a1=(const int*)p1;

const int*a2=(const int*)p2;

if(*a1>*a2)

return -1;

else if(*a1==*a2)

return 0;

else

return 1;

}

 


版权声明:本文为crayon_komatsu原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。