OS: Mac Catalina 10.15.4 Hardware: Intel Core i9/16G 2667MHz DDR4
编译器版本:Mac Xcode 11.6
第05章 运算符、表达式和语句
目录
例题4: 乘法运算符*,打印1~20及其平方 Page 108
例题及笔记
例题1: 把鞋码转换成英寸 Page 103
/* shoes1.c -- 把鞋码转换成英寸 */
#include <stdio.h>
#define ADJUST 7.31 // 字符常量
int main(void)
{
const double SCALE = 0.333; // const常量
double shoe, foot;
shoe = 9.0;
foot = SCALE * shoe + ADJUST;
printf("Shoe size (men's) foot length\n");
printf("%10.f %15.2f inches\n", shoe, foot);
return 0;
}
运行结果如下图:
例题2: 用循环改进例题1 Page 104
/* shoes2.c --计算多个不同鞋码对应的脚长 */
#include <stdio.h>
#define ADJUST 7.31 // 字符常量
int main(void)
{
const double SCALE = 0.333; // const 变量
double shoe, foot;
printf("Shoe size (men's) foot length\n");
shoe = 3.0;
while (shoe < 18.5) /* whilie循环开始 */
{ /* 块开始 */
foot = SCALE * shoe + ADJUST;
printf("%10.1f %15.2f inches\n", shoe, foot);
shoe = shoe + 1.0;
} /* 块结束 */
printf("If the shoe fits, wear it.\n");
return 0;
}
使用while循环的一个例子
程序输出结果:
例题3: 赋值运算符 page 107
/* golf.c --高尔夫锦标赛计分卡 */
#include <stdio.h>
int main(void)
{
int jane, tarzan, cheeta;
cheeta = tarzan = jane = 68;
printf(" cheeta tarzan jane\n");
printf("First round score %4d %8d %8d\n", cheeta, tarzan, jane);
return 0;
}
注意:赋值从右往左
程序输出结果:
例题4: 乘法运算符*,打印1~20及其平方 Page 108
/* squares.c -- 计算1~20的平方 */
#include <stdio.h>
int main(void)
{
int num = 1;
while (num < 21)
{
printf("%4d %6d\n", num, num * num);
num = num + 1;
}
return 0;
}
程序输出结果
例题5: 指数增长 Page 109
棋盘放小麦问题
/* wheat.c -- 指数增长 */
#include <stdio.h>
#define SQUARES 64 // 棋盘中的方格数
int main(void)
{
const double CROP = 2E16; // 世界小麦年产谷粒数
double current, total;
int count = 1;
printf("square grains total ");
printf("fraction of \n");
printf(" added grains ");
printf("world total\n");
total = current = 1.0; /* 从1颗谷粒开始 */
printf("%4d %13.2e %12.2e %12.2e\n", count, current,
total, total / CROP);
while (count < SQUARES)
{
count = count + 1;
current = 2.0 * current; /* 下一个方格谷粒翻倍 */
total = total + current; /* 更新总数 */
printf("%4d %13.2e %12.2e %12.2e\n", count, current,
total, total / CROP);
}
printf("That's all.\n");
return 0;
}
输出结果(前10行)
例题6: 除法运算符: / Page 110
演示除法,整数除法和浮点数除法
/* divide.c -- 演示除法 */
#include <stdio.h>
int main(void)
{
printf("integer division: 5/4 is %d \n", 5 / 4);
printf("integer division: 6/3 is %d \n", 6 / 3);
printf("integer division: 7/4 is %d \n", 7 / 4);
printf("floating division: 7./4. is %1.2f \n", 7. / 4.);
printf("mixed division: 7./4 is %1.2f \n", 7. / 4);
return 0;
}
输出结果:
- 最后一行是混合计算,浮点数除以整数,但是编译器会将类型统一转换成浮点数后进行计算。尽量规避这种编程风格,使用相同类型进行计算。
例题7: 优先级和求值顺序 Page 112
优先级测试
/* rules.c -- 优先级测试 */
#include <stdio.h>
int main(void)
{
int top, score;
top = score = -(2 + 5) * 6 + (4 + 3 * (2 + 3));
printf("top = %d, score = %d\n", top, score);
return 0;
}
程序输出结果
分解如下:
-(2 + 5) * 6 + (4 + 3 * (2 + 3))=-(7) * 6 + (4 + 3 * 5)=-7 * 6 + (4 + 15)=-7 * 6 + 19
=-42+19=-23
score=-23
top=-23
例题8: sizeof运算符 Page 113
// sizeof.c -- 使用sizeof运算符
// 使用C99新增的%zd转换说明 -- 如果编译器不支持%zd,请将其改成%u或%lu
#include <stdio.h>
int main(void)
{
int n = 0;
size_t intsize;
intsize = sizeof(int);
printf("n = %d, n has %zd bytes; all ints have %zd bytes.\n",
n, sizeof n, intsize);
return 0;
}
程序输出结果
- sizeof返回的是size_t类型,是一个无符号的整数类型。
- sizeof运算符以字节为单位返回运算对象的大小。
例题9: 求模运算:% Page 114
// min_sec.c -- 把秒数转换成分和秒
#include <stdio.h>
#define SEC_PER_MIN 60 // 1分钟60秒
int main(void)
{
int sec, min, left;
printf("Convert seconds to minutes and seconds!\n");
printf("Enter the number of seconds (<=0 to quit):\n");
scanf("%d", &sec); // 读取秒数
while (sec > 0) {
min = sec / SEC_PER_MIN; // 截断分钟数
left = sec % SEC_PER_MIN; // 剩下的秒数
printf("%d seconds is %d minutes, %d seconds.\n", sec,
min, left);
printf("Enter next value (<=0 to quit):\n");
scanf("%d", &sec);
}
printf("Done!\n");
return 0;
}
程序输出结果:
- 求模运算只能针对整数,不能对浮点数计算
- 如果求模运算符第一个是正数,则结果是正数
- 如果求模运算符第一个是负数,则结果是负数
例题10: 递增运算符:++ Page 115
/* add_one.c -- 递增:前缀和后缀 */
#include <stdio.h>
int main(void)
{
int ultra = 0, super = 0;
while (super < 5)
{
super++;
++ultra;
printf("super = %d, ultra = %d\n", super, ultra);
}
return 0;
}
程序输出结果:
例题11: 递增运算符的前缀和后缀的区别 Page 117
/* post_pre.c -- 前缀和后缀 */
#include <stdio.h>
int main(void)
{
int a = 1, b = 1;
int a_post, pre_b;
a_post = a++; // 后缀递增
pre_b = ++b; // 前缀递增
printf("a a_post b pre_b\n");
printf("%1d %5d %5d %5d\n", a, a_post, b, pre_b);
return 0;
}
程序输出结果:
- a_post = a++; // 后缀:使用a的值之后,递增a
- b_pre = ++b; // 后缀:使用b的值之前,递增b
例题12: 递减运算符:-- Page 118
#include <stdio.h>
#define MAX 100
int main(void)
{
int count = MAX + 1;
while (--count > 0) {
printf("%d bottles of spring water on the wall,"
"%d bottles of spring water!\n", count, count);
printf("Take one down and pass it around,\n");
printf("%d bottles of spring water!\n\n", count - 1);
}
return 0;
}
程序输出结果(显示前2笔):
例题13: 表达式和语句 Page 121
/* addemup.c -- 几种常见的语句 */
#include <stdio.h>
int main(void) /* 计算前20个整数的和 */
{
int count, sum; /* 声明 */
count = 0; /* 表达式语句 */
sum = 0; /* 表达式语句 */
while (count++ < 20) /* 迭代语句 */
sum = sum + count;
printf("sum = %d\n", sum); /* 表达式语句 */
return 0; /* 跳转语句 */
}
程序输出结果:
例题14: 类型转换 Page 125
/* convert.c -- 自动类型转换 */
#include <stdio.h>
int main(void)
{
char ch;
int i;
float f1;
f1 = i = ch = 'C';
printf("ch = %c, i = %d, f1 = %2.2f\n", ch, i, f1);
ch = ch + 1;
i = f1 + 2 * ch;
f1 = 2.0 * ch + i;
printf("ch = %c, i = %d, f1 = %2.2f\n", ch, i, f1);
ch = 1107;
printf("Now ch = %c\n", ch);
ch = 80.89;
printf("Now ch = %c\n", ch);
return 0;
}
程序输出结果:
- ch = 1107; 超出了范围,被截断,其与暖结果是1107 % 265 = 83 = 'S'
- ch = 80.89; 被截断得 ch = 80
例题15: 带参数的函数 Page 127
/* pound.c -- 定义一个带一个参数的函数 */
#include <stdio.h>
void pound(int n); //ANSI 函数原型声明
int main(void)
{
int times = 5;
char ch = '!'; // ASCII码是33
float f = 6.0f;
pound(times); // int类型的参数
pound(ch); // 和pound((int)ch);相同
pound(f); // 和pound((int)f);相同
return 0;
}
void pound(int n) // ANSI风格函数头
{ // 表面该函数接受一个int类型的参数
while (n-- > 0)
printf("#");
printf("\n");
}
程序输出结果:
例题16: 示例程序 Page 129
// running.c -- A useful program for runners
#include <stdio.h>
const int S_PER_M = 60; // 1分钟的秒数
const int S_PER_H = 3600; // 1小时的秒数
const double M_PER_K = 0.62137; // 1公里的英里数
int main(void)
{
double distk, distm; // 跑过的距离(分别以公里和英里为单位)
double rate; // 平均速度(以英里/小时为单位)
int min, sec; // 跑步用时(以分钟和秒为单位)
int time; // 跑步用时(以秒为单位)
double mtime; // 跑1英里所需要的时间,以秒为单位
int mmin, msec; // 跑1英里所需要的时间,以分钟和秒为单位
printf("This program converts your time for a metric race\n");
printf("to a time for running a mile and to your average\n");
printf("speed in miles per hour.\n");
printf("please enter, in kilometers, the distance run.\n");
scanf("%lf", &distk); // %lf表示读取一个double类型的值
printf("Next enter the time in minutes and seconds:\n");
printf("Begin by entering the minutes.\n");
scanf("%d", &min);
printf("Now enter the seconds.\n");
scanf("%d", &sec);
time = S_PER_M * min + sec; // 把时间转换成秒
distm = M_PER_K * distk; // 把公里转换成英里
rate = distm / time * S_PER_H; // 英里/秒*秒/小时 = 英里/小时
mtime = (double) time / distm; // 时间/距离 = 跑1英里所用的时间
mmin = (int) mtime / S_PER_M; // 求出分钟数
msec = (int) mtime % S_PER_M; // 求出剩余的秒数
printf("You ran %1.2f km (%1.2f miles) in %d min, %d sec.\n",
distk, distm, min, sec);
printf("That pace corresponds to running a mile in %d min, ",
mmin);
printf("%d sec.\nYour average speed was %1.2f mph.\n", msec,
rate);
return 0;
}
程序输出结果:
编程练习
习题1
编写一个程序,把用分钟表示的时间转换成用小时和分钟表示的时间。使用#define或const创建一个表示60的符号常量或const变量。通过while循环让用户重复输入值,直到用户输入小于或等于0的值才停止循环。
#include <stdio.h>
#define MINUTE_PER_HOUR 60
int main(void)
{
int minute, hour, key_minutes;
printf("请输入时间(单位分钟),输入<=0表示退出程序:");
scanf("%d", &key_minutes);
while(key_minutes > 0)
{
hour = (int) key_minutes / MINUTE_PER_HOUR;
minute = key_minutes % MINUTE_PER_HOUR;
printf("转换成小时:分钟为:%4d小时%4d分钟\n", hour, minute);
printf("请输入时间(单位分钟),输入<=0表示退出程序:");
scanf("%d", &key_minutes);
}
return 0;
}
程序输出结果:
习题2
编写一个程序,提示用户输入一个整数,然后打印从该数到比该数大10的所有整数(例如,用户输入5,则打印5~15的所有整数,包括5和15)。要求打印的各值之间用一个空格、制表符或换行符隔开。
#include <stdio.h>
int main(void)
{
int value, comp;
printf("输入一个整数:");
scanf("%d", &value);
comp = value + 10;
printf("比%d大10的所有整数有:\n", value);
while(value++ <= comp)
{
printf("%d\t", value - 1);
}
printf("\n");
return 0;
}
程序输出结果:
习题3
编写一个程序,提示用户输入天数,然后将其转换成周数和天数。例如,用户输入18,则转换成2周4天。以下面的格式显示结果:
18 days are 2 weeks, 4 days.
#include <stdio.h>
int main(void)
{
int days;
printf("Pleae days:");
scanf("%d", &days);
printf("%d days are %d weeks, %d days.\n",
days, (int)days / 7, days % 7);
return 0;
}
输出结果如下:
习题4
编写一个程序,提示用户输入一个身高(单位:厘米),并分别以厘米和英寸为单位显示该值,允许有小数部分。程序应该能让用户重复输入身高,直到用户输入一个非正值。其输出示例如下:
Enter a height in centimeters: 182
182.0 cm = 5 feet, 11.7 inches
Enter a height in centimeters (<=0 to quit): 168.7
168.7 cm = 5 feet, 6.4 inches
Enter a height in centimeters (<=0 to quit): 0
bye
#include <stdio.h>
#define CM_TO_INCH 0.393700787402 // 厘米转英寸
#define CM_TO_FEET 0.0328084 // 厘米转英尺
int main(void)
{
float height_cm;
int height_feet;
printf("Enter a height in cenntimeters: ");
scanf("%f", &height_cm);
while (height_cm > 0) {
height_feet = (int)height_cm * CM_TO_FEET;
printf("%.1f cm = %d feet, %.1f inches\n", height_cm,
height_feet,
(height_cm - (height_feet / CM_TO_FEET)) * CM_TO_INCH);
printf("Enter a height in centimeter (<=0 to quit): ");
scanf("%f", &height_cm);
}
printf("bye\n");
return 0;
}
程序输出结果:
习题5
修改程序addemup.c(程序清单5.13),你可以认为addemup.c是计算20天里赚多少钱的程序(假设第1天赚$1、第2天赚$2、第3天赚$3,一次类推)。修改程序,使其可以与用户交互,根据用户输入的数进行计算(即,用读入的第一个变量来代替20)。
#include <stdio.h>
int main(void)
{
int days, sum = 0, i = 1;
printf("输入天数:");
scanf("%d", &days);
while (days-- > 0)
{
sum += i++;
}
printf("sum = %d\n", sum);
return 0;
}
程序输出结果:
习题6
修改编程练习5的程序,使其能计算整数的平方和(可以认为第1天赚$1、第2天赚4$、第3天赚9,依此类推,这看起来不错)。C没有平方函数,但是可以用n * n来表示n的平方
#include <stdio.h>
int main(void)
{
int days, i = 1;
float sum = 0;
printf("输入天数: ");
scanf("%d", &days);
while (days-- > 0)
{
sum += i * i;
++i;
}
printf("sum = %.0f\n", sum);
return 0;
}
程序输出结果:
习题7
编写一个程序,提示用户输入一个double类型的数,并打印该数的立方值。自己设计一个函数计算并打印立方值。main()函数要把用户输入的值传递给该函数。
#include <stdio.h>
void cube(double x);
int main(void)
{
double value;
printf("输入一个double类型的数: ");
scanf("%lf", &value);
cube(value);
return 0;
}
void cube(double x)
{
printf("%lf^3 = ", x);
printf("%lf\n", x * x * x);
}
程序输出结果:
习题8
编写一个程序,提示求模运算的结果。把用户输入的第1个整数作为求模运算符的第2个运算对象,该数载运算过程中保持不变。用户后面输入的数是第1个运算对象。当用户输入一个非正值时,程序结束。其输出示例如下:
This program computes moduli.
Enter an integer to serve as the second operand: 256
Now enter the first operand: 438
438 % 256 is 182
Enter next number for first operand (<= 0 to quit): 1234567
1234567 % 256 is 135
Enter next number for first operand (<= 0 to quit): 0
Done
#include <stdio.h>
int main(void)
{
int first, second;
printf("This program computes moduli.\n");
printf("Enter an integer to serve as the second operand: ");
scanf("%d", &second);
printf("Now enter the first operand: ");
scanf("%d", &first);
while (first > 0)
{
printf("%d %% %d is %d\n", first, second, first % second);
printf("Enter next number for first operand (<= 0 to quit): ");
scanf("%d", &first);
}
printf("Done\n");
return 0;
}
程序输出结果:
习题9
编写一个程序,要求用户输入一个华氏摄氏度。程序应读取double类型的值作为温度值,并把该值作为参数传递给一个用户自定义的函数Temperatures()。该函数计算摄氏温度和开氏温度,并以小数点后面两位数字的精度显示3种温度。要使用不同的温标来表示这3个温度值。下面是华氏温度转换成摄氏温度的公式:
摄氏温度 = 5.0 / 9.0 * (华氏温度 - 32.0)
开氏温标常用于科学研究,0表示绝对零,代表最低温度。下面是摄氏温度转开氏温度的公式:
开始温度 = 摄氏温度 + 273.16
Temperatures()函数中用const创建温度转换中使用的常量。在main()函数中使用一个循环让用户重复输入温度,当用户输入q或者其他非数字时,循环结束。scanf()函数返回读取数据数量,所以如果读取数字则返回1,如果读取q则不返回1。可以使用==运算符将scanf()的返回值和1作比较,测试两值是否相等。
#include <stdio.h>
void Temperature(double temper_f);
int main()
{
double temperature_f = 0;
printf("输入华氏摄氏度(°F): ");
while (scanf("%lf", &temperature_f) == 1) {
Temperature(temperature_f);
printf("输入华氏摄氏度(°F),输入q或者非数字退出: ");
}
printf("Done.\n");
return 0;
}
void Temperature(double temper_f)
{
const double R1 = 5.0 / 9.0;
const double V1 = 32.0;
const double V2 = 273.16;
double temper_c, temper_k;
//华氏温度转摄氏温度
temper_c = R1 * (temper_f - V1);
//摄氏温度转开氏温度
temper_k = temper_c + V2;
printf("%10.2lf °F = %10.2lf °C = %10.2lf °K\n",
temper_f, temper_c, temper_k);
}
程序输出结果 :