1
C语言程序设计
1.6.7 5.7 程序举例

5.7 程序举例

例5-20 给出以下程序运行的结果。

程序如下:

img473

程序运行结果:

  i=3,j=11,*p=3,*q=3

  ch1='c',ch2='c',*t='c',*s='c'

程序第8行和第9行把整数3赋给变量i并把i的地址赋给指针p;第10行把p所指向的地址单元里的数据(=3)取出来,整除2以后加上10,故j的值等于11;第11行令指针q与指针p指向同一个存储单元,即此时*q的值也等于3。

程序第12行和第13行把字符a赋给变量chl,并把chl的地址赋给指针s;第14行改变s所指向的地址单元里的内容,令其等于字符c,这个运算实际上是改变了变量chl的值,它也等于字符c;第15行和第16行令变量ch2的值等于变量chl的值。

例5-21 用选择法对键盘输入的20个实数按升序排列,并按每行5个数据打印排序前后的数据。

程序如下:

img474

输入20个实数:

img475

排序后的数据:

img476

img477

程序定义了浮点型数组f,用于存放20个实数。定义了浮点型指针变量point,并将其指向数组f。在for循环中用指针法输入20个数组元素,由于控制循环的条件为:

  (i=0;i〈20;i++,point++)

其中,指针point在循环过程中做自增运算,依次从指向第一个元素f[0]到指向最后一个元素f[19]。因此,用选择法排序时,在控制循环for的条件:“(point=f,i=0;i〈19;i++)”中,先将数组首地址赋给指针变量point,即又将指针point当前指向的位置(数组f的最后一个元素f[19])恢复到数组f的第一个元素f[0]。

例5-22 输入两个字符串,从第一个字符串中删去所有与第二个字符串相同的字符。

程序如下:

img478

程序运行结果:

输入字符串:

  quickc-turbo c..turbopascal

  ctur

输出结果:

  qik-bo..bopasal

该程序首先读入两个字符串s1和s2,并用指针p1和p2分别指向这两个字符串。程序的第12~21行完成从p1所指的字符串中删除在p2所指字符串中存在的所有字符,具体做法是:首先取出p1中的一个字符,然后把它和p2中的每个字符相比较,如果发现p2中有这个字符,则取pl中的下一字符并重复上述的比较操作;如果已经和p2的末尾字符进行了比较仍然没有发现有相同的字符,则把这个字符往前移动,覆盖掉前面那些应该被删除的字符。这个过程进行到p1中的所有字符都检查完毕为止。

例5-23 编制一个程序显示内存中一片存储区的内容。

假定我们使用的是IBM PC微型机及其兼容机,考虑如何编制一个程序,它能根据输入的起始地址和结束地址,显示出内存中相应这一片存储单元中的信息。

IBM PC机的内存地址是用一个5位的十六进制数或20位的二进制数来表示,其最大数值可达0xfffff或1 048 575,在编制程序时,必须用长整型变量来存储地址值。我们用长整型变量b_addr来表示要显示的起始地址,用长整型变量e_addr来表示结束地址。

内存中的信息用十六进制数显示。由于机器的内存组织是每个字节对应一个地址,在显示时最好每次显示一个字节,且在字节间加上空格隔开。为此,使用一个字符指针point,每次显示该指针所指的一个字符(占一个字节)。初始时令指针point指向起始地址,在显示完当前单元的内容后对point进行加一操作,直到它等于结束地址为止。

程序如下:

img479

img480

程序运行结果:

  please enter the beginning and the end addr in hex

输入:

  20000 2006f

输出:

  20000:00 00 00 00 54 75 72 62 6f 2d 43 20 2d 20 43 6f

  20010:70 79 72 69 67 68 74 20 28 63 29 20 31 39 38 38

  20020:20 42 6f 72 6c 61 6e 64 20 49 6e 74 6c 2e 00 4e

  20030:75 6c 6c 20 70 6f 69 6e 74 65 72 20 61 73 73 69

  20040:67 6e 6d 65 6e 74 0d 0a 44 69 76 69 64 65 20 65

  20050:72 72 6f 72 0d 0a 41 62 6e 6f 72 6d 61 6c 20 70

  20060:72 6f 67 72 61 6d 20 74 65 72 6d 69 6e 61 74 69

程序的第9行输入要显示的内存起始地址和结束地址;第12行以5位十六进制数显示地址值,第14~22行显示内存内容,每行显示16个字节,并在前8个字节和后8个字节之间加上若干个空格使输出数据更加清晰。

例5-24 打鱼还是晒网?

中国有句俗语叫“三天打鱼两天晒网”。某人从2000年1月1日起开始“三天打鱼两天晒网”,问这个人在以后的某一天中是在“打鱼”,还是在“晒网”。

问题分析与算法设计:

根据题意可以将解题过程分为三步:

① 计算从2000年1月1日开始至指定日期一共有多少天。

② 由于“打鱼”和“晒网”的周期为5天,所以将计算出的天数用5去除。

③ 根据余数判断他是在“打鱼”,还是在“晒网”:

若余数为1、2、3,则他是在“打鱼”,否则是在“晒网”。

注意:

这三步中,关键是第一步,求从2000年1月1日至指定日期有多少天。要判断经历年份中是否有闰年,若是闰年,二月为29天,平年为28天。判断闰年的方法可以描述如下:

如果年能被4除尽且不能被100除尽或能被400除尽,则该年是闰年,否则不是闰年。

C语言中判断能否整除可使用求余(模)运算。

程序如下:

img481

img482

img483

运行结果:

请输入待查询的日期(年,月,日):2005,11,28

输出:今天该晒网。