c语言国二sizeof题目,国二c语言选择题参考答案

第四、五部分参考答案

第4节与第5节涉及到指针比较多,用文字描述比较难。大家以视频解析为准即可。这里提供参考答案

第4节 字符串、函数的递归、标识符的作用域和存储类

1-10:ACCAA  DBACC

11-20:DBADD  ADCAA

21-30:BBBCA   DCAAA

31-40:ACDBB  BADAA

41-50:DADAC  ABCBC

51-60:ACBAA  ADACA

61-70:DCAAC  ABDDA

71-80:ACAAD  CDDAA

81-90:CCCDA  AABCA

91-100:ACCCC  AACDA

101-110:ACACA  BCAAC

111-120:BBAAD  CACDA

121-135:ADABC  DBAAA   DDCDC

第5节 预编译处理、动态分配、结构体、位运算和文件

1、【答案】A

在本题中,p是指针,正确引用方式为p->name或(*p).name。

2、【答案】D

array五个元素分别是0,9,3,1,4。

for循环第一个if作用是把最大值赋值给res.first。第二个if作用是把最小值赋值给res.second。最后再将求和值赋值给res.third。然后通过ruturn返回给主函数,输出结果分别是最小值,最大值,和求和。

3、【答案】A

二级指针概念,二级指针即指向指针的指针,即存放地址的地址。c是普通变量,p是指向c的指针,q是指向p的指针即q是二级指针。

p=&c,是使p指向c。把q=&p,是使q指向p。

4、【答案】C

引用结构体成员的三种正确方式:

结构体变量名.成员名

结构体指针变量名->成员名

(*结构体指针变量名).成员名。

C选项应该改为D选项形式,即(*a).n。即第三种形式。

5、【答案】C

通过void可知其返回值为空,即指针赋空值。当指针被赋空值时不能通过指针引用存储单元。因为指针指向空,本身就不存在。

6、【答案】D

f函数传递三个实参:b.name, &b.gender, &b.score均为地址,在f函数改变指针指向内容改变,实参即变。上课时总结为:传地址,地址指向内容(*p,a[i])发生改变,实参就变。所以b变量变为qian,f,350。

7、【答案】C

引用结构体成员的三种正确方式:

结构体变量名.成员名

结构体指针变量名->成员名

(*结构体指针变量名).成员名。

由于ps是指针变量,所以C选项错。

8、【答案】C

函数功能,可以查看第12章概念。

9、【答案】A

程序要先编译再运行。但宏替换是在编译之前进行的预处理,所以不会占有运行时间。

10、【答案】A

引用结构体成员的三种正确方式:

结构体变量名.成员名

结构体指针变量名->成员名

(*结构体指针变量名).成员名。

A选项中scanf数据列表应是地址。而ps是指针,d是数组名,那正确引用方式为ps->d。

11、【答案】A

【解析】本题结构体数组中,room是数组名,表示首地址指向第一个元素:{'Wang', 19},那么room+1指向第二个元素{'Li', 20}。题目要求输出room+1指向的name,room指向的age。即第二个元素姓名,第一个元素的年龄。

12、【答案】A

#define   Memory(x,num)  malloc(num*sizeof(x)

上述语句中,malloc是动态分配内存。num表示数量,sizeof表示每个内存的大小。此题表示分别给对应类型分配100个内存。

13、【答案】B

引用结构体成员的三种正确方式:

结构体变量名.成员名

结构体指针变量名->成员名

(*结构体指针变量名).成员名。

在本题中rec是一个结构体变量,那么B选项错。应该采用上面三种方式中的第1种。

14、【答案】B

【解析】位运算与进制转换。位运算要转为二进制。y=010,是八进制数,转为二进制数形式是1000。执行y>>1表示位运算右移一位,即y>>1的值为二进制100,二进制100转为二进制为4。15、【答案】B

【解析】同14题考点相同都是位运算。a转为二进制是00000011,b转为二进制是0000110,a^b进行的是异或运算,运算法则是对应位相同为0不同为1。a^b=00000101。然后执行c=00000101<<2,即左移两位,即右边补2个0,得c=00010100,转为十进制是20。

16、【答案】D

【解析】同样考察位运算与进制转换。x转成二进制是00010000,y转为二进制是00000100。x>>=1即x=x>>1,右移一位,x变为00000100。y左移两位,得y值为00010000然后x^y异或运算,对应位相同为0不同为1。得x^y==00010100,由于%o表示不带前导的八进制,所以将00010100转为八进制为30。

17、【答案】C

【解析】宏替换,即文本替换。#define Out(x)n%2==0 ? '%c' : '%d'即当n为奇数时将out(x)替换为“%d”,即当n为偶数时将out(x)替换为“%c”。

第一次循环x=65,printf(Out(x),x)替换为printf(“%d”,x)输出65。

第二次循环x=66,printf(Out(x),x)替换为printf(“%c”,x)输出B。

第三次循环x=67,printf(Out(x),x)替换为printf(“%d”,x)输出67。

第四次循环x=68,printf(Out(x),x)替换为printf(“%c”,x)输出D。

所以选择C。

18、【答案】B

【解析】考察动态分配。p1=p2=(char*)malloc(sizeof(char)*10);通过mallo分配内存地址同时赋值给p1和p2。此时p1和p2指向同一内存空间。然后第一次通过strcpy(p1,'malloc');将“malloc'字符串放入所分配内存,第二次通过strcpy(p2,p1+1);将“alloc”放入所分配内存,由于放入的是同一个内存,第一次放的字符串会被第2次覆盖。此时内存中存放的是alloc字符串,那么不p1[0]和p2[0]都是表示内存的第一个元素a。

19、【答案】C

【解析】考察位运算。x转为十进制是00000011。y转为十进制是00000101。按位异或运算对应位相同为0,不同为1。刚x=x^y==00000110。y=x^y==00000011。x=x^y=00000101。最后转化为十进制是x=5,y=3。

20、【答案】B

【解析】考察位运算。a转为十进制是00001001。a右移3位(即a>>3)结果为00000001,转为十进制为1。但a的值并未变还是9。然后b=1%4==1。

21、【答案】A

【解析】考察位运算。即通过循环将数组的每一个元素与3进行按位与运算。5个元素分别是3,5,10,4,0。按位与的运算法则为对应位同时为1结果才为1。第一次循环:00000011&00000011==00000011,转化为十进制为3。其他几组用相同方法得到,1,2,0,0。

22、【答案】A

【解析】A选项fread作用是从文件中读取数据。只是读,并未输出。

B选项fwrite作用是从向文件内写入数据。

C选项fput作用是将字符ch写到文件指针fp所指向的文件的当前写指针的位置

D选项fprintf作用是按照格式装数据输出到文本文件中。

23、【答案】D

【解析】typedef作用是给已经有的类型另外取名。本题中将int *这个类型说明为T。那么把T *x[20]中的T换成int*得到结果是int **x[20]。D选项类型完全一样。

24、【答案】A

【解析】固定概念,位运算只能是整型或字符型数据。

25、【答案】C

【解析】位运算。x转为二进制为00000011,y转为二进制为00000101。按位异或对应位相同为0不同为1可得z1=x^y==00000110,转为十进制是6。z2=3+5=8。

26、【答案】D

【解析】程序的执行过程为:定义整型数组x1,x2并进行初始化,两个数组长度均为2。定义结构体数组x,并为其初始化,则x[0].a=1,x[0].b=x1,x[1].a=2,x[0].b=x2。输出x[0]的成员指针b指向的内存单元值,即数组x1的第一个元素3,输出x[1]的成员指针b指向的内存单元值,即数组x2的第一个元6。程序的运行结果是3,6,D选项正确。

27、【答案】A

【解析】recd数组共3个元素分别是:

srecd[0]=={{2016,3,5},{12,25,30}}

srecd[1]== {{2017,5,8},{8,45,55}}

srecd[2]== {{2015,6,8},{22,15,26}

每个元素的第一部分是年月日year,month,day,第二部分是时分秒hour,minute,second。

在for循环体中的if语句作用是如果年year>=2016则输出月和日。否则输出分和秒。

当i=1时:srecd[1].dt.year==2017>=2016为真,输出月和日即5-8。

当i=2时:srecd[1].dt.year==2015>=2016为假,输出分和秒即15-26。

所以答案选择A。

28、【答案】A

【解析】A选项中sanf()函数的数据列表部分必须是地址值。而p->age不是地址。正确方式是&(p->age)。

其他三个选项均是地址值。B选项name是数组名,为首地址。CD两个选项加了取地址符。

29、【答案】C

【解析】宏运算,运算法则是将所有都进行替换后再按照算术运算方式运算。

S(k+j+2)即k+j+2* k+j+2/k+j+2=6+3+2*6+3+2/6+3+2=29。

S(j+k+2)即j+k+2* j+k+2/ j+k+2=3+6+2*3+6+2/3+6+2=29。

30、【答案】B

【解析】位运算。先转二进制再进行运算。x转二进为00000011,y转二进制是00000101。

按位运算^相同为0不同为1。y^x==00000110,然后再收进行按位收运算,z1=00000110^00000101==00000011,转为十进制为3。按照同样方式运算可得z2=5。

31、【答案】B

【解析】array数组六个元素分别是19,21,3,4,0,0。

for循环第一个if作用是把最大值赋值给res.first。第二个if作用是把最小值赋值给res.second。然后通过ruturn返回给主函数,输出结果分别是最小值,最大值。

32、【答案】A

【解析】所有类型的指针所占内存均为4个字节,所以A选项正确。

33、【答案】C

【解析】带#号的预处理命令只是在编译前进行处理,但其位置可以不在最前面。

34、【答案】A

【解析】通过sturct S定义结构体变量s1,s2。然后分别给变量成员name数组赋值字符串“12345”,“ABC”。然后再将变量s2的值赋值给s1。此时s1结构体的成员name变为“ABC”。

35、【答案】A

【解析】main函数中b是指针,c是结构体变量。那么通过f(c,b)将变量c传递给a,将指针b传递给f函数的形参c。由于传值形参不改变实参,通过a=b并不会改变实参c的值。由于b传的是结构体成员name的地址。通过f函数里面面的for循环作用是将字符串小写转化为大写。所以本题只有name变成大写,其他值不变。

36、【答案】C

【解析】固定概念。

37、【答案】A

【解析】考查“逻辑与”和“按位与”的区别。

z1=x&&y中两边x、y均为真,那么z1的值为1。

z2=x&y,按位运算要先转二进制。x=00000100,y=00000010。按位与至应为均为1结果才为1。z2=00000100&00000010=000000000,转为十进制为0。

38、【答案】D

【解析】A选项fopen反回值为文件指针类型。B选项fopen调用形式为:fopen(文件名,文件使用方式)。C选项返回值为空表示未成功打开指定文件。ABC三选择错,D选项是fopen函数的作用。

39、【答案】A

【解析】考查位运算右移。ch转为二进制为00010000,右移一位结果为00001000,转为十进制的值为8。

40、【答案】A

【解析】引用结构体成员的三种正确方式:

结构体变量名.成员名

结构体指针变量名->成员名

(*结构体指针变量名).成员名。

由于ptr是指针类型,所以A选项引用方式错误,正确形式应该是D选项。

41、【答案】D

【解析】函数固定用法。ABC三选项均可读入多个字符。getc和fgetc均是读入一个字符。

42、【答案】A

【解析】p指向a节点,将p->next赋值给pt,表示将a节点的指针域赋值给pt,即让pt指向b。p->next表示b的地址,p->nxet指向b,那么p->next->next即c的地址。把p->next=p->next->next;赋值给p->nxet表示让a节点指向c节点。然后释放(free)pt指针,表示pt不再指向任何内容。此时a直接指骨向c,即将b节点删除。

43、【答案】B

【解析】位运算要先转二进制。按位异或相同为0,不同为1。a=00000011^00000010==1。按位或对应位同时为0才为0。5|2=00000101|00000010==00000111,然后00000111|11110000==11110111,然后按拉取反(~),得00001000,转为十进制为8。

44、【答案】B

【解析】引用结构体成员的三种正确方式:

结构体变量名.成员名

结构体指针变量名->成员名

(*结构体指针变量名).成员名。

由于rec是结构体变量。所以A选项引用方式错误,正确形式应该是B选项。

45、【答案】C

【解析】按位与,转为二进制,只有对应位同时为1结果为1。00000011&00000011==00000011,转为十进制为3。

46、【答案】D

【解析】“w”为写的方式打开文件,若文件存在,则从文件起始位置开始写入,若文件不存在则会新建指定文件名的文件。

47、【答案】D

【解析】宏运算,把所有的文本替换完后再进行运算。

S1(a+b,a+b)替换为a+b*a+b=3+4*3+4=19。

S1((a+b,(a+b))替换为(a+b)*(a+b)=(3+4)*(3+4)=49。

S2(a+b,a+b)替换为(a+b)*(a+b)=(3+4)*(3+4)=49。

48、【答案】A

【解析】结构体数组有5个元素,每个元素分为整数x和指针next两部分。通过for循环每次将下一个元素的地址赋值给前一个元素的指针域,即让第一个指向第二,第二个指向第三个,以此类推构成链表;并且每次将2*i+1赋值一给m[i].x。之前执行p=m,将首地址赋值给p,让p指向第一个元素m[i]。最后输出p++->x,由于p++的值是p,所以p++->x是第一个元素的x,即1。由于执行了P++,所以会指向第二个元素。然后输出p->x++,即2*1+1=3.

49、【答案】A

【解析】结构体数组有3个元素,每个元素有两部分分别为x,y。即data[0]={4,3}、data[1]={2,0}、data[2]={8,1}。每次循环输出第i个元素的x和第i个元素右移一位。

当i为0,输出41,

当i为1,输出20,

当i为2,输出80。

50、【答案】D

【解析】考查位运算。a转为二进制是00010000,右移4位结果是00000000,转为十进制是0,由于没有给a赋值,所以a的值还是16。然后0对1取余结果为0。

51、【答案】D

【解析】考查位运算。a转为二进制是000000001,右移4位结果是00000000,转为十进制是0,由于没有给a赋值,所以a的值还是1。然后0对3取余结果为0。

52、【答案】A

【解析】fread用法:fread(buffer,size,count,fp),第一个参数是内存块的首地址,A选项中第一个参数a[i]是一个数组元素,不是地址,所以是语法错误。

53、【答案】A

【解析】typedef作用是给已经有的类型另外取名。定义T b。可以认为b就是T。由于题目问题谁和b相同,那么只需要用a换掉T即可。

54、【答案】A

【解析】本质是考查函数数据传递。本题通过函数调用,将结构体变量a的地址传递给f函数里面的a.然后在f函数执行将结构体变量c的地址赋值给d,然后再赋值给a,此时形参a指向变量c。下面三个赋值语句其实就是把c变量赋值给a指向的变量即把c赋值给c。然后输出c的值。即sun,f,90。此时f函数执行结束,再输出main函数里面a的值。由于在f函数中,先将c的地址赋值给指针a,后面操作改变的都是变量c的值,并没有改变main里面a的值。所以a还是zhao,m,85.

可以总结为传地址,地址变,实参不变。

55、【答案】D

【解析】结构体变量中的成员可以是变量,可以是地址,可以是数组,同时也可以本结构体类的变量、指针、数组,不同成员之前要用分号隔开,同一个结构体中的成员不可同名,不同结构体中的成员可以同名。所以D选项是错的。

56、【答案】B

【解析】把结构体变量s2赋值给s1,那么s1变量里面的name成员就变成了字符串“ABC”。输出函数中%表示输出字符串,即本题输出ABC。

57、【答案】A

【解析】宏运算,把所有文本替换完再乾计算。

s(k+j)替换为(k+j/k+j)*k+j==(6+3/6+3)*6+3=57。

s(j+k)替换为(j+k/j+k)*j+k==(3+6/3+6)*3+6=39

58、【答案】C

【解析】在main函数定义两个结构体变量分别为a和b。ab两个变量分别有四个成员:name[9]、gender、score、next。在main函数中,先将b的地址赋值给a的指针域,即让a.next指向结构体变量b。调用f(a)即传递变量a给f函数的a,传值形参不改变实参,可知道main里面实参a的值不会变,还是zhao,m,85,所以在输出时,输出a结构体成员分别是zhao,m,85。在f函数中,又将d赋值给*a.next。所以a.next->name,a.next->gender,a.next->score三个即为d.name,d.gender,d.score结构体成员。即输出结果为:Li,m,100。

59、【答案】A

【解析】typedef是用户定义类型关键字,本题通过typedef将结构体struct Data说明为新的结构体类型名DATA,即DATA表示一个结构类型。

60、【答案】D

【解析】以“w”即写的方式打开文件都会从文件的起始位置开始写入内容,并且原来内容全部消失。本题每次循环均会首先执行一次打开文件,前一次写的内容都会消失,所以本题只需要考虑最后一次循环写入的内容。最后一次循环i=4,通过fputc写入的是’A’+4,即’E’。

61、【答案】D

【解析】固定用法。

62、【答案】A

【解析】固定用法。B选项错在有两个#。C选项错在替换文件不能是关键字。D选项define不能是大写。

63、【答案】C

【解析】考查位运算。将八进制的ch=020转为二进制为00010000,输出结果为左移1位,即00100000,转化为十进制为32。

64、【答案】A

【解析】用户定义类型,T *a可以认为T就是*a。那么把*a去替换掉T即得到A选项。

65、【答案】C

【解析】通过f函数将c变量的各成员分别赋值给a,然后通过return返回并赋值给main函数里面的变量b。由于定义变量a时是在函数外部定义的,所以a是全局变量,全部变量均为静态变量,所以在函数里面给a赋值,a的值即保留。所以本题main函数输出ab的各个成员均为f函数里面c变量成员值。

66、【答案】A

【解析】首先通过fopen打开文件,然后通过fprintf将a[0]即1写入文件的起始位置。然后每次进入循环后都先执行一次rewind(fp)那将指针重新移动到文件起始位置,然后再通过fprintf将a[i]写入指针所指向的起始位置。也就是每次循环都是向文件的起始位置写入数据,并覆盖上一次所写入的数据,最终文件写入的数据是a[5]即6。循环结束后rewind(fp)那将指针重新移动到文件起始位置,然后通过fscanf()从文件读取数值6并赋值给变量k。最终k的值为6。

67、【答案】B

【解析】A选项输出字符,C选项输出到文件,D选项向文件写入数据。而B选项是从文件获取数据。

68、【答案】A

【解析】宏名大小写均可,我们见到的多数是大写只是习惯问题,并不是说必须要大写。

69、【答案】A

【解析】位运算,将十六进制的0x0f转为二进制是00001111。将ch右移两位的结果为00000011。将ch左移4位为11110000。分别转化为十进制结果是3和240。

70、【答案】C

【解析】宏替换,所有文本替换完再运算。

D(i+j)宏替换为:4*i+j+1==4*2+4+1==13。

71、【答案】A

【解析】首先通过fopen打开文件,然后通过fwrite将a[0]即1写入文件的起始位置。然后每次进入循环后都先执行一次fseek(fp,0l,0)那将指针重新移动到文件起始位置,然后再通过fwrite将a[i]写入指针所指向的起始位置。也就是每次循环都是向文件的起始位置写入数据,并覆盖上一次所写入的数据,最终文件写入的数据是a[5]即6。循环结束后fseek(fp,0l,0)那将指针重新移动到文件起始位置,然后通过fread()从文件读取数值6并赋值给变量k。最终k的值为6。

72、【答案】A

【解析】B选项错,结构体变量只有在定义时才可以整体进行初始化。如果在定义后初始化只能单个成员进行赋值。C选项错,b是结构体变量,引用成员用b.name形式即可。D选项通过typedef将结构体说明为C。那么C即是一个结构体类型而不是结构体变量,把D错。

73、【答案】C

【解析】位运算与逻辑运算,13转为二进制是00001101,右移1位是00000110,然后与00000001进行按位或运算,对应位有一个为1结果就是1。所以00000110|00000001==00000111,转为十进制是7。||逻辑或,两边若有一个为真结果为1。00000110||00000001=1。

74、【答案】C

【解析】指向A节点,那么*P即是A节点,(*p).next即b节点的地址。(*p).next->next是即是b节点的指针域,b节点的指针域是指向c节点,所以*((*p).next->next)是c节点,那么如果表示c节点的dt部分,应该是:*((*p).next->next).dt。而不是A的形式。

75、【答案】C

【解析】通过f(a,&b)传递,将变量a和变量b的地址分别传递给形参的a,b。然后在f函数中将b指向的值即main里b的值赋值给形参a,再输出形参a的各个成员。即Qian,f,350,由于a传递的是地址,那么形参不改为实参,所以main里的实参a并不会变,还是原值。所以main里面输出Zhao,m,290。

76、【答案】A

【解析】逻辑或,只要有一个是真结果就为真。

77、【答案】D

【解析】c1转为二进制是00010010,c2转为二进制是00110110。按位与&,对应位同时为1结果为1,c1&c1结果为还是c1。按位异或^,对应位相同为0不同为1,所以c2||c2结果为0。

78、【答案】A

【解析】结构体成员引用,srud[0].name[3]是指Adum里面的第四个即m。

79、【答案】C

【解析】位运算,8转为二进制是00001000,然后右移两位是00000010,转为十进制是2,但并未给a赋值,所以a未变。然后执行b=2%2==0。所以输出ab值分别是8和0。

80、【答案】C

【解析】传地址,地址指向内容发生改变,实参就变。b传递的是地址值,然后在f函数中,给*b赋值,即给地址指向内容赋值,所以实参b会变为a的值。

81、【答案】A

【解析】1、传地址,地址指向内容发生改变,实参就变。

2、传地址,地址指向内容发生改变,实参就变。

3、传值形参不改变实参。

本题中b传递的是地址值,然后在f函数中,将a的值给*b赋值和给c赋值,然后输出b和c结构体的各成员。即输出:Zhao,m,290,Zhao,m,290。由于f函数中给b指向内容赋值,所以实参b会变为a的值。而c传递的是变量值,所的c的值不会变。所以在main函数中输出b和c结构体的各成员。Zhao,m,290,Sun,m,370。

82、【答案】D

【解析】本题中定义了两个结构体变量1c1,pc2。分别给成员cpu赋值,然后再将pc2的值赋值给pc1。即pc1.cpu的值变为“????“

83、【答案】A

【解析】通过动态分配分配同一段内存的首地址赋值给p1和p2。此时p1和p2相等并指向是同一段内存的首地址。这段内存有5个int类型的空间。即可认为是一个有5个元素的数组。

在循环过程中,当i分别为0,1,2,3,4时,5个数组元素分别是0*10+1,1*10+1,2*10+1,3*10+1,4*10+1。最后输出p2-p1==0。*(p2+1)+*(p1+2)=10+21=32。

84、【答案】D

【解析】1、传地址,地址指向内容发生改变,实参就变。

2、传地址,地址指向内容发生改变,实参就变。

3、传值形参不改变实参。

&input传递是地址,在change函数中改变的是data->name,即改变指向的内容,实参input会变为“****“。num传递的是值,所以形参不改变实参,即num还是4。

85、【答案】C

【解析】宏运算,所有文本替换完再运算。

S1(a+b)替换为4*a+b+4*(a+b)==4*1+2+4*(1+2)=18

S2(a+b)+S1(3)替换为4*(a)*(b)+b*x+4*3+4*(3)==4*(1)*(2)+2*1+4*3+4*(3)==34

S2(3+a,b+3) 替换为4*(3+a)*(b+3)+3+a*b+3==4*(3+1)*(2+3)+2+3*3+1=92

86、【答案】A

【解析】位运算,a转为二进制为00001000,然后右移三位结果为00000001,再转为十进制为1。但并未给a重新赋值所以a不会变。然后b=1*8=8。

87、【答案】A

【解析】A选项中已经用结构体定义了结构体变量PER,即PER已经是一个结构体变量,并不是类型,所以不能用来定义其他变量。

88、【答案】A

【解析】位运算,按位异或^,对应位相同为0不同为1。按位或,对应位有一位是1即为1。按位与对应位同时为1结果才为1。

根据以上规则,可得A选项。

89、【答案】D

【解析】1、传地址,地址指向内容发生改变,实参就变。

2、传地址,地址指向内容发生改变,实参就变。

3、传值形参不改变实参。

本题中通过f函数调用,f(&b)传递的是地址,在f函数改变的是地址指向的内容,那么应该对应上面第2条。所以实参b会变为Qian,f,350。然后分别输出a和b的各成员。

90、【答案】B

【解析】不论任何类型的指针均是指针类型的变量。

91、【答案】C

【解析】1、传地址,地址指向内容发生改变,实参就变。

2、传地址,地址指向内容发生改变,实参就变。

3、传值形参不改变实参。

本题中通过fun函数调用,fun(s[0])传递的是变量s[0],对应的是上面第3三种情况,所以实参s[0]不会变。

92、【答案】C

【解析】for循环作用是将最大值赋值给mx,并将最大值下标赋值给j,同时将最小值赋值给mn,并将最小值下标赋值给t。也就是说pd[j]是最大我是个,pd[i]是最小值。然后再将最大值赋值给pd[size-2]即pd[8]是最大值,同理pd[9]是最小值。main里面输出的是最大值结构体的data成员,即分别为“数据结构“和”计算机原理“。

93、【答案】A

【解析】概念,略。

94、【答案】D

【解析】a!b语法错误。

95、【答案】A

【解析】宏运算,将所有文本替换完再运算。

S1(a+b,a+b)替换为a+b*a+b=2+3*2+3=11

S1(b+a,b+a)替换为b+a * b+a =3+2*3+2=10

S2(a+b,a+b)替换为(a+b)(*a+b)= (2+3)*(2+3)=25

96、【答案】A

【解析】BC选项都是将第1个数据(个数)读入给datao数组。D选项由于先执行了i++,那么循环里面第一次给数组的a[1]读入数据,并未给a[0]读入数据。

97、【答案】A

【解析】通过fopen打开文件,然后再经过for循环将数组的5从个元素从最后一个开始写入文件,即写入文件的内容为6,5,4,3,2,1。再执行rewind将文件指针指向文件起始位置。然后再通过第二个for循环每次读取文件里面一个元素,并输出对应值。

98、【答案】D

【解析】fwrite()是从第一个参数开始读取,读第二个参数*第三个参数的乘积为个数。。ABC三个选项中第二和第三个参数相乘都是10,只有D选项相乘是1.所以D选项只读取了一个元素。

99、【答案】B

【解析】room数组有4个元素,room是数组名,即是首地址指向第一个元素room[0]。本题输出的是(room+2)->name表示第三个元素的name成员,(room+2)->age表示第一个元素的age成员。所以选择B。

100、【答案】B

【解析】宏运算,所有替换完再运算。HA*(HA+HB(2))可以替换为HA*(HA+(HA+1)*a)= 2*(2+(2+1)*2)=16。

101、【答案】D

【解析】用户定义类型。通过typedef  struct{ int x,y; }  *USER;将USER定义为结构体指针类型。

102、【答案】A

【解析】结构体成员中的name是数组名,所以(*p).name表示t结构体变量中的name数组的数组名,由于数组名是常量,不可给常量赋值,所以选项错。

103、【答案】D

【解析】A选项int是关键字不可用作用户标识符。B选项define不可大写,C选项多了一个#号。

104、【答案】A

【解析】固定概念,其代表内存块的首地址。

105、【答案】D

【解析】以w即写的方式打开文件时,若文件不存在系统将按照指定的文件名新建一个文件。新建文件后文件就已经存在,那么if为真,则输出“不能打开文件“。

106、【答案】A

【解析】BC选项多了一个#号。D选项int是关键字不可用作用户标识符。

107、【答案】C

【解析】typedef作用是给已经有的类型另外取名。定义T b。可以认为b就是T。由于题目问题谁和b相同,那么只需要用a换掉T即可。

108、【答案】C

【解析】1、传地址,地址指向内容发生改变,实参就变。

2、传地址,地址指向内容发生改变,实参就变。

3、传值形参不改变实参。

本题中通过f(d)传递的是地址,由于执行了*a=*p,在f函数中改变是地址指向的内容,所以实参就变,并且执行了a->score[2]= a->score[0] + a->score[1],所以a->score[2]=95+96=191。所以两个输出均为huang,m,95,96,191。

109、【答案】D

【解析】结构体数组有两个元素,每个元素分别又有两个成员。即第一个元素为:{“c++”,36.0},第二个元素为:{“java”,23.59}。prog是数组名,为首地址,指向第一个元素,那么prog+1指向第二个元素。

题目要求输出的是第二个元素的name成员和第一个元素的price成员。即先输出java,然后再输出36.0。

110、【答案】A

【解析】考查位运算和逻辑运算。x转为二进制是00100100,将其右移两位得00001001,转为十进制是9。由于’A’

111、【答案】D

【解析】1、传地址,地址指向内容发生改变,实参就变。

2、传地址,地址指向内容发生改变,实参就变。

3、传值形参不改变实参。

本题通过fun(a,b,q)传递给fun函数的p1,p2,s。三个形参均是指针变量(地址)。在fun函数中首先通过动态分配给指针变量,即改变了地址值,符合上面第二条,所以实参不会变,还是初值。由于q在main函数中被赋空值,即q不指向任何内容。所以不能通过*引用其指向的内存单元。所以运算错误。

112、【答案】A

【解析】fwrite的第二个参数是每个数据的字节数,第三个参数书写次数。所以本题选择A。

113、【答案】A

【解析】B选项不能有两个#号。C选项define不能大写。D选项int是关键字,不用用作用户标志符。

114、【答案】B

【解析】固定概念。

115、【答案】B

【解析】宏运算是所有文本替换完了再进行运算。

S(k+j)替换为:k+j/ k+j* k+j=6+3/6+3*6+3=27。

S(j+k)替换为:j+k / j+k * j+k =3+6/3+6*3+6=29。

116、【答案】A

【解析】概念。略。

117、【答案】A

【解析】宏替换,即文本替换。#define Out(x)n%2==0 ? '%c' : '%d'即当n为奇数时将out(x)替换为“%d”,即当n为偶数时将out(x)替换为“%c”。

第一次循环x=65,printf(Out(x),x)替换为printf(“%d”,x)输出65。

第二次循环x=66,printf(Out(x),x)替换为printf(“%c”,x)输出B。

第三次循环x=67,printf(Out(x),x)替换为printf(“%d”,x)输出67。

第四次循环x=68,printf(Out(x),x)替换为printf(“%c”,x)输出D。

所以选择A。

118、【答案】D

【解析】引用结构体成员的三种正确方式:

结构体变量名.成员名

结构体指针变量名->成员名

(*结构体指针变量名).成员名。

由于stu是结构体变量。所以D选项引用方式错误,不应该用箭头表示。

119、【答案】D

【解析】A选项00000101|00001000=00001101,再转为十进制是14为真。

B选项8%5==3为真。C选项逻辑与两边同时为真,即为真。

D选项00000101&00001000=00000000转为十进制为0,即假值。

120、【答案】B

【解析】宏运算是将所有文本替换完再进行运算。本题中将PRINT( F(5)*2 )用PR(F(5)*2);putchar('\n')替换,将PR(F(5)*2)用printf('%d',(int)( F(5)*2))替换,再将F(5)用2.84+5替换,最后替换结果为printf('%d' ,(int)(2.84+5*2));putchar('\n'),运行结果为:12。B选项正确。

121、【答案】B

【解析】题目所说明结构体有两个成员,分别为整数num和结构体data,而结构体data又有三个成员。B选项中1001对应的是结构体的第一个成员。2008,8,1是结构体第二个成员即内存中的结构体,应作为一个整体来处理。所以1001不能单独括起来,2008,8,1可以作为一个整体括起来。

122、【答案】C

【解析】对文件进行写的操作最后一定要对文件进行关闭。否则会引起数据丢失。

123、【答案】A

【解析】本题结构体类型有两个成员,分别为x,y。并定义了结构体数组a,有两个元素分别为a[0],a[1]。a[0].y=3,a[0].x=4,a[1].x=2。输出结果是3/4*2==0。

124、【答案】C

【解析】FNA(FNB(a))先替换为FNA(a+a),再替换为a+a*a+a=2*2+2*2==8。

FNB(FNA(B))先替换为FNB(a*a),再替换为a*a+ a*a=4*4+4*4=32。

125、【答案】B

【解析】在main函数定义两个结构体变量分别为a和b。ab两个变量分别有四个成员:name[9]、gender、score、next。在main函数中,先将b的地址赋值给a的指针域,即让a.next指向结构体变量b。调用f(&a)即传递变量a的地址给f函数的形参a,然后通过赋值改变指针a指向的结构体成员,即改变指针指向的内容。对应main实参会变为Sun,f,90。在f函数中,又将d赋值给*a.next。所以a.next->name,a.next->gender,a.next->score三个即为d.name,d.gender,d.score结构体成员。即输出结果为:Sun,f,90,Li,m,100。

126、【答案】B

【解析】每次以w(写)方式打开res文件,都会将原有的内容覆盖。所以res文件中以最后一次写入为准。最后一次写入的是'K’+2==’M’。

127、【答案】B

【解析】m转为二进制是00100001,n转为二进制是01000010。

m=m^n=00100001^01000010==01100011

n=n^m=01000010^01100011==00100001转为二进制是33,

m=m^n=01100011^00100001==01000010转为二进制是66。

128、【答案】A

【解析】malloc是动态分配内存赋值给p,并不是p去申请内存,所以B错。分配的250个int类型的内存共250*4==1000个字节,正好是125个double类型的内存大小,经强制转换后可以用来存放double数组。

129、【答案】D

【解析】”wb”,“w+”,“w”三种写的方式打开文件时都会将文件原有内容覆盖,即原有内容会消失,所以不能实现信息补充的功能。

130、【答案】A

【解析】B选项define不可大写,C选项不可有两个#号,D选项char是关键字,不可用作用户标识符。

131、【答案】D

【解析】p指向a[0]。A选项(*p).n表示5。(*p).n++先加用后加,其值为5。

B选项P++先用后加。所以p++->n的值即p->n的值,也为5。

C选项->优先级高于++,所以p->n++可以理解为(p->n)++,值也为5。

D选项执行++p会使p指向第二个元素。那么(++p)的值也是第二个元素的地址。所以(++p)->n的值为6。

132、【答案】A

【解析】用户定义类型,给已经有的用户类型换个名。本题可以理解为将int *类型换个名为INTEGER,所以D选项错。所以INTEGER   p可等价于int *p。所以p是基类型为int类型的指针,A选项正确,B选项错。INTEGER *q可以理解为int **q。q是基类型为int类型的二级指针。

133、【答案】A

【解析】位运算要先转为二进制。x转为二进制是00000100。

z1=x>>y,即将x右移两位得z=00000001转为十进制是1。z2=x<

134、【答案】D

【解析】题目已经将变量s2赋值给s1,所以s1中的name成员也变为“=”。

135、【答案】A

【解析】略。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
第 一 章 概述 1-1 简述计算机程序设计语言的发展历程。 解: 迄今为止计算机程序设计语言的发展经历了机器语言、汇编语言、高级语言等阶段,C++语言是一种面向对象的编程语言,也属于高级语言。 1-2 面向对象的编程语言有哪些特点? 解: 面向对象的编程语言与以往各种编程语言有根本的不同,它设计的出发点就是为了能更直接的描述客观世界中存在的事物以及它们之间的关系。面向对象的编程语言将客观事物看作具有属性和行为的对象,通过抽象找出同一类对象的共同属性(静态特征)和行为(动态特征),形成类。通过类的继承与多态可以很方便地实现代码重用,大大缩短了软件开发周期,并使得软件风格统一。因此,面向对象的编程语言使程序能够比较直接地反问题域的本来面目,软件开发人员能够利用人类认识事物所采用的一般思维方法来进行软件开发。C++语言是目前应用最广的面向对象的编程语言。 1-3 什么是结构化程序设计方法?这种方法有哪些优点和缺点? 解: 结构化程序设计的思路是:自顶向下、逐步求精;其程序结构是按功能划分为若干个基本模块;各模块之间的关系尽可能简单,在功能上相对独立;每一模块内部均是由顺序、选择和循环三种基本结构组成;其模块化实现的具体方法是使用子程序。结构化程序设计由于采用了模块分解与功能抽象,自顶向下、分而治之的方法,从而有效地将一个较复杂的程序系统设计任务分解成许多易于控制和处理的子任务,便于开发和维护。 虽然结构化程序设计方法具有很多的优点,但它仍是一种面向过程的程序设计方法,它把数据和处理数据的过程分离为相互独立的实体。当数据结构改变时,所有相关的处理过程都要进行相应的修改,每一种相对于老问题的新方法都要带来额外的开销,程序的可重用性差。 由于图形用户界面的应用,程序运行由顺序运行演变为事件驱动,使得软件使用起来越来越方便,但开发起来却越来越困难,对这种软件的功能很难用过程来描述和实现,使用面向过程的方法来开发和维护都将非常困难。 1-4 什么是对象?什么是面向对象方法?这种方法有哪些特点? 解: 从一般意义上讲,对象是现实世界中一个实际存在的事物,它可以是有形的,也可以是无形的。对象是构成世界的一个独立单位,它具有自己的静态特征和动态特征。面向对象方法中的对象,是系统中用来描述客观事物的一个实体,它是用来构成系统的一个基本单位,由一组属性和一组行为构成。 面向对象的方法将数据及对数据的操作方法放在一起,作为一个相互依存、不可分离的整体--对象。对同类型对象抽象出其共性,形成类。类中的大多数数据,只能用本类的方法进行处理。类通过一个简单的外部接口,与外界发生关系,对象与对象之间通过消息进行通讯。这样,程序模块间的关系更为简单,程序模块的独立性、数据的安全性就有了良好的保障。通过实现继承与多态性,还可以大大提高程序的可重用性,使得软件的开发和维护都更为方便。 面向对象方法所强调的基本原则,就是直接面对客观存在的事物来进行软件开发,将人们在日常生活中习惯的思维方式和表达方式应用在软件开发中,使软件开发从过分专业化的方法、规则和技巧中回到客观世界,回到人们通常的思维。 1-5 什么叫做封装? 解: 封装是面向对象方法的一个重要原则,就是把对象的属性和服务结合成一个独立的系统单位,并尽可能隐蔽对象的内部细节。 1-6 面向对象的软件工程包括哪些主要内容? 解: 面向对象的软件工程是面向对象方法在软件工程领域的全面应用,它包括面向对象的分析(OOA)、面向对象的设计(OOD)、面向对象的编程(OOP)、面向对象的测试(OOT)和面向对象的软件维护(OOSM)等主要内容。 1-7 简述计算机内部的信息可分为几类? 解: 计算机内部的信息可以分成控制信息和数据信息二大类;控制信息可分为指令和控制字两类;数据信息可分为数值信息和非数值信息两类。 1-8 什么叫二进制?使用二进制有何优点和缺点? 解: 二进制是基数为2,每位的权是以2 为底的幂的进制,遵循逢二进一原则,基本符号为0和1。采用二进制码表示信息,有如下几个优点:1.易于物理实现;2.二进制数运算简单;3.机器可靠性高;4.通用性强。其缺点是它表示数的容量较小,表示同一个数,二进制较其他进制需要更多的位数。 1-9 请将以下十进制数值转换为二进制和十六进制补码: (1)2 (2)9 (3)93 (4)-32 (5)65535 (6)-1 解: (1) (2)10 = (10)2 = (2)16 (2) (9)10 = (1001)2 = (9)16 (3) (93)10 = (1011101)2 = (5D)16 (4) (-32)10 = (11100000)2 = (E0)16 (5) (65535)10 = (11111111 11111111)2 = (FFFF)16 (6) (-1)10 = (11111111 11111111)2 = (FFFF)16 1-10 请将以下数值转换为十进制: (1)(1010)2 (2)(10001111)2 (3)(01011111 11000011)2 (4)(7F)16 (5)(2D3E)16 (6)(F10E)16 解: (1)(1010)2 = (10)10 (2)(10001111)2 = (143)10 (3)(01011111 11000011)2 = (24515)10 (4)(7F)16 = (127)10 (5)(2D3E)16 = (11582)10 (6)(F10E)16 = (61710)10 1-11 简要比较原码、反码、补码等几种编码方法。 解: 原码:将符号位数字化为 0 或 1,数的绝对值与符号一起编码,即所谓"符号──绝对值表示"的编码。 正数的反码和补码与原码表示相同。 负数的反码与原码有如下关系: 符号位相同(仍用1表示),其余各位取反(0变1,1变0)。 补码由该数反码的最末位加1求得。 第 二 章 C++简单程序设计 2-1 C++语言有那些主要特点和优点? 解: C++语言的主要特点表现在两个方面,一是全面兼容C,二是支持面向对象的方法。C++是一个更好的C,它保持了C的简洁、高效、接近汇编语言、具有良好的可读性和可移植性等特点,对C的类型系统进行了改革和扩充,因此C++比C更安全,C++的编译系统能检查出更多的类型错误。 C++语言最重要的特点是支持面向对象。 2-2 下列标识符哪些是合法的? Program, -page, _lock, test2, 3in1, @mail, A_B_C_D 解: Program, _lock, test2, A_B_C_D是合法的标识符,其它的不是。 2-3 例2.1中每条语句的作用是什么? #include void main(void) { cout<<"Hello!\n"; cout<<"Welcome to c++!\n"; } 解: #include //指示编译器将文件iostream.h中的代码 //嵌入到该程序中该指令所在的地方 void main() //主函数名,void 表示函数没有返回值 { //函数体标志 cout<<"Hello!\n"; //输出字符串Hello!到标准输出设备(显示器)上。 cout<<"Welcome to c++!\n"; //输出字符串Welcome to c++! } 在屏幕输出如下: Hello! Welcome to c++! 2-4 使用关键字const而不是#define语句的好处有哪些? 解: const定义的常量是有类型的,所以在使用它们时编译器可以查错;而且,这些变量在调试时仍然是可见的。 2-5 请写出C++语句声明一个常量PI,值为3.1416;再声明一个浮点型变量a,把PI的值赋给a。 解: const float PI = 3.1416; float a = PI; 2-6 在下面的枚举类型中,Blue的值是多少? enum COLOR { WHITE, BLACK = 100, RED, BLUE, GREEN = 300 }; 解: Blue = 102 2-7 注释有什么作用?C++中有哪几种注释的方法?他们之间有什么区别? 解: 注释在程序中的作用是对程序进行注解和说明,以便于阅读。编译系统在对源程序进行编译时不理会注释部分,因此注释对于程序的功能实现不起任何作用。而且由于编译时忽略注释部分,所以注释内容不会增加最终产生的可执行程序的大小。适当地使用注释,能够提高程序的可读性。在C++中,有两种给出注释的方法:一种是延用C语言方法,使用"/*"和"*/"括起注释文字。另一种方法是使用"//",从"//"开始,直到它所在行的行尾,所有字符都被作为注释处理。 2-8 什么叫做表达式?x = 5 + 7是一个表达式吗?它的值是多少? 解: 任何一个用于计算值的公式都可称为表达式。x = 5 + 7是一个表达式,它的值为12。 2-9 下列表达式的值是多少? 1. 201 / 4 2. 201 % 4 3. 201 / 4.0 解: 1. 50 2. 1 3. 50.25 2-10 执行完下列语句后,a、b、c三个变量的值为多少? a = 30; b = a++; c = ++a; 解: a:32 ; b:30 ; c:32; 2-11 在一个for循环中,可以初始化多个变量吗?如何实现? 解: 在for循环设置条件的第一个";"前,用,分隔不同的赋值表达式。 例如: for (x = 0, y = 10; x < 100; x++, y++) 2-12 执行完下列语句后,n的值为多少? int n; for (n = 0; n < 100; n++) 解: n的值为100 2-13 写一条for语句,计数条件为n从100到200,步长为2;然后用while和do…while语句完成同样的循环。 解: for循环: for (int n = 100; n <= 200; n += 2); while循环: int x = 100; while (n <= 200) n += 2; do…while循环: int n = 100; do { n += 2; } while(n y) x = y; else // y > x || y == x y = x; 2-17 修改下面这个程序中的错误,改正后它的运行结果是什么? #include void main() int i int j; i = 10; /* 给i赋值 j = 20; /* 给j赋值 */ cout << "i + j = << i + j; /* 输出结果 */ return 0; } 解: 改正: #include int main() { int i; int j; i = 10; // 给i赋值 j = 20; /* 给j赋值 */ cout << "i + j = " << i + j; /* 输出结果 */ return 0; } 程序运行输出: i + j = 30 2-18 编写一个程序,运行时提示输入一个数字,再把这个数字显示出来。 解: 源程序: #include int main() { int i; cout <> i; cout << "您输入一个数字是" << i << endl; return 0; } 程序运行输出: 请输入一个数字:5 您输入一个数字是5 2-19 C++有哪几种数据类型?简述其值域。编程显示你使用的计算机中的各种数据类型的字节数。 解: 源程序: #include int main() { cout << "The size of an int is:\t\t" << sizeof(int) << " bytes.\n"; cout << "The size of a short int is:\t" << sizeof(short) << " bytes.\n"; cout << "The size of a long int is:\t" << sizeof(long) << " bytes.\n"; cout << "The size of a char is:\t\t" << sizeof(char) << " bytes.\n"; cout << "The size of a float is:\t\t" << sizeof(float) << " bytes.\n"; cout << "The size of a double is:\t" << sizeof(double) << " bytes.\n"; return 0; } 程序运行输出: The size of an int is: 4 bytes. The size of a short int is: 2 bytes. The size of a long int is: 4 bytes. The size of a char is: 1 bytes. The size of a float is: 4 bytes. The size of a double is: 8 bytes. 2-20 打印ASCII码为32~127的字符。 解: #include int main() { for (int i = 32; i<128; i++) cout << (char) i; return 0; } 程序运行输出: !"#$%G'()*+,./0123456789:;?@ABCDEFGHIJKLMNOP_QRSTUVWXYZ[\]^'abcdefghijklmnopqrstuvwxyz~s 2-21 运行下面的程序,观察其输出,与你的设想是否相同? #include int main() { unsigned int x; unsigned int y = 100; unsigned int z = 50; x= y - z; cout << "Difference is: " << x; x = z - y; cout << "\nNow difference is: " << x <<endl; return 0; } 解: 程序运行输出: Difference is: 50 Now difference is: 4294967246 注意,第二行的输出并非 -50,注意x、y、z的数据类型。 2-22 运行下面的程序,观察其输出,体会i++与++i的差别。 #include int main() { int myAge = 39; // initialize two integers int yourAge = 39; cout << "I am: " << myAge << " years old.\n"; cout << "You are: " << yourAge << " years old\n"; myAge++; // postfix increment ++yourAge; // prefix increment cout << "One year passes...\n"; cout << "I am: " << myAge << " years old.\n"; cout << "You are: " << yourAge << " years old\n"; cout << "Another year passes\n"; cout << "I am: " << myAge++ << " years old.\n"; cout << "You are: " << ++yourAge << " years old\n"; cout << "Let's print it again.\n"; cout << "I am: " << myAge << " years old.\n"; cout << "You are: " << yourAge << " years old\n"; return 0; } 解: 程序运行输出: I am 39 years old You are 39 years old One year passes I am 40 years old You are 40 years old Another year passes I am 40 years old You are 41 years old Let's print it again I am 41 years old You are 41 years old 2-23 什么叫常量?什么叫变量? 解: 所谓常量是指在程序运行的整个过程中其值始终不可改变的量,除了用文字表示常量外,也可以为常量命名,这就是符号常量;在程序的执行过程中其值可以变化的量称为变量,变量是需要用名字来标识的。 2-24 变量有哪几种存储类型? 解: 变量有以下几种存储类型: auto存储类型:采用堆栈方式分配内存空间,属于一时性存储,其存储空间可以被若干变量多次覆盖使用; register存储类型:存放在通用寄存器中; extern存储类型:在所有函数和程序段中都可引用; static存储类型:在内存中是以固定地址存放的,在整个程序运行期间都有效。 2-25 写出下列表达式的值: 1. 2 < 3 && 6 < 9 2. ! ( 4 5) || (6 > 2 解: 1. 1 2. -1 3. 0 4. 0 2-28 编写一个完整的程序,实现功能:向用户提问"现在正在下雨吗?",提示用户输入Y或N。若输入为Y,显示"现在正在下雨。"; 若输入为N,显示"现在没有下雨。";否则继续提问"现在正在下雨吗?" 解: 源程序: #include #include void main() { char flag; while(1) { cout <> flag; if ( toupper(flag) == 'Y') { cout << "现在正在下雨。"; break; } if ( toupper(flag) == 'N') { cout << "现在没有下雨。"; break; } } } 程序运行输出: 现在正在下雨吗?(Yes or No):x 现在正在下雨吗?(Yes or No):l 现在正在下雨吗?(Yes or No):q 现在正在下雨吗?(Yes or No):n 现在没有下雨。 或: 现在正在下雨吗?(Yes or No):y 现在正在下雨。 2-29 编写一个完整的程序,运行时向用户提问"你考试考了多少分?(0~100)",接收输入后判断其等级,显示出来。规则如下: 解: #include void main() { int i,score; cout <> score; if (score>100 || score<0) cout << "分数值必须在0到100之间!"; else { i = score/10; switch (i) { case 10: case 9: cout << "你的成绩为优!"; break; case 8: cout << "你的成绩为良!"; break; case 7: case 6: cout << "你的成绩为中!"; break; default: cout << "你的成绩为差!"; } } } 程序运行输出: 你考试考了多少分?(0~100):85 你的成绩为良! 2-30 (1)实现一个简单的菜单程序,运行时显示"Menu: A(dd) D(elete) S(ort) Q(uit), Select one:"提示用户输入,A表示增加,D表示删除,S表示排序,Q表示退出,输入为A、D、S时分别提示"数据已经增加、删除、排序。"输入为Q时程序结束。要求使用if … else语句进行判断,用break、continue控制程序流程。 解: #include #include void main() { char choice,c; while(1) { cout <> c; choice = toupper(c); if (choice == 'A') { cout << "数据已经增加. " << endl; continue; } else if (choice == 'D') { cout << "数据已经删除. " << endl; continue; } else if (choice == 'S') { cout << "数据已经排序. " << endl; continue; } else if (choice == 'Q') break; } } 程序运行输出: Menu: A(dd) D(elete) S(ort) Q(uit), Select one:a 数据已经增加. Menu: A(dd) D(elete) S(ort) Q(uit), Select one:d 数据已经删除. Menu: A(dd) D(elete) S(ort) Q(uit), Select one:s 数据已经排序. Menu: A(dd) D(elete) S(ort) Q(uit), Select one:q (2)实现一个简单的菜单程序,运行时显示"Menu: A(dd) D(elete) S(ort) Q(uit), Select one:"提示用户输入,A表示增加,D表示删除,S表示排序,Q表示退出,输入为A、D、S时分别提示"数据已经增加、删除、排序。"输入为Q时程序结束。要求使用Switch语句。 解: 源程序: #include #include void main() { char choice; while(1) { cout <> choice; switch(toupper(choice)) { case 'A': cout << "数据已经增加. " << endl; break; case 'D': cout << "数据已经删除. " << endl; break; case 'S': cout << "数据已经排序. " << endl; break; case 'Q': exit(0); break; default: ; } } } 程序运行输出: Menu: A(dd) D(elete) S(ort) Q(uit), Select one:a 数据已经增加. Menu: A(dd) D(elete) S(ort) Q(uit), Select one:d 数据已经删除. Menu: A(dd) D(elete) S(ort) Q(uit), Select one:s 数据已经排序. Menu: A(dd) D(elete) S(ort) Q(uit), Select one:q 2-31 用穷举法找出1~100间的质数,显示出来。分别使用while,do-while,for循环语句实现。 解: 源程序: 使用while循环语句: #include #include void main() { int i,j,k,flag; i = 2; while(i <= 100) { flag = 1; k = sqrt(i); j = 2; while (j <= k) { if(i%j == 0) { flag = 0; break; } j++; } if (flag) cout << i << "是质数." << endl; i++; } } 使用do…while循环语句: #include #include void main() { int i,j,k,flag; i = 2; do{ flag = 1; k = sqrt(i); j = 2; do{ if(i%j == 0) { flag = 0; break; } j++; }while (j <= k); if (flag) cout << i << "是质数." << endl; i++; }while(i <= 100); } 使用for循环语句: #include #include void main() { int i,j,k,flag; for(i = 2; i <= 100; i++) { flag = 1; k = sqrt(i); for (j = 2; j <= k; j++) { if(i%j == 0) { flag = 0; break; } } if (flag) cout << i << "是质数." << endl; } } 程序运行输出: 2是质数. 3是质数. 5是质数. 7是质数. 11是质数. 13是质数. 17是质数. 19是质数. 23是质数. 29是质数. 31是质数. 37是质数. 41是质数. 43是质数. 47是质数. 53是质数. 59是质数. 61是质数. 67是质数. 71是质数. 73是质数. 79是质数. 83是质数. 89是质数. 97是质数. 2-32 比较Break语句与Continue语句的不同用法。 解: Break使程序从循环体和switch语句内跳出,继续执行逻辑上的下一条语句,不能用在别处; continue 语句结束本次循环,接着开始判断决定是否继续执行下一次循环; 2-33 定义一个表示时间的结构体,可以精确表示年、月、日、小时、分、秒;提示用户输入年、月、日、小时、分、秒的值,然后完整地显示出来。 解: 源程序见"实验指导"部分实验二 2-34 在程序中定义一个整型变量,赋以1~100的值,要求用户猜这个数,比较两个数的大小,把结果提示给用户,直到猜对为止。分别使用while、do…while语句实现循环。 解: //使用while语句 #include void main() { int n = 18; int m = 0; while(m != n) { cout <> m; if (n > m) cout << "你猜的值太小了!" << endl; else if (n < m) cout << "你猜的值太大了!" << endl; else cout << "你猜对了!" << endl; } } //使用do…while语句 #include void main() { int n = 18; int m = 0; do{ cout <> m; if (n > m) cout << "你猜的值太小了!" << endl; else if (n < m) cout << "你猜的值太大了!" << endl; else cout << "你猜对了!" << endl; }while(n != m); } 程序运行输出: 请猜这个数的值为多少?(0~~100):50 你猜的值太大了! 请猜这个数的值为多少?(0~~100):25 你猜的值太大了! 请猜这个数的值为多少?(0~~100):10 你猜的值太小了! 请猜这个数的值为多少?(0~~100):15 你猜的值太小了! 请猜这个数的值为多少?(0~~100):18 你猜对了! 2-35 定义枚举类型weekday,包括Sunday到Saturday七个元素在程序中定义weekday类型的变量,对其赋值,定义整型变量,看看能否对其赋weekday类型的值。 解: #include enum weekday { Sunday, Monday, Tuesday, Wednesday, Thursday, Friday, Saturday }; void main() { int i; weekday d = Thursday; cout << "d = " << d << endl; i = d; cout << "i = " << i << endl; d = (weekday)6; cout << "d = " << d << endl; d = weekday( 4 ); cout << "d = " << d << endl; } 程序运行输出: d = 4 i = 4 d = 6 d = 4 2-36口袋中有红、黄、蓝、白、黑五种颜色的球若干个,每次从口袋中取出三个不同颜色的球,问有多少种取法。 解: #include using namespace std; int main() { enum color{red,yellow,blue,white,black}; enum color pri; int n,loop,i,j,k; char c; n=0; for(i=red;i<=black;i++) for(j=red;j<=black;j++) if(i!=j) { for(k=red;k<black;k++) if((k!=i)&&(k!=j)) { n=n+1; cout.width(4); cout<<n; for(loop=1;loop<=3;loop++) { switch(loop) { case 1: pri=(enum color)i; break; case 2: pri=(enum color)j; break; case 3: pri=(enum color)k; break; default: break; } switch(pri) { case red:cout<<"red";break; case yellow:cout<<"yellow";break; case blue:cout<<"blue";break; case white:cout<<"white";break; case black:cout<<"black";break; default: break; } } cout<<endl; } } cout<<"total:"<<n<<endl; } 2-37输出九九算表 #include #include using namespace std; int main() { int i,j; for(i=1;i<5;i++) cout<<setw(4)<<i; cout<<endl; cout<<endl; for(i=1;i<5;i++) { for(j=1;j<5;j++) cout<<setw(4)<<(i*j); cout<<endl; } } 第三章 函数 3-1 C++中的函数是什么?什么叫主调函数,什么叫被调函数,二者之间有什么关系?如何调用一个函数? 解: 一个较为复杂的系统往往需要划分为若干子系统,高级语言中的子程序就是用来实现这种模块划分的。C和C++语言中的子程序就体现为函数。调用其它函数的函数被称为主调函数,被其它函数调用的函数称为被调函数。一个函数很可能既调用别的函数又被另外的函数调用,这样它可能在某一个调用与被调用关系中充当主调函数,而在另一个调用与被调用关系中充当被调函数。 调用函数之前先要声明函数原型。按如下形式声明: 类型标识符 被调函数名 (含类型说明的形参表); 声明了函数原型之后,便可以按如下形式调用子函数: 函数名(实参列表) 3-2 观察下面程序的运行输出,与你设想的有何不同?仔细体会引用的用法。 源程序: #include int main() { int intOne; int &rSomeRef; = intOne; intOne = 5; cout << "intOne:\t\t" << intOne << endl; cout << "rSomeRef:\t" << rSomeRef << endl; int intTwo = 8; rSomeRef = intTwo; // not what you think! cout << "\nintOne:\t\t" << intOne << endl; cout << "intTwo:\t\t" << intTwo << endl; cout << "rSomeRef:\t" << rSomeRef << endl; return 0; } 程序运行输出: intOne: 5 rSomeRef: 5 intOne: 8 intTwo: 8 rSomeRef: 8 3-3 比较值调用和引用调用的相同点与不同点。 解: 值调用是指当发生函数调用时,给形参分配内存空间,并用实参来初始化形参(直接将实参的值传递给形参)。这一过程是参数值的单向传递过程,一旦形参获得了值便与实参脱离关系,此后无论形参发生了怎样的改变,都不会影响到实参。 引用调用将引用作为形参,在执行主调函数中的调用语句时,系统自动用实参来初始化形参。这样形参就成为实参的一个别名,对形参的任何操作也就直接作用于实参。 3-4 什么叫内联函数?它有哪些特点? 解: 定义时使用关键字 inline的函数叫做内联函数; 编译器在编译时在调用处用函数体进行替换,节省了参数传递、控制转移等开销; 内联函数体内不能有循环语句和switch语句; 内联函数的定义必须出现在内联函数第一次被调用之前; 对内联函数不能进行异常接口声明; 3-5 函数原型中的参数名与函数定义中的参数名以及函数调用中的参数名必须一致吗? 解: 不必一致,所有的参数是根据位置和类型而不是名字来区分的。 3-6 重载函数时通过什么来区分? 解: 重载的函数的函数名是相同的,但它们的参数的个数和数据类型不同,编译器根据实参和形参的类型及个数的最佳匹配,自动确定调用哪一个函数。 3-7 编写函数,参数为两个unsigned short int型数,返回值为第一个参数除以第二个参数的结果,数据类型为short int;如果第二个参数为0,则返回值为-1。在主程序中实现输入输出。 解: 源程序: #include short int Divider(unsigned short int a, unsigned short int b) { if (b == 0) return -1; else return a/b; } typedef unsigned short int USHORT; typedef unsigned long int ULONG; int main() { USHORT one, two; short int answer; cout <> one; cout <> two; answer = Divider(one, two); if (answer > -1) cout << "Answer: " << answer; else cout << "Error, can't divide by zero!"; return 0; } 程序运行输出: Enter two numbers. Number one:8 Number two:2 Answer: 4 3-8 编写函数把华氏温度转换为摄氏温度,公式为:C = (F - 32) * 5/9; 在主程序中提示用户输入一个华氏温度,转化后输出相应的摄氏温度。 解: 源程序见"实验指导"部分实验三 3-9 编写函数判断一个数是否是质数,在主程序中实现输入、输出。 解: #include #include int prime(int i); //判一个数是否是质数的函数 void main() { int i; cout <> i; if (prime(i)) cout << i << "是质数." << endl; else cout << i << "不是质数." << endl; } int prime(int i) { int j,k,flag; flag = 1; k = sqrt(i); for (j = 2; j <= k; j++) { if(i%j == 0) { flag = 0; break; } } if (flag) return 1; else return 0; } 程序运行输出: 请输入一个整数:1151 1151是质数. 3-10 编写函数求两个整数的最大公约数和最小公倍数。 解: 源程序: #include #include int fn1(int i,int j); //求最大公约数的函数 void main() { int i,j,x,y; cout <> i ; cout <> j ; x = fn1(i,j); y = i * j / x; cout << i << "和" << j << "的最大公约数是:" << x << endl; cout << i << "和" << j << "的最小公倍数是:" << y << endl; } int fn1(int i, int j) { int temp; if (i < j) { temp = i; i = j; j = i; } while(j != 0) { temp = i % j; i = j; j = temp; } return i; } 程序运行输出: 请输入一个正整数:120 请输入另一个正整数:72 120和72的最大公约数是:24 120和72的最小公倍数是:360 3-11 什么叫作嵌套调用?什么叫作递归调用? 解: 函数允许嵌套调用,如果函数1调用了函数2,函数2再调用函数3,便形成了函数的嵌套调用。 函数可以直接或间接地调用自身,称为递归调用。 3-12 在主程序中提示输入整数n,编写函数用递归的方法求1 + 2 + … + n的值。 解: #include #include int fn1(int i); void main() { int i; cout <> i ; cout << "从1累加到" <<i << "的和为:" << fn1(i) << endl; } int fn1(int i) { if (i == 1) return 1; else return i + fn1(i -1); } 程序运行输出: 请输入一个正整数:100 从1累加到100的和为:5050 3-13 编写递归函数GetPower(int x, int y)计算x的y次幂, 在主程序中实现输入输出。 解: 源程序: #include long GetPower(int x, int y); int main() { int number, power; long answer; cout <> number; cout <> power; answer = GetPower(number,power); cout << number << " to the " << power << "th power is " <<answer <2; fib(1) = fib(2) = 1;观察递归调用的过程。 解: 源程序见"实验指导"部分实验三 3-15 用递归的方法编写函数求n阶勒让德多项式的值,在主程序中实现输入、输出; 解: #include float p(int n, int x); void main() { int n,x; cout <> n; cout <> x; cout << "n = " << n << endl; cout << "x = " << x << endl; cout << "P" << n << "(" << x << ") = " << p(n,x) << endl; } float p(int n, int x) { if (n == 0) return 1; else if (n == 1) return x; else return ((2*n-1)*x*p(n-1,x) - (n-1)*p(n-2,x)) /n ; } 程序运行输出: 请输入正整数n:1 请输入正整数x:2 n = 1 x = 2 P1(2) = 2 请输入正整数n:3 请输入正整数x:4 n = 3 x = 4 P3(4) = 154 第 四 章 类 4-1 解释public和private的作用,公有类型成员与私有类型成员有些什么区别? 解: 公有类型成员用public关键字声明,公有类型定义了类的外部接口;私有类型的成员用private关键字声明,只允许本类的函数成员来访问,而类外部的任何访问都是非法的,这样,私有的成员就整个隐蔽在类中,在类的外部根本就无法看到,实现了访问权限的有效控制。 4-2 protected关键字有何作用? 解: protected用来声明保护类型的成员,保护类型的性质和私有类型的性质相似,其差别在于继承和派生时派生类的成员函数可以访问基类的保护成员。 4-3 构造函数和析构函数有什么作用? 解: 构造函数的作用就是在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态,使此对象具有区别于彼对象的特征,完成的就是是一个从一般到具体的过程,构造函数在对象创建的时候由系统自动调用。 析构函数与构造函数的作用几乎正好相反,它是用来完成对象被删除前的一些清理工作,也就是专门作扫尾工作的。一般情况下,析构函数是在对象的生存期即将结束的时刻由系统自动调用的,它的调用完成之后,对象也就消失了,相应的内存空间也被释放。 4-4 数据成员可以为公有的吗?成员函数可以为私有的吗? 解: 可以,二者都是合法的。数据成员和成员函数都可以为公有或私有的。但数据成员最好定义为私有的。 4-5 已知class A中有数据成员int a,如果定义了A的两个对象A1、A2,它们各自的数据成员a的值可以不同吗? 解: 可以,类的每一个对象都有自己的数据成员。 4-6 什么叫做拷贝构造函数?拷贝构造函数何时被调用? 解: 拷贝构造函数是一种特殊的构造函数,具有一般构造函数的所有特性,其形参是本类的对象的引用,其作用是使用一个已经存在的对象,去初始化一个新的同类的对象。在以下三种情况下会被调用:在当用类的一个对象去初始化该类的另一个对象时;如果函数的形参是类对象,调用函数进行形参和实参结合时;如果函数的返回值是类对象,函数调用完成返回时; 4-7 拷贝构造函数与赋值运算符(=)有何不同? 解: 赋值运算符(=)作用于一个已存在的对象;而拷贝构造函数会创建一个新的对象。 4-8 定义一个Dog 类,包含的age、weight等属性,以及对这些属性操作的方法。实现并测试这个类。 解: 源程序: #include class Dog { public: Dog (int initialAge = 0, int initialWeight = 5); ~Dog(); int GetAge() { return itsAge;} // inline! void SetAge (int age) { itsAge = age;} // inline! int GetWeight() { return itsWeight;} // inline! void SetWeight (int weight) { itsAge = weight;} // inline! private: int itsAge, itsWeight; }; Dog::Dog(int initialAge, int initialWeight) { itsAge = initialAge; itsWeight = initialWeight; } Dog::~Dog() //destructor, takes no action { } int main() { Dog Jack(2,10); cout << "Jack is a Dog who is " ; cout << Jack.GetAge() << " years old and"; cout << Jack.GetWeight() << " pounds weight.\n"; Jack.SetAge(7); Jack.SetWeight(20); cout << "Now Jack is " ; cout << Jack.GetAge() << " years old and"; cout << Jack.GetWeight() << " pounds weight."; return 0; } 程序运行输出: Jack is a Dog who is 2 years old and 10 pounds weight. Now Jack is 7 years old 20 pounds weight. 4-9 设计并测试一个名为Rectangle的矩形类,其属性为矩形的左下角与右上角两个点的坐标,能计算矩形的面积。 解: 源程序: #include class Rectangle { public: Rectangle (int top, int left, int bottom, int right); ~Rectangle () {} int GetTop() const { return itsTop; } int GetLeft() const { return itsLeft; } int GetBottom() const { return itsBottom; } int GetRight() const { return itsRight; } void SetTop(int top) { itsTop = top; } void SetLeft (int left) { itsLeft = left; } void SetBottom (int bottom) { itsBottom = bottom; } void SetRight (int right) { itsRight = right; } int GetArea() const; private: int itsTop; int itsLeft; int itsBottom; int itsRight; }; Rectangle::Rectangle(int top, int left, int bottom, int right) { itsTop = top; itsLeft = left; itsBottom = bottom; itsRight = right; } int Rectangle::GetArea() const { int Width = itsRight-itsLeft; int Height = itsTop - itsBottom; return (Width * Height); } int main() { Rectangle MyRectangle (100, 20, 50, 80 ); int Area = MyRectangle.GetArea(); cout << "Area: " << Area << "\n"; return 0; } 程序运行输出: Area: 3000 Upper Left X Coordinate: 20 4-10 设计一个用于人事管理的People(人员)类。考虑到通用性,这里只抽象出所有类型人员都具有的属性:number(编号)、sex(性别)、birthday(出生日期)、id(身份证号)等等。其中"出生日期"定义为一个"日期"类内嵌子对象。用成员函数实现对人员信息的录入和显示。要求包括:构造函数和析构函数、拷贝构造函数、内联成员函数、带缺省形参值的成员函数、聚集。 解: 本题用作实验四的选做题,因此不给出答案。 4-11 定义一个矩形类,有长、宽两个属性,有成员函数计算矩形的面积 解: #include class Rectangle { public: Rectangle(float len, float width) { Length = len; Width = width; } ~Rectangle(){}; float GetArea() { return Length * Width; } float GetLength() { return Length; } float GetWidth() { return Width; } private: float Length; float Width; }; void main() { float length, width; cout <> length; cout <> width; Rectangle r(length, width); cout << "长为" << length << "宽为" << width << "的矩形的面积为:" << r.GetArea () << endl; } 程序运行输出: 请输入矩形的长度:5 请输入矩形的宽度:4 长为5宽为4的矩形的面积为:20 4-12 定义一个"数据类型" datatype类,能处理包含字符型、整型、浮点型三种类型的数据,给出其构造函数。 解: #include class datatype{ enum{ character, integer, floating_point } vartype; union { char c; int i; float f; }; public: datatype(char ch) { vartype = character; c = ch; } datatype(int ii) { vartype = integer; i = ii; } datatype(float ff) { vartype = floating_point; f = ff; } void print(); }; void datatype::print() { switch (vartype) { case character: cout << "字符型: " << c << endl; break; case integer: cout << "整型: " << i << endl; break; case floating_point: cout << "浮点型: " << f << endl; break; } } void main() { datatype A('c'), B(12), C(1.44F); A.print(); B.print(); C.print(); } 程序运行输出: 字符型: c 整型: 12 浮点型: 1.44 4-13 定义一个Circle类,有数据成员半径Radius,成员函数GetArea(),计算圆的面积,构造一个Circle的对象进行测试。 解: #include class Circle { public: Circle(float radius){ Radius = radius;} ~Circle(){} float GetArea() { return 3.14 * Radius * Radius; } private: float Radius; }; void main() { float radius; cout <> radius; Circle p(radius); cout << "半径为" << radius << "的圆的面积为:" << p.GetArea () << endl; } 程序运行输出: 请输入圆的半径:5 半径为5的圆的面积为:78.5 4-14 定义一个tree类,有成员ages,成员函数grow(int years)对ages加上years,age()显示tree对象的ages的值。 解: #include class Tree { int ages; public: Tree(int n=0); ~Tree(); void grow(int years); void age(); }; Tree::Tree(int n) { ages = n; } Tree::~Tree() { age(); } void Tree::grow(int years) { ages += years; } void Tree::age() { cout << "这棵树的年龄为" << ages << endl; } void main() { Tree t(12); t.age(); t.grow(4); } 程序运行输出: 这棵树的年龄为12 这棵树的年龄为16 第 五 章 C++程序的基本结构 5-1 什么叫做作用域?有哪几种类型的作用域? 解: 作用域讨论的是标识符的有效范围,作用域是一个标识符在程序正文中有效的区域。C++的作用域分为函数原形作用域、块作用域(局部作用域)、类作用域和文件作用域. 5-2 什么叫做可见性?可见性的一般规则是什么? 解: 可见性是标识符是否可以引用的问题; 可见性的一般规则是:标识符要声明在前,引用在后,在同一作用域中,不能声明同名的标识符。对于在不同的作用域声明的标识符,遵循的原则是:若有两个或多个具有包含关系的作用域,外层声明的标识符如果在内层没有声明同名标识符时仍可见,如果内层声明了同名标识符则外层标识符不可见。 5-3 下面的程序的运行结果是什么,实际运行一下,看看与你的设想有何不同。 #include void myFunction(); int x = 5, y = 7; int main() { cout << "x from main: " << x << "\n"; cout << "y from main: " << y << "\n\n"; myFunction(); cout << "Back from myFunction!\n\n"; cout << "x from main: " << x << "\n"; cout << "y from main: " << y << "\n"; return 0; } void myFunction() { int y = 10; cout << "x from myFunction: " << x << "\n"; cout << "y from myFunction: " << y << "\n\n"; } 解: 程序运行输出: x from main: 5 y from main: 7 x from myFunction: 5 y from myFunction: 10 Back from myFunction! x from main: 5 y from main: 7 5-4 假设有两个无关系的类Engine和Fuel,使用时,怎样允许Fuel成员访问Engine中的私有和保护的成员? 解: 源程序: class fuel; class engine { friend class fuel; private; int powerlevel; public; engine(){ powerLevel = 0;} void engine_fn(fuel &f); }; class fuel { friend class engine; private; int fuelLevel; public: fuel(){ fuelLevel = 0;} void fuel_fn( engine &e); }; 5-5 什么叫做静态数据成员?它有何特点? 解: 类的静态数据成员是类的数据成员的一种特例,采用static关键字来声明。对于类的普通数据成员,每一个类的对象都拥有一个拷贝,就是说每个对象的同名数据成员可以分别存储不同的数值,这也是保证对象拥有自身区别于其它对象的特征的需要,但是静态数据成员,每个类只要一个拷贝,由所有该类的对象共同维护和使用,这个共同维护、使用也就实现了同一类的不同对象之间的数据共享。 5-6 什么叫做静态函数成员?它有何特点? 解: 使用static关键字声明的函数成员是静态的,静态函数成员属于整个类,同一个类的所有对象共同维护,为这些对象所共享。静态函数成员具有以下两个方面的好处,一是由于静态成员函数只能直接访问同一个类的静态数据成员,可以保证不会对该类的其余数据成员造成负面影响;二是同一个类只维护一个静态函数成员的拷贝,节约了系统的开销,提高程序的运行效率。 5-7 定义一个Cat类,拥有静态数据成员HowManyCats,记录Cat的个体数目;静态成员函数GetHowMany(),存取HowManyCats。设计程序测试这个类,体会静态数据成员和静态成员函数的用法。 解: 源程序: #include class Cat { public: Cat(int age):itsAge(age){HowManyCats++; } virtual ~Cat() { HowManyCats--; } virtual int GetAge() { return itsAge; } virtual void SetAge(int age) { itsAge = age; } static int GetHowMany() { return HowManyCats; } private: int itsAge; static int HowManyCats; }; int Cat::HowManyCats = 0; void TelepathicFunction(); int main() { const int MaxCats = 5; Cat *CatHouse[MaxCats]; int i; for (i = 0; i<MaxCats; i++) { CatHouse[i] = new Cat(i); TelepathicFunction(); } for ( i = 0; i<MaxCats; i++) { delete CatHouse[i]; TelepathicFunction(); } return 0; } void TelepathicFunction() { cout << "There are " << Cat::GetHowMany() << " cats alive!\n"; } 程序运行输出: There are 1 cats alive! There are 2 cats alive! There are 3 cats alive! There are 4 cats alive! There are 5 cats alive! There are 4 cats alive! There are 3 cats alive! There are 2 cats alive! There are 1 cats alive! There are 0 cats alive! 5-8 什么叫做友元函数?什么叫做友元类? 解: 友元函数是使用friend关键字声明的函数,它可以访问相应类的保护成员和私有成员。友元类是使用friend关键字声明的类,它的所有成员函数都是相应类的友元函数。 5-9 如果类A是类B的友元,类B是类C的友元,类D是类A的派生类,那么类B是类A的友元吗?类C是类A的友元吗?类D是类B的友元吗? 解: 类B不是类A的友元,友元关系不具有交换性; 类C不是类A的友元,友元关系不具有传递性; 类D不是类B的友元,友元关系不能被继承。 5-10 静态成员变量可以为私有的吗?声明一个私有的静态整型成员变量。 解: 可以,例如: private: static int a; 5-11 在一个文件中定义一个全局变量n,主函数main(),在另一个文件中定义函数fn1(),在main()中对n赋值,再调用fn1(),在fn1()中也对n赋值,显示n最后的值。 解: #include #include "fn1.h" int n; void main() { n = 20; fn1(); cout << "n的值为" <<n; } // fn1.h文件 extern int n; void fn1() { n=30; } 程序运行输出: n的值为30 5-12 在函数fn1()中定义一个静态变量n,fn1()中对n的值加1,在主函数中,调用fn1()十次,显示n的值。 解: #include void fn1() { static int n = 0; n++; cout << "n的值为" << n <<endl; } void main() { for(int i = 0; i i =+10; } void Y::g(X* x) { x->i ++; } class Z { public: void f(X* x) { x->i += 5; } }; #endif // MY_X_Y_Z_H 程序运行输出:无 5-14 定义Boat与Car两个类,二者都有weight属性,定义二者的一个友元函数totalWeight(),计算二者的重量和。 解: 源程序: #include class Boat; class Car { private: int weight; public: Car(int j){weight = j;} friend int totalWeight(Car &aCar;, Boat &aBoat;); }; class Boat { private: int weight; public: Boat(int j){weight = j;} friend int totalWeight(Car &aCar;, Boat &aBoat;); }; int totalWeight(Car &aCar;, Boat &aBoat;) { return aCar.weight + aBoat.weight; } void main() { Car c1(4); Boat b1(5); cout << totalWeight(c1, b1) << endl; } 程序运行输出: 9 第 六 章 数组、指针与字符串 6-1 数组A[10][5][15]一共有多少个元素? 解: 10×5×15 = 750 个元素 6-2 在数组A[20]中第一个元素和最后一个元素是哪一个? 解: 第一个元素是A[0],最后一个元素是A[19]。 6-3 用一条语句定义一个有五个元素的整型数组,并依次赋予1~5的初值。 解: 源程序: int IntegerArray[5] = { 1, 2, 3, 4, 5 }; 或:int IntegerArray[] = { 1, 2, 3, 4, 5 }; 6-4 已知有一个数组名叫oneArray,用一条语句求出其元素的个数。 解: 源程序: nArrayLength = sizeof(oneArray) / sizeof(oneArray[0]); 6-5 用一条语句定义一个有5×3个元素的二维整型数组,并依次赋予1~15的初值。 解: 源程序: int theArray[5][3] = { 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 }; 或:int theArray[5][3] = { {1,2,3}, {4,5,6}, {7,8,9}, {10,11,12},{13,14,15} }; 6-6 运算符*和&的作用是什么? 解: *称为指针运算符,是一个一元操作符,表示指针所指向的对象的值;&称为取地址运算符,也是一个一元操作符,是用来得到一个对象的地址。 6-7 什么叫做指针?指针中储存的地址和这个地址中的值有何区别? 解: 指针是一种数据类型,具有指针类型的变量称为指针变量。指针变量存放的是另外一个对象的地址,这个地址中的值就是另一个对象的内容。 6-8 定义一个整型指针,用new语句为其分配包含10个整型元素的地址空间。 解: 源程序: int *pInteger = new int[10]; 6-9 在字符串”Hello,world!”中结束符是什么? 解: 是NULL字符。 6-10 定义一个有五个元素的整型数组,在程序中提示用户输入元素值,最后再在屏幕上显示出来。 解: 源程序: #include int main() { int myArray[5]; int i; for ( i=0; i<5; i++) { cout << "Value for myArray[" << i <> myArray[i]; } for (i = 0; i<5; i++) cout << i << ": " << myArray[i] << "\n"; return 0; } 程序运行输出: Value for myArray[0]: 2 Value for myArray[1]: 5 Value for myArray[2]: 7 Value for myArray[3]: 8 Value for myArray[4]: 3 0: 2 1: 5 2: 7 3: 8 4: 3 6-11 引用和指针有何区别?何时只能使用指针而不能使用引用? 解: 引用是一个别名,不能为NULL值,不能被重新分配;指针是一个存放地址的变量。当需要对变量重新赋以另外的地址或赋值为NULL时只能使用指针。 6-12 声明下列指针:float类型变量的指针pFloat,char类型的指针pString和struct customer型的指针prec。 解: float *pfloat; char *pString; struct customer *prec; 6-13 给定float类型的指针fp,写出显示fp所指向的值的输出流语句。 解: cout << "Value == " << *fp; 6-14 程序中定义一个double类型变量的指针。分别显示指针占了多少字节和指针所指的变量占了多少字节。 解: double *counter; cout << "\nSize of pointer == "sizeof(counter); cout << '\nSize of addressed value == "<<sizeof(*counter); 6-15 const int * p1 和 int * const p2的区别是什么? 解: const int * p1 声明了一个指向整型常量的指针p1,因此不能通过指针p1来改变它所指向的整型值;int * const p2声明了一个指针型常量,用于存放整型变量的地址,这个指针一旦初始化后,就不能被重新赋值了。 6-16 定义一个整型变量a,一个整型指针p,一个引用r,通过p把a的值改为10,通过r把a的值改为5 解: void main() { int a; int *p = &a; int &r = a; *p = 10; r = 5; } 6-17 下列程序有何问题,请仔细体会使用指针时应避免出现这个的问题。 #include int main() { int *p; *pInt = 9; cout << "The value at p: " << *p; return 0; } 解: 指针p没有初始化,也就是没有指向某个确定的内存单元,它指向内存中的一个随机地址,给这个随机地址赋值是非常危险的。 6-18 下列程序有何问题,请改正;仔细体会使用指针时应避免出现的这个问题。 #include int Fn1(); int main() { int a = Fn1(); cout << "the value of a is: " << a; return 0; } int Fn1() { int * p = new int (5); return *p; } 解: 此程序中给*p分配的内存没有被释放掉。 改正: #include int* Fn1(); int main() { int *a = Fn1(); cout << "the value of a is: " << *a; delete a; return 0; } int* Fn1() { int * p = new int (5); return p; } 6-19 声明一个参数为整型,返回值为长整型的函数指针;声明类A的一个成员函数指针,其参数为整型,返回值长整型。 解: long (* p_fn1)(int); long ( A::*p_fn2)(int); 6-20 实现一个名为SimpleCircle的简单圆类,其数据成员int *itsRadius为一个指向其半径值的指针,设计对数据成员的各种操作,给出这个类的完整实现并测试这个类。 解: 源程序: #include class SimpleCircle { public: SimpleCircle(); SimpleCircle(int); SimpleCircle(const SimpleCircle &); ~SimpleCircle() {} void SetRadius(int); int GetRadius()const; private: int *itsRadius; }; SimpleCircle::SimpleCircle() { itsRadius = new int(5); } SimpleCircle::SimpleCircle(int radius) { itsRadius = new int(radius); } SimpleCircle::SimpleCircle(const SimpleCircle & rhs) { int val = rhs.GetRadius(); itsRadius = new int(val); } int SimpleCircle::GetRadius() const { return *itsRadius; } int main() { SimpleCircle CircleOne, CircleTwo(9); cout << "CircleOne: " << CircleOne.GetRadius() << endl; cout << "CircleTwo: " << CircleTwo.GetRadius() << endl; return 0; }程序运行输出: CircleOne: 5 CircleTwo: 9 6-21 编写一个函数,统计一个英文句子中字母的个数,在主程序中实现输入、输出。 解: 源程序: #include #include int count(char *str) { int i,num=0; for (i=0; str[i]; i++) { if ( (str[i]>='a' && str[i]='A' && str[i]<='Z') ) num++; } return num; } void main() { char text[100]; cout << "输入一个英语句子:" << endl; gets(text); cout << "这个句子里有" << count(text) << "个字母。" << endl; } 程序运行输出: 输入一个英语句子: It is very interesting! 这个句子里有19个字母。 6-22 编写函数int index(char *s, char *t),返回字符串t 在字符串s中出现的最左边的位置,如果在s中没有与t匹配的子串,就返回-1。 解: 源程序: #include int index( char *s, char *t) { int i,j,k; for(i = 0; s[i] != '\0'; i++) { for(j = i, k = 0; t[k] != '\0' && s[j] == t[k]; j++, k++) ; if (t[k] =='\0') return i; } return -1; } void main() { int n; char str1[20],str2[20]; cout <> str1; cout <> str2; n = index(str1,str2); if (n > 0) cout << str2 << "在" << str1 << "中左起第" << n+1 << "个位置。"<<endl; else cout << str2 << "不在" << str1 << "中。" << endl; } 程序运行输出: 输入一个英语单词:abcdefgh 输入另一个英语单词:de de在abcdefghijk中左起第4个位置。 6-23 编写函数reverse(char *s)的倒序递归程序,使字符串s倒序。 解: 源程序: #include #include void reverse(char *s, char *t) { char c; if (s < t) { c = *s; *s = *t; *t = c; reverse(++s, --t); } } void reverse( char *s) { reverse(s, s + strlen(s) - 1); } void main() { char str1[20]; cout <> str1; cout << "原字符串为:" << str1 << endl; reverse(str1); cout << "倒序反转后为:" << str1 << endl; } 程序运行输出: 输入一个字符串:abcdefghijk 原字符串为:abcdefghijk 倒序反转后为:kjihgfedcba 6-24 设学生人数N=8,提示用户输入N个人的考试成绩,然后计算出平均成绩,显示出来。 解: 源程序: #include #include #define N 8 float grades[N]; //存放成绩的数组 void main() { int i; float total,average; //提示输入成绩 for(i = 0; i < N; i++ ) { cout << "Enter grade #" <<(i +1) <> grades[i]; } total = 0; for (i = 0; i < N; i++) total += grades[i]; average = total / N; cout << "\nAverage grade: " << average << endl; } 程序运行输出: Enter grade #1: 86 Enter grade #2: 98 Enter grade #3: 67 Enter grade #4: 80 Enter grade #5: 78 Enter grade #6: 95 Enter grade #7: 78 Enter grade #8: 56 Average grade: 79.75 6-25 设计一个字符串类MyString,具有构造函数、析构函数、拷贝构造函数,重载运算符+、=、+=、[],尽可能地完善它,使之能满足各种需要。(运算符重载功能为选做,参见第8章) 解: #include #include class MyString { public: MyString(); MyString(const char *const); MyString(const MyString &); ~MyString(); char & operator[](unsigned short offset); char operator[](unsigned short offset) const; MyString operator+(const MyString&); void operator+=(const MyString&); MyString & operator= (const MyString &); unsigned short GetLen()const { return itsLen; } const char * GetMyString() const { return itsMyString; } private: MyString (unsigned short); // private constructor char * itsMyString; unsigned short itsLen; }; MyString::MyString() { itsMyString = new char[1]; itsMyString[0] = '\0'; itsLen=0; } MyString::MyString(unsigned short len) { itsMyString = new char[len+1]; for (unsigned short i = 0; i<=len; i++) itsMyString[i] = '\0'; itsLen=len; } MyString::MyString(const char * const cMyString) { itsLen = strlen(cMyString); itsMyString = new char[itsLen+1]; for (unsigned short i = 0; i<itsLen; i++) itsMyString[i] = cMyString[i]; itsMyString[itsLen]='\0'; } MyString::MyString (const MyString & rhs) { itsLen=rhs.GetLen(); itsMyString = new char[itsLen+1]; for (unsigned short i = 0; i<itsLen;i++) itsMyString[i] = rhs[i]; itsMyString[itsLen] = '\0'; } MyString::~MyString () { delete [] itsMyString; itsLen = 0; } MyString& MyString::operator=(const MyString & rhs) { if (this == &rhs;) return *this; delete [] itsMyString; itsLen=rhs.GetLen(); itsMyString = new char[itsLen+1]; for (unsigned short i = 0; i itsLen) return itsMyString[itsLen-1]; else return itsMyString[offset]; } char MyString::operator[](unsigned short offset) const { if (offset > itsLen) return itsMyString[itsLen-1]; else return itsMyString[offset]; } MyString MyString::operator+(const MyString& rhs) { unsigned short totalLen = itsLen + rhs.GetLen(); MyString temp(totalLen); for (unsigned short i = 0; i<itsLen; i++) temp[i] = itsMyString[i]; for (unsigned short j = 0; j<rhs.GetLen(); j++, i++) temp[i] = rhs[j]; temp[totalLen]='\0'; return temp; } void MyString::operator+=(const MyString& rhs) { unsigned short rhsLen = rhs.GetLen(); unsigned short totalLen = itsLen + rhsLen; MyString temp(totalLen); for (unsigned short i = 0; i<itsLen; i++) temp[i] = itsMyString[i]; for (unsigned short j = 0; j<rhs.GetLen(); j++, i++) temp[i] = rhs[i-itsLen]; temp[totalLen]='\0'; *this = temp; } int main() { MyString s1("initial test"); cout << "S1:\t" << s1.GetMyString() << endl; char * temp = "Hello World"; s1 = temp; cout << "S1:\t" << s1.GetMyString() << endl; char tempTwo[20]; strcpy(tempTwo,"; nice to be here!"); s1 += tempTwo; cout << "tempTwo:\t" << tempTwo << endl; cout << "S1:\t" << s1.GetMyString() << endl; cout << "S1[4]:\t" << s1[4] << endl; s1[4]='x'; cout << "S1:\t" << s1.GetMyString() << endl; cout << "S1[999]:\t" << s1[999] << endl; MyString s2(" Another myString"); MyString s3; s3 = s1+s2; cout << "S3:\t" << s3.GetMyString() << endl; MyString s4; s4 = "Why does this work?"; cout << "S4:\t" << s4.GetMyString() << endl; return 0; } 程序运行输出: S1: initial test S1: Hello World tempTwo: ; nice to be here! S1: Hello World; nice to be here! S1[4]: o S1: Hellx World; nice to be here! S1[999]: ! S3: Hellx World; nice to be here! Another myString S4: Why does this work? 6-26 编写一个3×3矩阵转置的函数,在main()函数中输入数据。 解: #include void move (int matrix[3][3]) { int i, j, k; for(i=0; i<3; i++) for (j=0; j<i; j++) { k = matrix[i][j]; matrix[i][j] = matrix[j][i]; matrix[j][i] = k; } } void main() { int i, j; int data[3][3]; cout << "输入矩阵的元素" << endl; for(i=0; i<3; i++) for (j=0; j<3; j++) { cout << "第" << i+1 << "行第" << j+1 <> data[i][j]; } cout << "输入的矩阵的为:" << endl; for(i=0; i<3; i++) { for (j=0; j<3; j++) cout << data[i][j] << " "; cout << endl; } move(data); cout << "转置后的矩阵的为:" << endl; for(i=0; i<3; i++) { for (j=0; j<3; j++) cout << data[i][j] << " "; cout << endl; } } 程序运行输出: 输入矩阵的元素 第1行第1个元素为:1 第1行第2个元素为:2 第1行第3个元素为:3 第2行第1个元素为:4 第2行第2个元素为:5 第2行第3个元素为:6 第3行第1个元素为:7 第3行第2个元素为:8 第3行第3个元素为:9 输入的矩阵的为: 1 2 3 4 5 6 7 8 9 转置后的矩阵的为: 1 4 7 2 5 8 3 6 9 6-27 编写一个矩阵转置的函数,矩阵的维数在程序中由用户输入。 解: #include void move (int *matrix ,int n) { int i, j, k; for(i=0; i<n; i++) for (j=0; j<i; j++) { k = *(matrix + i*n + j); *(matrix + i*n + j) = *(matrix + j*n + i); *(matrix + j*n + i) = k; } } void main() { int n, i, j; int *p; cout <> n; p = new int[n*n]; cout << "输入矩阵的元素" << endl; for(i=0; i<n; i++) for (j=0; j<n; j++) { cout << "第" << i+1 << "行第" << j+1 <> p[i*n + j]; } cout << "输入的矩阵的为:" << endl; for(i=0; i<n; i++) { for (j=0; j<n; j++) cout << p[i*n + j] << " "; cout << endl; } move(p, n); cout << "转置后的矩阵的为:" << endl; for(i=0; i<n; i++) { for (j=0; j<n; j++) cout << p[i*n + j] << " "; cout << endl; } } 程序运行输出: 请输入矩阵的维数:3 输入矩阵的元素 第1行第1个元素为:1 第1行第2个元素为:2 第1行第3个元素为:3 第2行第1个元素为:4 第2行第2个元素为:5 第2行第3个元素为:6 第3行第1个元素为:7 第3行第2个元素为:8 第3行第3个元素为:9 输入的矩阵的为: 1 2 3 4 5 6 7 8 9 转置后的矩阵的为: 1 4 7 2 5 8 3 6 9 6-28 定义一个Employee类,其中包括表示姓名、街道地址、城市和邮编等属性,包括chage_name()和display()等函数;display()使用cout语句显示姓名、街道地址、城市和邮编等属性,函数change_name()改变对象的姓名属性,实现并测试这个类。 解: 源程序: #include #include class Employee { private: char name[30]; char street[30]; char city[18]; char zip[6]; public: Employee(char *n, char *str, char *ct, char *z); void change_name(char *n); void display(); }; Employee::Employee (char *n,char *str,char *ct, char *z) { strcpy(name, n); strcpy(street, str); strcpy(city, ct); strcpy(zip, z); } void Employee::change_name (char *n) { strcpy(name, n); } void Employee::display () { cout << name << " " << street << " "; cout << city << " "<< zip; } void main(void) { Employee e1("张三","平安大街3号", "北京", "100000"); e1.display(); cout << endl; e1.change_name("李四"); e1.display(); cout << endl; } 程序运行输出: 张三 平安大街3号 北京 100000 李四 平安大街3号 北京 100000 第 七 章 继承与派生 7-1 比较类的三种继承方式public公有继承、protected保护继承、private私有继承之间的差别。 解: 不同的继承方式,导致不同访问属性的基类成员在派生类中的访问属性也有所不同: 公有继承,使得基类public(公有)和protected(保护)成员的访问属性在派生类中不变,而基类private(私有)成员不可访问。 私有继承,使得基类public(公有)和protected(保护)成员都以private(私有)成员身份出现在派生类中,而基类private(私有)成员不可访问。 保护继承中,基类public(公有)和protected(保护)成员都以protected(保护)成员身份出现在派生类中,而基类private(私有)成员不可访问。 7-2 派生类构造函数执行的次序是怎样的? 解: 派生类构造函数执行的一般次序为:调用基类构造函数;调用成员对象的构造函数;派生类的构造函数体中的内容。 7-3 如果在派生类B已经重载了基类A的一个成员函数fn1(),没有重载成员函数fn2(),如何调用基类的成员函数fn1()、fn2()? 解: 调用方法为: A::fn1(); fn2(); 7-4 什么叫做虚基类?有何作用? 解: 当某类的部分或全部直接基类是从另一个基类派生而来,这些直接基类中,从上一级基类继承来的成员就拥有相同的名称,派生类的对象的这些同名成员在内存中同时拥有多个拷贝,我们可以使用作用域分辨符来唯一标识并分别访问它们。我们也可以将直接基类的共同基类设置为虚基类,这时从不同的路径继承过来的该类成员在内存中只拥有一个拷贝,这样就解决了同名成员的唯一标识问题。 虚基类的声明是在派生类的定义过程,其语法格式为: class 派生类名:virtual 继承方式 基类名 上述语句声明基类为派生类的虚基类,在多继承情况下,虚基类关键字的作用范围和继承方式关键字相同,只对紧跟其后的基类起作用。声明了虚基类之后,虚基类的成员在进一步派生过程中,和派生类一起维护一个内存数据拷贝。 7-5 定义一个Shape基类,在此基础上派生出Rectangle和Circle,二者都有GetArea()函数计算对象的面积。使用Rectangle类创建一个派生类Square。 解: 源程序: #include class Shape { public: Shape(){} ~Shape(){} virtual float GetArea() { return -1; } }; class Circle : public Shape { public: Circle(float radius):itsRadius(radius){} ~Circle(){} float GetArea() { return 3.14 * itsRadius * itsRadius; } private: float itsRadius; }; class Rectangle : public Shape { public: Rectangle(float len, float width): itsLength(len), itsWidth(width){}; ~Rectangle(){}; virtual float GetArea() { return itsLength * itsWidth; } virtual float GetLength() { return itsLength; } virtual float GetWidth() { return itsWidth; } private: float itsWidth; float itsLength; }; class Square : public Rectangle { public: Square(float len); ~Square(){} }; Square::Square(float len): Rectangle(len,len) { } void main() { Shape * sp; sp = new Circle(5); cout << "The area of the Circle is " <GetArea () << endl; delete sp; sp = new Rectangle(4,6); cout << "The area of the Recta
CruiseYoung提供的带有详细书签的电子书籍目录 http://blog.csdn.net/fksec/article/details/7888251 该资料是《C语言入门经典(第4版)》的源代码及课后练习答案 对应的书籍资料见: C语言入门经典(第4版) 基本信息 原书名: Beginning C: From Novice to Professional, Fourth Edition 原出版社: Apress 作者: (美)Ivor Horton 译者: 杨浩 出版社:清华大学出版社 ISBN:9787302170839 上架时间:2008-4-15 出版日期:2008 年4月 开本:16开 页码:571 版次:4-1 编辑推荐    本书是编程语言先驱者Ivor Horton的经典之作,是C语言方面最畅销的图书品种之一,在世界范围内广受欢迎,口碑极佳。    本书的目标是使你在C语言程序设计方面由一位初学者成为一位称职的程序员。 内容简介   本书是编程语言先驱者Ivor Horton的经典之作,是C语言方面最畅销的图书品种之一。本书集综合性、实用性为一体,是学习C语言的优秀入门教材,在世界范围内广受欢迎,口碑极佳。书中除了讲解C程序设计语言,还广泛介绍了作为一名C程序设计人员应该掌握的必要知识,并提供了大量的实用性很强的编程实例。本书的目标是使你在C语言程序设计方面由一位初学者成为一位称职的程序员。读者基本不需要具备任何编程知识,即可通过本书从头开始编写自己的C程序。 作译者 作者   Ivor Horton是世界著名的计算机图书作家,主要从事与编程相关的咨询及撰写工作,曾帮助无数程序员步入编程的殿堂。他曾在IBM工作多年,能使用多种语言进行编程(在多种机器上使用汇编语言和高级语言),设计和实现了实时闭环工业控制系统。Horton拥有丰富的教学经验(教学内容包括C、C++、Fortran、PL/1、APL等),同时还是机械、加工和电子CAD系统、机械CAM系统和DNC/CNC系统方面的专家。IvorHorton还著有关于C、C++和Java的多部入门级好书,如《C语言入门经典(第4版)》和《C++入门经典(第3版)》。 译者   杨浩,知名译者,大学讲师,从事机械和计算机方面的教学和研究多年,发表论文数篇,参编和翻译的图书多达20余部,还曾多次获得市部级奖项。近几年一直在跟踪.NET技术的发展,积极从事.NET技术文档和图书的翻译工作。 目录 封面 -12 封底 572 前言 -9 目录 -6 第1章 C语言编程 1 1.1 创建C程序 1 1.1.1 编辑 1 1.1.2 编译 2 1.1.3 链接 2 1.1.4 执行 3 1.2 创建第一个程序 4 1.3 编辑第一个程序 4 1.4 处理错误 5 1.5 剖析一个简单的程序 6 1.5.1 注释 6 1.5.2 预处理指令 7 1.5.3 定义main()函数 7 1.5.4 关键字 8 1.5.5 函数体 8 1.5.6 输出信息 9 1.5.7 参数 10 1.5.8 控制符 10 1.6 用C语言开发程序 12 1.6.1 了解问题 12 1.6.2 详细设计 12 1.6.3 实施 13 1.6.4 测试 13 1.7 函数及模块化编程 13 1.8 常见错误 17 1.9 要点 17 1.10 小结 18 1.11 习题 18 第2章 编程初步 19 2.1 计算机的内存 19 2.2 什么是变量 21 2.3 存储数值的变量 21 2.3.1 整数变量 21 2.3.2 变量的命名 25 2.3.3 变量的使用 26 2.3.4 变量的初始化 28 2.3.5 算术语句 28 2.4 变量与内存 34 2.5 整数变量类型 35 2.5.1 无符号的整数类型 35 2.5.2 使用整数类型 36 2.5.3 指定整数常量 37 2.6 浮点数 38 2.7 浮点数变量 38 2.8 使用浮点数完成除法运算 39 2.8.1 控制小数位数 40 2.8.2 控制输出的字段宽度 41 2.9 较复杂的表达式 41 2.10 定义常量 44 2.10.1 极限值 46 2.10.2 sizeof运算符 49 2.11 选择正确的类型 50 2.12 强制类型转换 53 2.12.1 自动转换类型 53 2.12.2 隐式类型转换的规则 54 2.12.3 赋值语句中的隐式类型转换 54 2.13 再谈数值数据类型 55 2.13.1 字符类型 56 2.13.2 字符的输入输出 57 2.13.3 宽字符类型 60 2.13.4 枚举 60 2.13.5 存储布尔值的变量 63 2.13.6 复数类型 63 2.14 赋值操作的op=形式 66 2.15 数学函数 68 2.16 设计一个程序 69 2.16.1 问题 69 2.16.2 分析 69 2.16.3 解决方案 71 2.17 小结 75 2.18 练习 76 第3章 条件判断 79 3.1 判断过程 79 3.1.1 算术比较 80 3.1.2 涉及关系运算符的表达式 80 3.1.3 基本的if语句 81 3.1.4 扩展if语句:if-else 84 3.1.5 在if语句中使用代码块 86 3.1.6 嵌套的if语句 87 3.1.7 更多的关系运算符 90 3.1.8 逻辑运算符 93 3.1.9 条件运算符 97 3.1.10 运算符的优先级 99 3.2 多项选择问题 103 3.2.1 给多项选择使用else-if语句 104 3.2.2 switch语句 104 3.2.3 goto语句 113 3.3 按位运算符 114 3.3.1 按位运算符的op=用法 116 3.3.2 使用按位运算符 117 3.4 设计程序 120 3.4.1 问题 120 3.4.2 分析 120 3.4.3 解决方案 121 3.5 小结 124 3.6 练习 124 第4章 循环 127 4.1 循环 127 4.2 递增和递减运算符 128 4.3 for循环 129 4.4 for循环的一般语法 132 4.5 再谈递增和递减运算符 133 4.5.1 递增运算符 133 4.5.2 递增运算符的前置和后置形式 134 4.5.3 递减运算符 134 4.6 再论for循环 135 4.6.1 修改for循环变量 137 4.6.2 没有参数的for循环 138 4.6.3 循环内的break语句 138 4.6.4 使用for循环限制输入 141 4.6.5 生成伪随机整数 143 4.6.6 再谈循环控制选项 145 4.6.7 浮点类型的循环控制变量 146 4.7 while循环 147 4.8 嵌套循环 150 4.9 嵌套循环和goto语句 153 4.10 do-while循环 154 4.11 continue语句 157 4.12 设计程序 157 4.12.1 问题 157 4.12.2 分析 157 4.12.3 解决方案 158 4.13 小结 170 4.14 习题 170 第5章 数组 173 5.1 数组简介 173 5.1.1 不用数组的程序 173 5.1.2 什么是数组 175 5.1.3 使用数组 176 5.2 内存 179 5.3 数组和地址 182 5.4 数组的初始化 184 5.5 确定数组的大小 184 5.6 多维数组 185 5.7 多维数组的初始化 187 5.8 设计一个程序 191 5.8.1 问题 192 5.8.2 分析 192 5.8.3 解决方案 193 5.9 小结 200 5.10 习题 200 第6章 字符串和文本的应用 201 6.1 什么是字符串 201 6.2 处理字符串和文本的方法 203 6.3 字符串操作 206 6.3.1 连接字符串 206 6.3.2 字符串数组 208 6.4 字符串库函数 210 6.4.1 使用库函数复制字符串 210 6.4.2 使用库函数确定字符串的长度 211 6.4.3 使用库函数连接字符串 212 6.4.4 比较字符串 213 6.4.5 搜索字符串 216 6.5 分析和转换字符串 219 6.5.1 转换字符 222 6.5.2 将字符串转换成数值 225 6.7 使用宽字符串 225 6.8 设计一个程序 228 6.8.1 问题 229 6.8.2 分析 229 6.8.3 解决方案 229 6.9 小结 237 6.10 习题 237 第7章 指针 239 7.1 指针初探 239 7.1.1 声明指针 240 7.1.2 通过指针访问值 241 7.1.3 使用指针 244 7.1.4 指向常量的指针 248 7.1.5 常量指针 248 7.1.6 指针的命名 249 7.2 数组和指针 249 7.3 多维数组 252 7.3.1 多维数组和指针 255 7.3.2 访问数组元素 257 7.4 内存的使用 260 7.4.1 动态内存分配:malloc()函数 260 7.4.2 分配内存时使用sizeof运算符 261 7.4.3 用calloc()函数分配内存 265 7.4.4 释放动态分配的内存 265 7.4.5 重新分配内存 267 7.5 使用指针处理字符串 268 7.5.1 更多地控制字符串输入 268 7.5.2 使用指针数组 269 7.6 设计程序 280 7.6.1 问题 280 7.6.2 分析 281 7.6.3 解决方案 281 7.7 小结 291 7.8 习题 291 第8章 程序的结构 293 8.1 程序的结构 293 8.1.1 变量的作用域和生存期 294 8.1.2 变量的作用域和函数 297 8.2 函数 297 8.2.1 定义函数 298 8.2.2 return语句 301 8.3 按值传递机制 304 8.4 函数声明 305 8.5 指针用作参数和返回值 307 8.5.1 常量参数 310 8.5.2 从函数中返回指针值 318 8.5.3 在函数中递增指针 322 8.6 小结 322 8.7 习题 323 第9章 函数再探 325 9.1 函数指针 325 9.1.1 声明函数指针 325 9.1.2 通过函数指针调用函数 326 9.1.3 函数指针数组 329 9.1.4 作为变元的函数指针 331 9.2 函数中的变量 334 9.2.1 静态变量:函数内部的追踪 334 9.2.2 在函数之间共享变量 336 9.3 调用自己的函数:递归 338 9.4 变元个数可变的函数 341 9.4.1 复制va_list 344 9.4.2 长度可变的变元列表的基本规则 344 9.5 main()函数 345 9.6 结束程序 346 9.7 函数库:头文件 347 9.8 提高性能 348 9.8.1 内联声明函数 348 9.8.2 使用restrict关键字 348 9.9 设计程序 349 9.9.1 问题 349 9.9.2 分析 349 9.9.3 解决方案 351 9.10 小结 367 9.11 习题 368 第10章 基本输入和输出操作 369 10.1 输入和输出流 369 10.2 标准流 370 10.3 键盘输入 371 10.3.1 格式化键盘输入 371 10.3.2 输入格式控制字符串 372 10.3.3 输入格式字符串中的字符 377 10.3.4 输入浮点数的各种变化 378 10.3.5 读取十六进制和八进制值 379 10.3.6 用scanf()读取字符 381 10.3.7 scanf()的陷阱 383 10.3.8 从键盘上输入字符串 383 10.3.9 键盘的非格式化输入 384 10.4 屏幕输出 389 10.4.1 使用printf()格式输出到屏幕 389 10.4.2 转义序列 391 10.4.3 整数输出 392 10.4.4 输出浮点数 394 10.4.5 字符输出 395 10.5 其他输出函数 398 10.5.1 屏幕的非格式化输出 398 10.5.2 数组的格式化输出 399 10.5.3 数组的格式化输入 400 10.6 打印机输出 400 10.7 小结 401 10.8 习题 401 第11章 结构化数据 403 11.1 数据结构:使用struct 403 11.1.1 定义结构类型和结构变量 405 11.1.2 访问结构成员 405 11.1.3 未命名的结构 408 11.1.4 结构数组 408 11.1.5 表达式中的结构 411 11.1.6 结构指针 411 11.1.7 为结构动态分配内存 412 11.2 再探结构成员 414 11.2.1 将一个结构作为另一个结构的成员 414 11.2.2 声明结构中的结构 415 11.2.3 将结构指针用作结构成员 416 11.2.4 双向链表 420 11.2.5 结构中的位字段 423 11.3 结构与函数 424 11.3.1 结构作为函数的变元 424 11.3.2 结构指针作为函数变元 425 11.3.3 作为函数返回值的结构 426 11.3.4 修改程序 430 11.3.5 二叉树 433 11.4 共享内存 442 11.4.1 联合 442 11.4.2 联合指针 444 11.4.3 联合的初始化 444 11.4.4 联合中的结构成员 444 11.5 定义自己的数据类型 446 11.5.1 结构与类型定义(typedef)功能 446 11.5.2 使用typedef简化代码 447 11.6 设计程序 448 11.6.1 问题 448 11.6.2 分析 448 11.6.3 解决方案 448 11.7 小结 459 11.8 习题 459 第12章 处理文件 461 12.1 文件的概念 461 12.1.1 文件中的位置 462 12.1.2 文件流 462 12.2 文件访问 462 12.2.1 打开文件 463 12.2.2 文件重命名 465 12.2.3 关闭文件 465 12.2.4 删除文件 466 12.3 写入文本文件 466 12.4 读取文本文件 467 12.5 将字符串写入文本文件 470 12.6 从文本文件中读入字符串 471 12.7 格式化文件的输入输出 474 12.7.1 格式化文件输出 474 12.7.2 格式化文件输入 475 12.8 错误处理 477 12.9 再探文本文件操作模式 478 12.10 二进制文件的输入输出 479 12.10.1 指定二进制模式 479 12.10.2 写入二进制文件 480 12.10.3 读取二进制文件 480 12.11 在文件中移动 488 12.11.1 文件定位操作 489 12.11.2 找出我们在文件中的位置 489 12.11.3 在文件中设定位置 490 12.12 使用临时文件 496 12.12.1 创建临时文件 496 12.12.2 创建唯一的文件名 496 12.13 更新二进制文件 497 12.13.1 修改文件的内容 502 12.13.2 从键盘读取记录 503 12.13.3 将记录写入文件 504 12.13.4 从文件中读取记录 505 12.13.5 写入文件 506 12.13.6 列出文件内容 507 12.13.7 更新已有的文件内容 508 12.14 文件打开模式小结 515 12.15 设计程序 516 12.15.1 问题 516 12.15.2 分析 516 12.15.3 解决方案 516 12.16 小结 522 12.17 习题 522 第13章 支持功能 523 13.1 预处理 523 13.1.1 在程序中包含头文件 523 13.1.2 外部变量及函数 524 13.1.3 替换程序源代码 525 13.1.4 宏替换 526 13.1.5 看起来像函数的宏 526 13.1.6 多行上的预处理指令 528 13.1.7 字符串作为宏参数 528 13.1.8 结合两个宏展开式的结果 529 13.2 预处理器逻辑指令 530 13.2.1 条件编译 530 13.2.2 测试指定值的指令 531 13.2.3 多项选择 531 13.2.4 标准预处理宏 532 13.3 调试方法 533 13.3.1 集成的调试器 533 13.3.2 调试阶段的预处理器 533 13.3.3 使用assert()宏 537 13.4 其他库函数 539 13.4.1 日期和时间函数库 539 13.4.2 获取日期 543 13.5 小结 549 13.6 习题 549 附录A 计算机中的数学知识 551 附录B ASCII字符代码定义 559 附录C C语言中的保留字 565 附录D 输入输出格式指定符 567 前言   欢迎使用《C语言入门经典(第4版)》。研读本书,你就可以成为一位称职的C语言程序员。从许多方面来说,C语言都是学习程序设计的理想起步语言。C语言很简洁,因此无须学习大量的语法,就能够开始编写真正的应用程序。除了简明易学外,它还是一种功能非常强大的语言,至今仍被专业人士广泛使用。C语言的强大之处主要体现在,它能够进行各种层次的程序设计,从硬件设备驱动程序和操作系统组件到大规模的应用程序,都能胜任。事实上,任何计算机都支持C语言编译器,因此,当我们学会了C语言,就可以在任何环境下进行程序设计。最后一点,掌握了C语言,就为理解面向对象的C++语言奠定了良好的基础。.   积极热情的程序员都必将面对三大障碍,即掌握适用于所有程序设计语言的术语,理解如何使用一种语言的元素(而不仅仅只知道它们的概念)以及领会如何在实际环境中应用这种语言,本书的目的就是将这些障碍降到最低。   术语是专业人士与优秀的业余人士们进行交流时必不可少的,因此掌握它们是必需的。本书会让你理解这些术语,并自如地在各种环境下使用它们。这样才能更有效地使用大多数软件产品附带的文档,且能轻松地阅读和学习大多数程序设计语言的相关文献。   显然,理解语言元素的语法和作用是学习一门语言的关键,不过认识语言的特性如何发挥作用和如何应用它们,也同等重要。在说明每种语言特性与特定问题的关系时,本书采用实际应用的程序示例,而不只是代码片断。这些示例提供了实践的基础,你可以任意改动它们,研究改动后的效果。   要理解在特定背景中的程序设计方法,需要理解应用独立语言元素的机理。为了帮助理解它们,本书每章最后都给出一个较复杂的程序,该程序应用了本章前面已经学习的知识。这些程序可帮助你获得开发程序的能力和信心,了解如何综合运用各种语言元素。最重要的是,它们能让你了解设计真实程序时会遇到的问题以及如何管理实际的代码。   学习任何程序设计语言,都要认识几件事情。首先,要学的东西很多,但是掌握了它们之后,你会有极大的成就感。其次,学习的过程很有趣,你将体会到这一点。第三,你只有通过动手实践才能学会程序设计。最后,学习程序设计语言比你想象的容易得多,所以你肯定能掌握它。   如何使用本书   作者认为动手实践是最好的方法,你应当立刻开始编写自己的第一个程序。每一章都有几个把理论应用于实践的程序,这些示例是学习本书的关键。建议读者输入并运行文中的示例,因为输入程序对记住语言元素有极大的帮助。此外,你还应该做每章后面的练习。当你第一次使一个程序运行起来,尤其是在试图解决自己的问题时,快速的进展会使你有很大的成就感。..   刚开始,学习的进展不会太快,不过随着逐渐深入,我们会加快学习的速度。每一章都会涉及很多基础知识,因此在学习新的内容之前,需要花些时间,确保理解了前面学过的所有知识。实践各部分的代码,并尝试实现自己的想法,这是学习程序设计语言的一个重要部分。尝试修改书中的程序,看看还能让它们做什么,这是很有趣的。不要害怕尝试,如果不明白某一点如何使用,输入几种变体,看看会出现哪些情况。好的学习方法是先通读整章,全面了解其中介绍的内容,然后再实践其中的所有程序示例。   你可能会觉得某些章末尾的程序非常难。如果第一次读这样的程序没有完全理解,不必担心。第一次难免会觉得难以理解,因为它们通常都是把你所学的知识应用到了相当复杂的问题中。如果你真的不能理解,可以略过那些章末尾的程序,继续学习下一章,然后再回头研究这些程序。甚至可以在学完全书之后再来研究它们。之所以演示这些程序是因为即使读完了本书,它们对你来说仍是非常有用的资源。   本书读者对象   本书的目的是教你如何尽可能简单快速地编写有用的程序,如果你属于下列情况之一,那么本书就非常适合你:   ●刚接触程序设计,但想直接深入了解C语言,从头开始学习程序设计及编写C语言程序。   ●以前有一点程序设计经历,对其基本概念有一定了解,也许曾经使用过BASIC或PASCAL。现在想学习C语言,进一步提高自己的程序设计技能。   本书并未假设此前你对程序设计的知识有所了解,不过本书会很快地从基本概念转入到实际应用。学完了本书,你就为自己的C语言程序设计奠定了全面的基础。   使用本书的条件   要使用本书,需要一台安装了C语言编译器和库的计算机,这样才能执行书中的示例,还需要一个程序文本编辑器,用于创建源代码文件。你使用的编译器要很好地支持C语言国际标准:ISO/IEC 9899。你还需要一个用于创建和修改代码的编辑器,可以采用任何纯文本编辑器创建源程序文件,如Notepad或vi。不过,采用专为编辑C语言代码设计的编辑器更有帮助。   要最大限度地发挥本书的功效,你需要有学习的意愿、成功的渴望,当学习不顺利,觉得前途渺茫时,还要有坚持下去的决心。几乎每个人在初次学习程序设计时都会在某处觉得迷茫。当你发现自己艰难地掌握了C语言的某个方面时,要坚持下去,迷雾一定会消散,你会觉得为什么当初我不明白这一点呢?也许你明白要做到这些将会很难,不过相信你一定会惊讶自己能在较短的时间内取得很大进步。本书会帮助你开始自己的实践之旅,使你成为成功的程序设计员。   本书采用的约定   本书的文本和布局采用了许多不同的样式,以便区分各种不同的信息。大多数样式表达的含义都很明显,其中程序代码以类似下面的样子出现: .  int main(void)   {   printf("\nBeginning C");   return 0;   }   如果代码片段是从前面的实例修改而来的,修改过的代码行就用粗体显示,如下所示:   int main(void)   {   printf("\nBeginning C by Ivor Horton");   return 0;   }   程序代码中还使用了各种“括号”。它们之间的差别非常重要,不能互换。本书中称( )为圆括号,{ }为大括号,[ ]为方括号。   本书源代码下载   从Apress的站点可以下载本书中的所有代码和练习的解决方案:http://www.apress.com。也可以访问www.tupwk.com.cn/downpage下载本书中的所有代码和解决方案。...   
1 愉快的开始-HELLO WORLD 14 1.1 INCLUDE头文件包含 14 1.2 MAIN函数 14 1.3 注释 14 1.4 {}括号,程序题和代码块 14 1.5 声明 14 1.6 C语言自定义名字的要求 15 1.7 PRINTF函数 15 1.8 RETURN语句 15 1.9 SYSTEM系统调用 15 1.9.1 System返回值在windows和unix下的不同, 15 1.9.2 POSIX 15 1.10 C语言编译过程,GCC参数简介 16 1.10.1 C语言编译过程 16 1.10.2 -E预编译 16 1.10.3 -S汇编 16 1.10.4 -c编译 16 1.10.5 链接 16 1.11 操作系统结构 17 1.11.1 用户模式 17 1.11.2 内核模式 17 1.12 64位,32位系统区别 18 1.12.1 CPU内部结构与寄存器 18 1.12.2 RISC与CISC CPU构架 18 1.12.3 SPARC,x86与ARM 18 1.13 汇编语言 18 1.13.1 I386汇编简介 18 1.13.2 VS反汇编 19 1.14 IDE工具 19 1.14.1 QT常用快捷键 19 1.14.2 VS常用快捷键 19 1.14.3 VS断点,调试 19 2 C语言中的数据类型 19 2.1 常量 19 2.1.1 #define 19 2.1.2 const 19 2.2 字符串常量 20 2.3 二进制数、位、字节与字 20 2.4 八进制 20 2.5 十六进制 20 2.6 原码 21 2.7 反码 21 2.8 补码 21 2.9 SIZEOF关键字 22 2.10 INT类型 22 2.10.1 int常量,变量 22 2.10.2 printf输出int值 23 2.10.3 printf输出八进制和十六进制 23 2.10.4 short,long,long long,unsigned int 23 2.10.5 整数溢出 23 2.10.6 大端对齐与小端对齐 23 2.11 CHAR类型 24 2.11.1 char常量,变量 24 2.11.2 printf输出char 24 2.11.3 不可打印char转义符 24 2.11.4 char和unsigned char 25 2.12 浮点FLOAT,DOUBLE,LONG DOUBLE类型 25 2.12.1 浮点常量,变量 25 2.12.2 printf输出浮点数 25 2.13 类型限定 25 2.13.1 const 25 2.13.2 volatile 26 2.13.3 register 26 3 字符串格式化输出和输入 26 3.1 字符串在计算机内部的存储方式 26 3.2 PRINTF函数,PUTCHAR函数 27 3.3 SCANF函数与GETCHAR函数 28 4 运算符表达式和语句 29 4.1 基本运算符 29 4.1.1 = 29 4.1.2 + 29 4.1.3 – 29 4.1.4 * 29 4.1.5 / 29 4.1.6 % 29 4.1.7 += 29 4.1.8 -= 29 4.1.9 *= 29 4.1.10 /= 30 4.1.11 %= 30 4.1.12 ++ 30 4.1.13 -- 30 4.1.14 逗号运算符 30 4.1.15 运算符优先级 30 4.2 复合语句 31 4.3 空语句 31 4.4 类型转化 31 5 条件分支语句 31 5.1 关系运算符 31 5.1.1 < 31 5.1.2 <= 31 5.1.3 > 32 5.1.4 >= 32 5.1.5 == 32 5.1.6 != 32 5.2 关系运算符优先级 32 5.3 逻辑运算符 32 5.3.1 && 32 5.3.2 || 32 5.3.3 ! 33 5.4 IF 33 5.5 IF ELSE 34 5.6 IF ELSE IF 34 5.7 SWITCH与BREAK,DEFAULT 35 5.8 条件运算符? 36 5.9 GOTO语句与标号 36 6 循环语句 36 6.1 WHILE 36 6.2 CONTINUE 37 6.3 BREAK 37 6.4 DO WHILE 37 6.5 FOR 37 6.6 循环嵌套 37 7 数组 38 7.1 一维数组定义与使用 38 7.2 数组在内存的存储方式 38 7.3 一维数组初始化 38 7.4 二维数组定义与使用 39 7.5 二维数组初始化 39 8 字符串与字符数组 39 8.1 字符数组定义 39 8.2 字符数组初始化 39 8.3 字符数组使用 40 8.4 随机数产生函数RAND与SRAND 40 8.5 用SCANF输入字符串 40 8.6 字符串的结束标志 41 8.7 字符串处理函数 41 8.7.1 gets 41 8.7.2 fgets函数 41 8.7.3 puts函数 42 8.7.4 fputs函数 42 8.7.5 strlen,字符串长度 42 8.7.6 strcat,字符串追加 42 8.7.7 strncat,字符串有限追加 43 8.7.8 strcmp,字符串比较 43 8.7.9 strncmp,字符串有限比较 43 8.7.10 strcpy字符串拷贝 43 8.7.11 strncpy字符串有限拷贝 43 8.7.12 sprintf,格式化字符串 43 8.7.13 Sscanf函数 44 8.7.14 strchr查找字符 44 8.7.15 strstr查找子串 44 8.7.16 strtok分割字符串 44 8.7.17 atoi转化为int 45 8.7.18 atof转化为float 45 8.7.19 atol转化为long 45 9 函数 45 9.1 函数的原型和调用 45 9.2 函数的形参与实参 45 9.3 函数的返回类型与返回值 46 9.4 MAIN函数与EXIT函数与函数的RETURN语句 46 9.5 多个源代码文件程序的编译 47 9.5.1 头文件的使用 47 9.5.2 #include与#define的意义 47 9.5.3 #ifndef与#endif 47 9.6 函数的递归 48 9.6.1 递归的过程分析 48 9.6.2 递归的优点 52 9.6.3 递归的缺点 52 1 指针 52 1.1 指针 52 1.1.1 指针的概念 52 1.1.2 指针变量的定义 52 1.1.3 &取地址运算符 52 1.1.4 无类型指针 52 1.1.5 NULL 53 1.1.6 空指针与野指针 53 1.1.7 指针的兼容性 53 1.1.8 指向常量的指针与指针常量 54 1.1.9 指针与数组的关系 54 1.1.10 指针运算 54 1.1.11 通过指针使用数组元素 55 1.1.12 指针数组 55 1.1.13 指向指针的指针(二级指针) 55 1.1.14 指向二维数组的指针 57 1.1.15 指针变量做为函数的参数 57 1.1.16 一维数组名作为函数参数 57 1.1.17 二维数组名作为函数参数 58 1.1.18 const关键字保护数组内容 58 1.1.19 指针做为函数的返回值 58 1.1.20 指向函数的指针 59 1.1.21 把指向函数的指针做为函数的参数 60 1.1.22 memset,memcpy,memmove函数 61 1.1.23 指针小结 63 2 字符指针与字符串 64 2.1 指针和字符串 64 2.2 通过指针访问字符串数组 64 2.3 函数的参数为CHAR * 64 2.4 指针数组做为MAIN函数的形参 65 3 内存管理 65 3.1 作用域 65 3.1.1 auto自动变量 65 3.1.2 register寄存器变量 65 3.1.3 代码块作用域的静态变量 66 3.1.4 代码块作用域外的静态变量 66 3.1.5 全局变量 66 3.1.6 外部变量与extern关键字 66 3.1.7 全局函数和静态函数 66 3.2 内存四区 66 3.2.1 代码区 67 3.2.2 静态区 67 3.2.3 栈区 67 3.2.4 栈溢出 68 3.2.5 堆区 68 3.3 堆的分配和释放 70 3.3.1 malloc 70 3.3.2 free 70 3.3.3 calloc: 70 3.3.4 realloc 71 4 结构体,联合体,枚举与TYPEDEF 71 4.1 结构体 71 4.1.1 定义结构体struct和初始化 71 4.1.2 访问结构体成员 71 4.1.3 结构体的内存对齐模式 72 4.1.4 指定结构体元素的位字段 72 4.1.5 结构数组 72 4.1.6 嵌套结构 73 4.1.7 结构体的赋值 73 4.1.8 指向结构体的指针 73 4.1.9 指向结构体数组的指针 73 4.1.10 结构中的数组成员和指针成员 73 4.1.11 在堆中创建的结构体 74 4.1.12 将结构作为函数参数 74 4.1.13 结构,还是指向结构的指针 74 4.2 联合体 75 4.3 枚举类型 75 4.3.1 枚举定义 75 4.3.2 默认值 76 4.4 TYPEDEF 76 4.5 通过TYPEDEF定义函数指针 76 5 文件操作 77 5.1 FOPEN 77 5.2 二进制和文本模式的区别 77 5.3 FCLOSE 78 5.4 GETC和PUTC函数 78 5.5 EOF与FEOF函数文件结尾 78 5.6 FPRINTF,FSCANF,FGETS,FPUTS函数 78 5.7 STAT函数 78 5.8 FREAD和FWRITE函数 79 5.9 FREAD与FEOF 79 5.10 通过FWRITE将结构保存到二进制文件中 79 5.11 FSEEK函数 80 5.12 FTELL函数 80 5.13 FFLUSH函数 80 5.14 REMOVE函数 81 5.15 RENAME函数 81 6 基础数据结构与算法 82 6.1 什么是数据结构 82 6.2 什么是算法 82 6.3 排序 83 6.3.1 冒泡排序 83 6.3.2 选择排序 83 6.4 查找 83 6.4.1 顺序查找 83 6.4.2 二分查找 83 6.5 链表 84 6.5.1 单向链表定义 84 6.5.2 单向链表数据结构定义 85 6.5.3 单向链表的实现 85

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值