C语言程序设计案例精粹
上QQ阅读APP看本书,新人免费读10天
设备和账号都新为新人

实训3.1——计算圆柱体体积

教学录像 光盘\chap3\实训3.1——计算圆柱体体积

有一长为50 cm,宽为30 cm的长方形纸张,编写程序,计算将该纸张卷成圆筒时的体积,要求精确到小数点后6位,圆周率取3.141592。

纸张卷成圆筒的方法有两种,一种是以长50 cm作高,宽30 cm作底,另一种是以宽30 cm作高,长50 cm作底。这里使用第二种方案。

1. 需求分析

分析目标需求,程序中需要做到如下几条。

需求1:计算圆筒的底面半径r

需求2:计算圆筒体积。

需求3:精确度为小数点后6位。

2. 技术应用

根据C语言标准以及开发平台版本,完善各个需求模块。

对于需求1,使用已知周长50 cm计算半径r,注意使用数据类型为浮点。实现语句如下:

r=50.0/(2*pi);

对于需求2,根据数学公式:V=S*H,计算体积V = pi*r*r*h,其中h=30。

对于需求3,由于要求精确到小数点后6位,因此采用数据类型double型。

通过上述分析,写出完整的程序如下。

程序清单3.1:CalculateVector.c

          01   #include<stdio.h>
          02   main()
          03   {
          04       int l_long=50;                      //定义长度
          05       int w_whith=30;                    //定义宽度
          06       double r=0;                        //定义半径
          07       double pi=3.141592;                  //定义圆周率
          08       double V=0;                       //定义体积
          09       r=l_long/(2*pi);                     //计算半径
          10       V=pi*r*r*w_whith;                  //计算体积
          11       printf("radius=%f, volume=%f\n", r, V);
          12   }

程序运行结果为:

radius = 7.957749, volume = 5968.311608

程序使用了double类型作为变量的定义类型,读者可试着将该类型变为float型和int型,然后运行程序,查看结果与本实训是否相同,并分析原因。

随·堂·实·训3.1

使用第一种方法,即以长50 cm作高,宽30 cm作底,重新编写程序,验证两者所得体积是否相同。

(1)修改程序第4行和第5行的值。

(2)使用不同精度的数据类型验证所得结果的精确性。

3.4.2 模除运算符

模除运算符(%)用于求两个整数相除的余数。%的优先级与四则运算符*和/相同,结合律从左到右。需要注意的是,模除运算只能用于整数间求余运算,不可用于浮点数。并且0不能作为除数。例如:

7%3结果为1,而7.5%5将使程序编译出错。

C语言规定,%两边的操作数都为正整数,结果为正整数或零;%两边的操作数都是负整数,结果为负整数或零。%左边的操作数是正整数,结果为正整数或零;%左边的操作数是负整数,结果为负整数或零。例如:

17%4 = 1

17%-4 = 1

-17%4 = -1

-17%-4 = -1

范例3.5 Months2Year.c

Months2Year.c程序实现键盘输入总月数,用%运算符和/运算符将输入的月数换算成年数和月数的形式,如25个月,表示2年零1个月。(光盘\chat3\ Months2Year.c)

          01   #include<stdio.h>
          02   #define MONTH_ONE_YEAR  12                   //宏定义
          03   main()
          04   {
          05       unsigned int months_num=0;
          06       unsigned int years_num=0;
          07       unsigned int months_stay=0;
          08       printf("请输入月数:");
          09       scanf("%d", &months_num);                             //输入总月数
          10       years_num=months_num/MONTH_ONE_YEAR;        //计算年数
          11       months_stay=months_num % MONTH_ONE_YEAR;  //计算剩余月数
          12       printf("%d个月是 %d年,%d个月.\n", months_num, years_num, months_stay);
          13   }

对于模除运算,例如m%n,可以使用公式m - (m / n) * n代替。例如上述算式中-17%4,可以使用下面算式计算:

-17%4 = -17- (-17 / 4) * 4 = -1

程序运行时由键盘输入25并按Enter键:

请输入月数: 25

将输出:

25个月是2年, 1个月.

作者心得:

注意/和%的区别,如下程序:

01 int a =17, b = 3;

02 printf("a/b = %d, a%d = %d\n", a/b, a%b);

程序输出:a/b = 5, a%b =2

3.4.3 自增自减运算符

自增(++)自减(--)运算符是C语言所特有的运算符,在工程中应用非常频繁。这两种运算符只能用于变量,不能用于表达式或其他C语言对象。例如下面操作均不正确。

(b+c)++;

--(m-1);

按照与变量的结合顺序,自增自减运算分别分为左运算和右运算两类,例如:++a,--b为左运算,a++,b--为右运算。

范例3.6 SelfAddSelfReduce.c

SelfAddSelfReduce.c程序定义4个变量a, b, c, d。对部分变量执行自增自减操作,验证左运算和右运算的区别,并进一步分析自增自减运算符与算术运算符的优先级。(光盘\chat3\ SelfAddSelfReduce.c)

          01   #include<stdio.h>
          02   main()
          03   {
          04       int  a=2;
          05       int  b=5;
          06       int  c=0;
          07       int  d=0;
          08       int  e=0;
          09       c=a++;               //将a自增右运算后赋给c
          10       d=--c;               //将c自减左运算后赋给d
          11       e=--d+c++;          //将d与c的复合运算赋给e
          12       printf("a=%d, b=%d, c=%d, d=%d, e=%d\n", a, b, c, d, e);
          13   }

程序第9行赋值语句,将表达式a++的值赋给变量c,对于表达式a++,由于对a采用右运算,因此表达式的值为a的值2,将该表达式的值2赋给c,然后a做自增1运算,a变为3。等价语句如下:

c = a;

a = a + 1;

程序第10行赋值语句,由于是在第9行语句的基础上进行运算,因此需考虑第9行中变量c的值,上述讨论中确定c的值为2。本行赋值语句是将表达--c的值赋给变量d。对于表达式--c,由于对c采用左运算,因此首先进行c自减1运算,c变为1。同时,表达式的值为c的值,也为1,然后将表达式的值1赋给变量d。等价语句如下:

c = c -1;

d = c;

对于第11行赋值语句,由于是在第10行语句的基础上进行运算,因此需要考虑第10行中变量c和变量d的值分别为:c = 1、d = 1。本行赋值语句是将表达式--d + c++赋给变量e,对表达式--d + c++,先对d进行自减1运算,d变为0,然后将d的值与c的值相加得到1,作为整个表达式的值赋给变量e,然后变量c做自增1运算,c的值变为2。等价语句如下:d = d -1;

e = d + c;

c = c + 1;

综合上述讨论,程序9,10,11行等价于如下程序段:

c = a;

a = a + 1;

c = c -1;

d = c;

d = d -1;

e = d + c;

c = c + 1;

程序运行输出结果为:

a = 3, b = 5, c = 2, d = 0, e = 1

左运算中表达式的值为变量作自增或自减运算后所参与运算的值,右运算中表达式的值为变量作自增或自减前所参与运算的值。

范例3.7 SelfAddSelfReduce2.c

SelfAddSelfReduce2.c定义变量a,分别执行单次和多次自增运算,输出结果,分析同一表达式中两次和三次自增操作中左运算和右运算的差别。(光盘\chat3\ SelfAddSelfReduce2.c)

          01   #include<stdio.h>
          02   main()
          03   {
          04       int a=3;
          05       int b=0;
          06       int c=0;
          07       b=a++;                           //a执行一次自增右运算
          08       printf("a=%d, b=%d\n", a, b);
          09       a=3;
          10       b=(a++)+(a++);                     //a执行两次自增右运算
          11       printf("a=%d, b=%d\n", a, b);
          12       a=3;
          13       b=(a++)+(a++)+(a++);                //a执行三次自增右运算
          14       printf("a=%d, b=%d\n", a, b);
          15       a=3;
          16       b=++a;                           //a执行一次自增左运算
          17       printf("a=%d, b=%d\n", a, b);
          18       a=3;
          19       b=(++a)+(++a);                     //a执行两次自增左运算
          20       printf("a=%d, b=%d\n", a, b);
          21       a=3;
          22       b=(++a)+(++a)+(++a);                //a执行三次自增左运算
          23       printf("a=%d, b=%d\n", a, b);
          24   }

程序第10行将a作两次自增右运算的和赋给b。程序首先取a的值3作加运算,将和6赋给b,然后a作两次自增运算,变为5。

程序第13行将a作三次自增右运算的和赋给b。程序首先取a的值3作加运算,将和9赋给b,然后a作三次自增运算,变为6。

程序第19行将a作两次自增左运算的和赋给b。程序首先将a作两次自增左运算,a变为5,然后取a的值作加运算,将和10赋给b。

程序第22行将a作三次自增左运算的和赋给b。由于赋值运算符右边表达式中含有3个算术加(+)运算符,同时+运算符结合性为自左至右,因此程序首先取前两个自增表达式作加运算,即(++a)+(++a),此时a的值变为5,即作5+5操作,得和10。然后再作最后一个+运算符操作,a变为6,然后作10+6操作,得和16。最后将和数16赋给变量b。

程序运行输出结果为:

a = 4, b = 3

a = 5, b = 6

a = 6, b = 9

a = 4, b = 4

a = 5, b = 10

a = 6, b = 16

作者心得:

上述范例3.7主要说明自增自减运算符的执行过程,实际编程中,程序员应尽量避免使用类似程序第13行和第22行这类难以理解的语句。