C Primer Plu学习笔记【7-8章节】
第7章 C控制语句:分支和跳转
7.1 if语句
示例代码
#include <stdio.h> int main(void) { const int FREEZING = 0; float temperature; int cold_days = 0; int all_days = 0; printf("Enter the list of daily low temperatures.\n"); printf("Use Celsius and enter q to quit.\n"); while (scanf("%f", &temperature) == 1) { all_days++; if (temperature < FREEZING) { cold_days++; } } if (all_days != 0) { printf("%d days total: %.1f%% were below freezing.\n", all_days, 100.0 * (float) cold_days / all_days); } if (all_days == 0) { printf("No data entered!\n"); } return 0; }
输出:
Enter the list of daily low temperatures.
Use Celsius and enter q to quit.
12 5 -2.5 0 6 8 -3 -10 10 q
9 days total: 33.3% were below freezing.
比较简单的格式
if (expression)
statement
7.2if else语句
if (expression)
statement
else
statement
二选一的if else表达式
7.2.1 另一示例:介绍getchar与putchar()
getchar()与putchar()定义在stdio.h头文件中。在处理字符的时候,用起来比较方便
示例代码
#include <stdio.h> #define SPACE ' ' int main(void) { char ch; ch = getchar(); while (ch != '\n') { // 对输入进行判断 if (ch == SPACE) { putchar(ch); } else { putchar(++ch); } ch = getchar(); /* 循环接受字符*/ } putchar(ch); // 打印换行符号 return 0; }
输出
CALL ME HAL
DBMM NF IBM
改进的C语言程序员写法
#include <stdio.h> #define SPACE ' ' int main(void) { char ch; while ((ch = getchar()) != '\n') { // 对输入进行判断 if (ch == SPACE) { putchar(ch); } else { putchar(++ch); } } putchar(ch); // 打印换行符号 return 0; }
7.2.2 ctype.h系列的字符函数
介绍了一些ctype.h头文件中判断字符的函数
#include <stdio.h> #include <ctype.h> int main(void) { char ch; while ((ch = getchar()) != '\n') { // 对输入进行判断 if (isalnum(ch)) { // 是字符就处理 putchar(++ch); } else { putchar(ch); } } putchar(ch); // 打印换行符号 return 0; }
输出
LOOK! It's a programmer!
MPPL! Ju't b qsphsbnnfs!
Program ended with exit code: 0
7.2.3多重选择else if
示例代码
#include <stdio.h> #define RATE1 0.13230 #define RATE2 0.15040 // 定义不同档次的电费价格 #define RATE3 0.30025 #define RATE4 0.34025 #define BREAK1 360.0 // 定义了每档的用电度数 #define BREAK2 468.0 #define BREAK3 720.0 // 这个定义设计的很好,定义第一档用到的时候电费价格 #define BASE1 (RATE1 * BREAK1) #define BASE2 (BASE1 + (RATE2 * (BREAK2 - BREAK1))) #define BASE3 (BASE1 + BASE2 + (RATE3 * (BREAK3 - BREAK2))) int main(void) { double kwh; double bill; printf("Please enter the kwh used.\n"); scanf("%lf", &kwh); if (kwh <= BREAK1) { bill = RATE1 * kwh; } else if (kwh <= BREAK2) { bill = BASE1 + (RATE2 * (kwh - BREAK1)); } else if (kwh <= BREAK3) bill = BASE2 + (RATE3 * (kwh - BREAK2)); else bill = BASE3 + (RATE4 * (kwh - BREAK3)); printf("The charge for %.1f kwh is $%1.2f.\n", kwh, bill); return 0; }
输出
Please enter the kwh used.
580
The charge for 580.0 kwh is $97.50.
Program ended with exit code: 0
整个代码使用了预处理很好的定义了一些常量,思路还是非常不错的。
7.2.4 else与if配对
没有大括号的情况下,else与最近的if配对。
7.2.5 多层嵌套的if语句
示例代码
#include <stdio.h> #include <stdbool.h> int main(void) { unsigned long num; unsigned long div; bool isPrime; printf("Please enter an integer for analysis; "); printf("Enter q to quit.\n"); while (scanf("%lu", &num) == 1) { for (div = 2, isPrime = true; (div * div) <= num; div++) { if (num % div ==0){ if ((div * div) != num) { printf("%lu is divisible by %lu and %lu.\n", num, div, num/div); } else {printf("%lu is divisible by %lu.\n", num, div);} isPrime = false; // 不是素数 } } if (isPrime) { printf("%lu is prime.\n", num); } printf("Please enter anpther integer for analysis; "); printf("Enter q to quit.\n"); } printf("Bye.\n"); return 0; }
输出
Please enter an integer for analysis; Enter q to quit.
25
25 is divisible by 5.
Please enter anpther integer for analysis; Enter q to quit.
149
149 is prime.
Please enter anpther integer for analysis; Enter q to quit.
81
81 is divisible by 3 and 27.
81 is divisible by 9.
Please enter anpther integer for analysis; Enter q to quit.
q
Bye.
Program ended with exit code: 0
7.3逻辑运算符
这个就是Python中的and or not
示例代码
#include <stdio.h> #define PERIOD '.' int main(void) { char ch; int charcount = 0; while ((ch = getchar()) != PERIOD) { // 书中的if (ch != '"' and ch != '\'') if (!(ch == '"' || ch == '\'')) { charcount++; } } printf("There are %d non-quote characters.\n", charcount); return 0; }
I didn't read the "I'm a Programming Fool" best seller.
There are 50 non-quote characters.
&&表示and
||表示or
!表示not
7.3.1 备选拼写: iso646.h头文件
导入这个头文件就可以用and or not 来代替&& || !了
#include <stdio.h> #include <iso646.h> #define PERIOD '.' int main(void) { char ch; int charcount = 0; while ((ch = getchar()) != PERIOD) { // 书中的if (ch != '"' and ch != '\'') if (!(ch == '"' or ch == '\'')) { charcount++; } } printf("There are %d non-quote characters.\n", charcount); return 0; }
7.3.2
优先级!的运算符优先级很高,比乘法远算符还高。&&比||高,但比< >等关系远算符要低。
写的时候最好用上小括号,表示各个比较逻辑。
7.3.3 求值顺序
C保证逻辑表达式的求值顺序是从左向右。 &&和||运算符都是序列点,所有程序在从一个运算对象到下一个运算对象之前,所有的副作用都会生效。
书中介绍了求值顺序,与短路原则
x != 0 && (20 / x) <5 当写这个条件的时候,短路原则可以剔除了x为0 的情况。
7
7.3.4 范围
写条件的时候
if (range >= 90 && range <= 100)
printf("ok");
不要写成
if (90 <= range <= 100)
printf("ok");
这个会永远成立,因为逻辑表达式是从左向右执行的。
(90 <= range) <= 100
前面无论如何返回的都是0或1,这个条件永远成立。
7.4 一个统计单词的程序,设计的非常好的逻辑算法
#include <stdio.h> #include <ctype.h> #include <stdbool.h> #define STOP '|' int main(void) { char c; char prev; long n_chars = 0L; int n_lines = 0; int n_words = 0; int p_lines = 0; bool inword = false; printf("Enter text to br analyzed (| to terminate):\n"); prev = '\n'; while ((c = getchar()) != STOP) { // 循环读取输入的字符 n_chars++; // 统计字符数量 if (c == '\n') { // 统计换行数量 n_lines++; } if (!isspace(c) && !inword) { //只要出现字母就统计第一个单次,且后面的字母忽略 inword = true; n_words++; } if (isspace(c) && inword) { //只要在字母中,出现空格就设置inword不在字母中,给前面的统计创建条件 inword = false; } prev = c; } if (prev != '\n') { // 统计最后一行是否有换行符 p_lines = 1; } printf("characters = %ld, words = %d, lines = %d, ", n_chars, n_words, n_lines); printf("partial lines = %d\n", p_lines); return 0; }
输出
Enter text to br analyzed (| to terminate):
I love you
see you tormorrow!|
characters = 34, words = 6, lines = 1, partial lines = 1
Program ended with exit code: 0
7.5 条件远算符
到了所谓的三目表达式了,C语言的写法是
expression ? expression2 : expression3
示例代码
#include <stdio.h> #define COVERAGE 350 // 整桶油漆可用面积 int main(void) { int sq_feet; int cans; printf("Enter number of square feet to be painted:\n"); while (scanf("%d", &sq_feet) == 1) { cans = sq_feet / COVERAGE; cans += (sq_feet % COVERAGE == 0) ? 0 : 1; printf("You need %d %s of plait.\n", cans, cans == 1 ? "can" : "cans"); printf("Enter next value (q to quit):\n"); } return 0; }
输出
Enter number of square feet to be painted:
349
You need 1 can of plait.
Enter next value (q to quit):
351
You need 2 cans of plait.
Enter next value (q to quit):
q
7.6循环辅助:continue和break
这个跟Python中的用法差不多,首相上示例代码:
#include <stdio.h> int main(void) { const float MIN = 0.0f; const float MAX = 100.f; float score; float total = 0.0f; int n = 0; float min = MAX; float max = MIN; /* 很好的一种初始值的丁回忆方式 */ printf("Enter the first score (q to quit): "); while (scanf("%f", &score) == 1) { if (score < MIN || score > MAX) { printf("%.1f is an invalid value. Try again: ", score); continue; } printf("Accepting %.1f:\n", score); min = (score < min) ? score: min; max = (score > max) ? score: max; total += score; n++; printf("Enter next score (q to quit): "); } if (n > 0) { printf("Average of %d scores is %.1f.\n", n, total / n); printf("Low = %.1f, high = %.1f\n", min, max); } else printf("No valid scores were entered.\n"); return 0; }
输出
12 45 100
Enter the first score (q to quit): Accepting 12.0:
Enter next score (q to quit): Accepting 45.0:
Enter next score (q to quit): Accepting 100.0:
Enter next score (q to quit): q
Average of 3 scores is 52.3.
Low = 12.0, high = 100.0
Program ended with exit code: 0
其实这种代码分割我是不会写的,一般我写的代码也很少用到continue,书中也说明了很多另外的写法可以替代continue
有一处书中写了,可以用来当占位符还算最有意思的解释了
while (getchar() != '\n') continue;
另外书中就没有什么有意思的东西了。
7.6.2 break语句
这个其实跟Python的用法也差不多,书中特意强调了,只会停止内部的循环,不会停止外部的。
示例代码是一个求面积的函数
#include <stdio.h> int main(void) { float length, width; printf("Enter the length of the rectangle:\n"); while (scanf("%f", &length) == 1) { printf("Length = %.2f:\n", length); printf("Enter its width:\n"); if (scanf("%f", &width) != 1) { break; } printf("Width = %.2f:\n", width); printf("Area = %.2f:\n", length * width); printf("Enter the length of the rectangle:\n"); } printf("Done.\n"); return 0; }
输出
Enter the length of the rectangle:
1.2
Length = 1.20:
Enter its width:
3.3
Width = 3.30:
Area = 3.96:
Enter the length of the rectangle:
1.5
Length = 1.50:
Enter its width:
q
Done.
7.7 多重选择: switch和break
#include <stdio.h> #include <ctype.h> int main(void) { char ch; printf("Give me a letter of the alphabet, and I will give "); printf("an animal name\nbeginning with that letter.\n"); printf("Please type in a letter; tyoe # to end my act.\n"); while ((ch = getchar()) != '#') { if ('\n' == ch) { // 回车不退出 continue; } if (islower(ch)) { switch (ch) { // stitch 使用 case 'a': printf("argali, a wild sheep of Asia\n"); break; case 'b': printf("babirusa, a wild pig of Malay\n"); break; case 'c': printf("coati racoonlike manmal\n"); break; case 'd': printf("desman, aquatic, molelike critter \n"); break; case 'e': printf("echidna, the spiny anteacher\n"); break; case 'f': printf("fisher, browish marten\n"); break; default: printf("That's a stumper!\n"); break; } } else printf("I recognize only lowercase letters.\n"); while (getchar() != '\n') { // 输入多个字符串后面的全部忽略掉 continue; } printf("Please type another letter or a #.\n"); } printf("Bye!\n"); return 0; }
输出:
Give me a letter of the alphabet, and I will give an animal name
beginning with that letter.
Please type in a letter; tyoe # to end my act.
abc#
argali, a wild sheep of Asia
Please type another letter or a #.
cd
coati racoonlike manmal
Please type another letter or a #.
#
Bye!
这是一个设计非常逻辑精密的代码,让我感觉到了作者大神就是大神。
7.7.1switch语句
switch作为我刚接触新的关键字,书中介绍C语言的case一般指定一个值,不能使用一个范围。switch在圆括号中的测试表达式的值应该是一个整数值(包括char类型。)case标签必须是整数类型(包括char类型)的常量或者整形常量表达式(既,表达式中只包含整数常量)。不能用变量作为case的便签
格式:
switch (整数表达式)
{
case 常量1:
语句;
case 常量2:
语句
}
7.7.2只读每行的首字符
书中用了case的穿透功能,有点小意思
#include <stdio.h> int main(void) { char ch; int a_ct, e_ct, i_ct, o_ct, u_ct; a_ct = e_ct = i_ct = o_ct = u_ct =0; printf("Enter some text; enter # to quit.\n"); while ((ch = getchar()) != '#') { switch (ch) { case 'a': // 这里就演示了穿透 case 'A': a_ct++; break; case 'e': case 'E': e_ct++; break; case 'i': case 'I': i_ct++; break; case 'o': case 'O': o_ct++; break; case 'u': case 'U': u_ct++; break; default: break; } } printf("number og vowels: A E I O U\n"); printf(" %4d%4d%4d%4d%4d\n", a_ct, e_ct, i_ct, o_ct, u_ct); return 0; }
输出
Enter some text; enter # to quit.
I see under the oberseer.#
number og vowels: A E I O U
0 7 1 1 1
Program ended with exit code: 0
书中后面自己也写了,可以在前面对输入条件先进行装换,那样会更加方便
头文件假如ctype 用过toupper(ch)的方式无论大小写转换成大写再判断更加方便。
7.7.4书中也介绍了,switch一般用的地方比较少,只有在整数的条件下采用。范围取值条件,if更加方便。
7.8 goto语句
第一次接触goto语句,但书中介绍要避免使用goto语句,且写法非常有意思
goto语句有两部分组成:goto 和标签名
goto:part2
要让这条语句正常工作,函数还必须包含另一条标为part2的语句,该语句以标签名后紧跟一个冒号开始:
part2: printf("Refined analysis:\n")
7.8.1避免使用goto
写代码需要尽量回避goto的用法,书中也没有整串的示例代码
只要理解一点。实际上,break和continue是goto的特殊形式。使用break和continue的好处是:其名称已经表明它们的用法,而且这些语句不使用标签,所以不用担心把标签放在错误的位置导致的危险。
#include <stdio.h> int main(void) { float length, width; printf("Enter the length of the rectangle:\n"); while (scanf("%f", &length) == 1) { printf("Length = %.2f:\n", length); printf("Enter its width:\n"); if (scanf("%f", &width) != 1) { goto end; } printf("Width = %.2f:\n", width); printf("Area = %.2f:\n", length * width); printf("Enter the length of the rectangle:\n"); } end: printf("Done.\n"); return 0; }
上面我自己简单写了一个goto的示例,还蛮有意思的。
7.11 复习题
第一题
a false b true c false
第二题
a num >= 90 && num < 100
b ch != 'q' && ch !='k'
c num>=1 && num <= 9 && num !=5
d num < 1 || num >9
第三题
抄书代码
#include <stdio.h> int main(void) { int weight, height; printf("Enter you weight in pounds and "); printf("your height in inches.\n"); scanf("%d %d", &weight, &height); if (weight < 100 && height >64) { if (height >= 72) { printf("You are very taoll for your weight.\n"); } else printf("You are tall for your weight.\n"); } else if (weight > 300 && height < 48) printf("You are quite short for your weight.\n"); else printf("Your weight is idels.\n"); return 0; }
第四题
a true
b false
c true
d 6
e 10
f false
第五题
*#%*#%*#$*#%*#%*#$*#%*#%*#$*#% 错了
第六题
hatcatOh no!catOh no!Oh no!
订正
hatcatOh no!
catOh no!
Oh no!
第七题
#include <stdio.h> int main(void) { char ch; int lc, uc, oc; lc = uc = oc =0; while ((ch = getchar()) != '#') { if ('a' <= ch && ch <= 'z') { lc++; } else if ('A' <= ch && ch <= 'Z') { uc++; } else oc++; } printf("%d lowercase, %d uppercase %d other\n", lc, uc, oc); return 0; }
答案用了Ctype头文件的判断字母大小写的函数
第八题
Your are 40,Here is a raise.
Your are 60,Here is a raise.
Your are 65,Here is a yuor gold watch.
订正,上当了
后面的if条件是个赋值语句,返回值本身。
第九题
1 2 1 1 3 1 Done 记住 带了标签的还是一个正常的语句,该如何顺序执行还是如何执行
第十题
#include <stdio.h> int main(void) { char ch; while ((ch=getchar()) != '#') { if (ch != '\n') { printf("Step 1\n"); if (ch == 'b') { break; } else if (ch == 'h') { printf("Step 3\n"); } else if (ch != 'c') printf("Step 2\n"); } } printf("Done\n"); return 0; }
输出
q
Step 1
Step 2
c
Step 1
h
Step 1
Step 3
b
Step 1
Done
订正的逻辑
#include <stdio.h> int main(void) { char ch; while ((ch=getchar()) != '#') { if (ch != '\n') { printf("Step 1\n"); if (ch == 'b') { break; } else if (ch == 'h') { printf("Step 3\n"); } else if (ch != 'c'){ printf("Step 2\n"); printf("Step 3\n"); } } } printf("Done\n"); return 0; }
没有书中的代码逻辑好。
7.12 编程练习
第一题
#include <stdio.h> int main() { char ch; int space_num, enter_num, other_num; space_num = enter_num = other_num = 0; printf("Please inpout a series string:\n"); while ((ch = getchar()) != '#') { switch (ch) { case ' ': space_num++; break; case '\n': enter_num++; break; default: other_num++; break; } } printf("The series string space num is %d, enter num is %d, other num is %d.\n", space_num, enter_num, other_num); return 0; }
输出
Please inpout a series string:
Hello every.
My name is sidian.
#
The series string space num is 4, enter num is 2, other num is 26.
Program ended with exit code: 0
第二题
#include <stdio.h> #include <string.h> int main() { char ch, ch_l[100]; int count = 0, my_index = 0; while ((ch = getchar()) != '#') { ch_l[count] = ch; count++; } while (my_index < strlen(ch_l)) { printf("\"%c\"->%3d ", ch_l[my_index], ch_l[my_index]); my_index++; if (my_index % 8 == 0) { printf("\n"); } } return 0; }
感觉中间输入\n有点小问题。
第三题
#include <stdio.h> int main(void) { char ch; int even_num, odd_num, even_sum, odd_sum; even_num = odd_num = even_sum = odd_sum = 0; while ((ch = getchar()) != '0') { if ((ch - '0') % 2) { even_num++; even_sum += (ch - 48); } else{ odd_num++; odd_sum += (ch - 48); } } printf("even number is %d ,average is %.3f,\neven number is %d ,average is %.3f.\n", even_num, (double)even_sum / even_num, odd_num, (double)odd_sum / odd_num); return 0; }
输出
1110
even number is 3 ,average is 1.000,
even number is 0 ,average is nan.
Program ended with exit code: 0
第四题
#include <stdio.h> int main(void) { char ch, ch_l[1000]; int c_index, count,change_count; c_index = count = change_count = 0; while ((ch = getchar()) != '#') { if (ch == '.') { ch_l[c_index] = '!'; change_count++; } else if (ch == '!'){ ch_l[c_index] = ch; c_index++; ch_l[c_index] = ch; change_count++; } else{ ch_l[c_index] = ch; } c_index++; } printf("Out message is: \"%s\"; change num is %d.\n", ch_l, change_count); return 0; }
输出
I love you.
You love me!
#
Out message is: "I love you!
You love me!!
"; change num is 2.
Program ended with exit code: 0
第五题
#include <stdio.h> int main(void) { char ch, ch_l[1000]; int c_index, count,change_count; c_index = count = change_count = 0; while ((ch = getchar()) != '#') { switch (ch) { case '.': ch_l[c_index] = '!'; change_count++; break; case '!': ch_l[c_index] = ch; c_index++; ch_l[c_index] = ch; change_count++; break; default: ch_l[c_index] = ch;; } c_index++; } printf("Out message is: \"%s\"; change num is %d.\n", ch_l, change_count); return 0; }
第六题
#include <stdio.h> #include <stdbool.h> int main(void) { char ch; bool is_e; int count = 0; is_e = false; while ((ch=getchar()) != '#') { switch (ch) { case 'e': is_e = true; break; case 'i': if (is_e) count++; is_e = false; default: break; } } printf("ei count number is %d.\n", count); return 0; }
输出
Receice your eieio award.#
ei count number is 3.
Program ended with exit code: 0
第七题
#include <stdio.h> #define TAX300 300 * 0.15 #define TAX450 TAX300 + 150 * 0.2 int main(void) { const double hour_salary = 10.0; double work_hour, salary, tax; printf("Please enter your working hours per week.\n"); if (scanf("%lf", &work_hour)) { if (work_hour > 40.0) { work_hour = (work_hour - 40) * 1.5 + 40;} salary = work_hour * hour_salary; if (salary <= 300.0) { tax = salary * 0.15; } else if (salary <= 450.0){ tax = TAX300 + (salary - 300) * 0.2; } else tax = TAX450 + (salary - 450) * 0.25; printf("Your all_salary is %.2f, tax is %.2f, net income is %.2f.\n", salary, tax, salary - tax); } else printf("You have typed in the wrong information.\n"); return 0; }
输出
Please enter your working hours per week.
60
Your all_salary is 700.00, tax is 137.50, net income is 562.50.
Program ended with exit code: 0
第八题
#include <stdio.h> #include <ctype.h> #define TAX300 300 * 0.15 #define TAX450 TAX300 + 150 * 0.2 #define FIRST_WAGE 8.75 #define SECOND_WAGE 9.33 #define THIRD_WAGE 10.0 #define FOURTH_WAGE 11.2 int main(void) { double hour_salary = .0; double work_hour, salary, tax; char in_num; _Bool my_condittion = 1; while (my_condittion) { printf("*****************************************************************\n"); printf("Enter the number corresponding to the desired pay rate of action\n"); printf("1) $8.75/hr 2) $9.33/hr\n"); printf("3) $10.00/hr 4) $11.20/hr\n"); printf("5) quit\n"); printf("*****************************************************************\n"); thisway:if (isdigit(in_num = getchar())){ switch (in_num) { case '1': hour_salary = FIRST_WAGE; break; case '2': hour_salary = SECOND_WAGE; break; case '3': hour_salary = THIRD_WAGE; break; case '4': hour_salary = FOURTH_WAGE; break; case '5': goto end; // 在case条件下无法break循环,又用了goto break; default: printf("Please re-enter the correct option.\n"); break; } if (hour_salary) { printf("Please enter your working hours per week.\n"); if (scanf("%lf", &work_hour)) { if (work_hour > 40.0) { work_hour = (work_hour - 40) * 1.5 + 40;} salary = work_hour * hour_salary; if (salary <= 300.0) { tax = salary * 0.15; } else if (salary <= 450.0){ tax = TAX300 + (salary - 300) * 0.2; } else tax = TAX450 + (salary - 450) * 0.25; printf("Your all_salary is %.2f, tax is %.2f, net income is %.2f.\n", salary, tax, salary - tax); } else printf("You have typed in the wrong information.\n"); } } else if(in_num == '\n') goto thisway; /* 因为只能5号退出,所以没有能力有限只能用了goto */ else{ printf("Please re-enter the correct option.\n"); } } end: printf("Bye,Bye\n"); return 0; }
输出
*****************************************************************
Enter the number corresponding to the desired pay rate of action
1) $8.75/hr 2) $9.33/hr
3) $10.00/hr 4) $11.20/hr
5) quit
*****************************************************************
a
Please re-enter the correct option.
*****************************************************************
Enter the number corresponding to the desired pay rate of action
1) $8.75/hr 2) $9.33/hr
3) $10.00/hr 4) $11.20/hr
5) quit
*****************************************************************
6
Please re-enter the correct option.
*****************************************************************
Enter the number corresponding to the desired pay rate of action
1) $8.75/hr 2) $9.33/hr
3) $10.00/hr 4) $11.20/hr
5) quit
*****************************************************************
3
Please enter your working hours per week.
60
Your all_salary is 700.00, tax is 137.50, net income is 562.50.
*****************************************************************
Enter the number corresponding to the desired pay rate of action
1) $8.75/hr 2) $9.33/hr
3) $10.00/hr 4) $11.20/hr
5) quit
*****************************************************************
4
Please enter your working hours per week.
60
Your all_salary is 784.00, tax is 158.50, net income is 625.50.
*****************************************************************
Enter the number corresponding to the desired pay rate of action
1) $8.75/hr 2) $9.33/hr
3) $10.00/hr 4) $11.20/hr
5) quit
*****************************************************************
第九题
#include <stdio.h> #include <ctype.h> #include <math.h> int main(void) { int number, other = 2, n_index = 0, init_index; long true_number = 0; char ch[80]; _Bool not_prime_number_signal = 0; printf("Please enter a number:"); while (isdigit(number = getchar())){ ch[n_index] = number; n_index++; } // printf("ch = %s\n", ch); for (init_index=0; init_index < n_index; init_index++) { true_number += (ch[init_index] - 48) * pow(10, (n_index - init_index -1)); // printf("true_name %ld\n", true_number); } printf("Input number is %ld\n", true_number); printf("All prime numbers are: "); while (true_number > 2) { while (other * other <= true_number) { if (true_number % other == 0) { not_prime_number_signal = 1; break; } else other++; } if (!not_prime_number_signal) { printf("%ld, ", true_number); } not_prime_number_signal = 0; other = 2; true_number--; } if (true_number >= 3) { printf("3, 2 ," ); } if (true_number == 2) { printf("2, "); } printf("\nDone\n"); return 0; }
输出
Please enter a number:987
Input number is 987
All prime numbers are: 983, 977, 971, 967, 953, 947, 941, 937, 929, 919, 911, 907, 887, 883, 881, 877, 863, 859, 857, 853, 839, 829, 827, 823, 821, 811, 809, 797, 787, 773, 769, 761, 757, 751, 743, 739, 733, 727, 719, 709, 701, 691, 683, 677, 673, 661, 659, 653, 647, 643, 641, 631, 619, 617, 613, 607, 601, 599, 593, 587, 577, 571, 569, 563, 557, 547, 541, 523, 521, 509, 503, 499, 491, 487, 479, 467, 463, 461, 457, 449, 443, 439, 433, 431, 421, 419, 409, 401, 397, 389, 383, 379, 373, 367, 359, 353, 349, 347, 337, 331, 317, 313, 311, 307, 293, 283, 281, 277, 271, 269, 263, 257, 251, 241, 239, 233, 229, 227, 223, 211, 199, 197, 193, 191, 181, 179, 173, 167, 163, 157, 151, 149, 139, 137, 131, 127, 113, 109, 107, 103, 101, 97, 89, 83, 79, 73, 71, 67, 61, 59, 53, 47, 43, 41, 37, 31, 29, 23, 19, 17, 13, 11, 7, 5, 3, 2,
Done
Program ended with exit code: 0
上面这道题目,我真的是又点脑子不好使,学的绝对不扎实,明明可以用scanf接受参数的.
scanf前面忘的差不多,跟getchar搞混了,真的不应该,再次反省。
第十题
#include <stdio.h> #include <ctype.h> #define SINGLE 17850 #define MASTER 23900 #define MARRIED 29750 #define DIVORCED 14875 int main(void) { char ch; double threshold, taxes, income; printf("******************************************\n"); printf("Please enter your personal information(Q is Quit):\n"); printf("A: single B: master \n"); printf("C: married D: divorced \n"); printf("Q: quit\n"); printf("******************************************\n"); while ((ch = toupper(getchar())) != ('Q')) { switch (ch) { case 'A': threshold = SINGLE; break; case 'B': threshold = MASTER; break; case 'C': threshold = MARRIED; break; case 'D': threshold = DIVORCED; break; default: threshold = 0; } if (threshold) { printf("Please enter your income:"); scanf("%lf", &income); if (income > threshold) { taxes = 0.15 * income + (income - threshold) * 0.28; } else taxes = 0.15 * income; printf("Your tax payable is %.2f.\n", taxes); printf("******************************************\n"); printf("Please enter your personal information(Q is Quit):\n"); printf("A: single B: master \n"); printf("C: married D: divorced \n"); printf("Q: quit\n"); printf("******************************************\n"); } else if (ch != '\n') { printf("Please input as requested:\n"); } } printf("Bye Bye !!\n"); return 0; }
输出
******************************************
Please enter your personal information(Q is Quit):
A: single B: master
C: married D: divorced
Q: quit
******************************************
f
Please input as requested:
z
Please input as requested:
b
Please enter your income:600
Your tax payable is 90.00.
******************************************
Please enter your personal information(Q is Quit):
A: single B: master
C: married D: divorced
Q: quit
******************************************
q
Bye Bye !!
Program ended with exit code: 0
第十一题
#include <stdio.h> #include <ctype.h> #include <math.h> #define BYE_QUESTION printf("Please enter the weight you want to buy:\n") #define SELECT_QUESTION printf("Please enter the variety you want to select(Q is Quit):\n"); int main(void) { const double artichoke = 2.05; const double beet = 1.15; const double carrot = 1.09; const double discount = 0.95; char ch; float a_weight, b_weight, c_weight, all_weight, in_weight, all_total, freight; a_weight = b_weight = c_weight = all_weight = .0; printf("******************************************\n"); printf("Please enter the variety you want to select(Q is Quit):\n"); printf("A: artichoke B: beet \n"); printf("C: carrot Q: quit\n"); printf("******************************************\n"); while ((ch = toupper(getchar())) != 'Q'){ switch (ch) { case 'A': BYE_QUESTION; scanf("%f", &in_weight); a_weight += in_weight; all_weight += in_weight; printf("The artichoke weight is %.2f, All weight is %.2f\n", a_weight, all_weight); SELECT_QUESTION; break; case 'B': BYE_QUESTION; scanf("%f", &in_weight); b_weight += in_weight; all_weight += in_weight; printf("The beet weight is %.2f, All weight is %.2f\n", b_weight, all_weight); SELECT_QUESTION; break; case 'C': BYE_QUESTION; scanf("%f", &in_weight); c_weight += in_weight; all_weight += in_weight; printf("The carrot weight is %.2f, All weight is %.2f\n", c_weight, all_weight); SELECT_QUESTION; break; default: if (ch != '\n') { SELECT_QUESTION; } break; } } if (a_weight) { printf("artichoke price: %4.2f, weight: %3.2f, total: $%4.2f.\n", artichoke, a_weight, artichoke * a_weight); } if (b_weight) { printf("beet price: %4.2f, weight: %3.2f, total: $%4.2f.\n", beet, b_weight, beet * b_weight); } if (c_weight) { printf("carrot price: %4.2f, weight: %3.2f, total: $%4.2f.\n", carrot, c_weight, carrot * c_weight); } all_total = artichoke * a_weight + beet * b_weight + carrot * c_weight; // 总价 if (all_total >= 100) { all_total *= discount; printf("You get a %.2f discount, all_total: $%4.2f.\n", discount, all_total); } else printf("all_total: $%4.2f.\n", all_total); if (all_weight <= 5.0) { freight = 6.5; printf("The freight of the goods is $%.2f.\n", freight); } else if (all_weight > 5 && all_weight <= 20){ freight = 14; printf("The freight of the goods is $%.2f.\n", freight); } else{ freight = 14 + ceil(all_weight - 20) * 0.5; printf("The freight of the goods is $%.2f.\n", freight); } // 所有的总费用 printf("The total cost of this order is %4.2f.\n", all_total + freight); return 0; }
输出
******************************************
Please enter the variety you want to select(Q is Quit):
A: artichoke B: beet
C: carrot Q: quit
******************************************
a
Please enter the weight you want to buy:
30.3
The artichoke weight is 30.30, All weight is 30.30
Please enter the variety you want to select(Q is Quit):
b
Please enter the weight you want to buy:
40.4
The beet weight is 40.40, All weight is 70.70
Please enter the variety you want to select(Q is Quit):
c
Please enter the weight you want to buy:
50.5
The carrot weight is 50.50, All weight is 121.20
Please enter the variety you want to select(Q is Quit):
c
Please enter the weight you want to buy:
5
The carrot weight is 55.50, All weight is 126.20
Please enter the variety you want to select(Q is Quit):
q
artichoke price: 2.05, weight: 30.30, total: $62.11.
beet price: 1.15, weight: 40.40, total: $46.46.
carrot price: 1.09, weight: 55.50, total: $60.50.
You get a 0.95 discount, all_total: $160.62.
The freight of the goods is $67.50.
The total cost of this order is 228.12.
Program ended with exit code: 0
第八章
字符输入/输出和输入验证
书中主要介绍所有系统都通用的标准I/O函数,用这些函数编写的可移植成勋很容易从一个系统移植到另一个系统。
8.1 单字符I/O:getchar()和putchar()
getchar与putchar的方法非常适合计算机
示例代码:
#include <stdio.h> int main(void) { signed char ch; while ((ch = getchar()) != '#') { putchar(ch); } return 0; }
输出
sd
sd
sidianhao#lala
sidianhao
8.2缓存区
书中详细的介绍了缓存的说明,在没有缓存区的情况下,计算机读取一个信息,想上面的函数会直接输出这个信息。
有缓存区的会进行缓存,一般分为完全缓存I/O和行缓冲I/O,缓存区大小一般为512字节或者4096字节。行缓存区一般在按下Enter才刷新缓冲区。
后续章节在介绍,控制缓冲的一些方法。
8.3结束键盘输入
上面的代码用'#'当结束符不是很合适,因为你不能使用这个'#'的输出了。
8.3.1 文件、流和键盘输入
文件(file)是存储器中存储信息的区域。
C使用标准的I/O标准包,可以让用户不用考虑处理不同操作系统文件的差异。
流(stream)是一种实际输入或输出映射的理想化数据流。这意味着不同属性和不同种类的输入,由属性更同一的流来表示。于是,代开文件的过程就是把流与文件相关联,而且读写都通过流来完成。
本章着重理解C把输入和输出设备视为存储设备上的普通文件,尤其是把键盘和显式设备视为每个C程序自动打开的文件。stdin流表示键盘输入,stdout流表示屏幕输出。getchar(),putchar(),printf(),scanf()函数都是标准I/O包的成员,处理这两个流。
8.3.2 文件结尾
那既然讲到文件,既必须要学如何标记文件结尾。检查文件结尾的一种方法是,在文件末尾放一个特殊的字符标记文件结尾。
文件结束可以通过Ctrl-Z来标志文件结尾,也可以通过判断存储文件大小的信息来判断是否读到文件结尾。
无论用哪一种,在C语言中,用getcahr()读取文件检测检测到文件结尾时候将返回一个特殊的值,即EOF(end of file的缩写)。scanf()函数检测到文件结尾时也返回EOF
EOF定义为-1
#include <stdio.h> int main(void) { signed char ch;
// int ch;也可以有,必须是一个有符号的整形,因为char默认是无符号的。 while ((ch = getchar()) != EOF) { putchar(ch); } return 0; }
所以我们可以通过读取的字符是否=EOF来定义是否读取到文件的底部。
Unix与Linux用Ctrl+D来传入文件结尾信号。许多微型计算机系统都把一行开始处的Ctrl+Z识别为文件结尾信号(mac就是),一些系统把任意位置的Ctrl+Z解释成文件结尾信号
8.4 重定向和文件。
> < 的重定向标识有用过,但从来不知道具体的原理,这次学习让我更好的理解了重定向的原理。
程序可以通过两种方式使用文件。第1种方法是,显式使用特定函数打开文件、关闭文件、读取文件、写入文件,诸如此类。
第二种是设计能与键盘和屏幕互动的程序,通过不同的渠道重定向输入至文件和从文件输出。
组合重定向
(base) shijianongdeMBP:sd shijianzhong$ ./a.out > myfile2 < mywords (base) shijianongdeMBP:sd shijianzhong$ cat myfile2 nihao wohao tahao you (base) shijianongdeMBP:sd shijianzhong$
重定向的输入、输出谁先谁后没有关系,输入文件名和输出文件名不能重名,这将导致输入文件在输入之前长度已被截断为0。
如果用不了重定向,可以用程序直接打开文件。示例代码。
#include <stdio.h> #include <stdlib.h> int main(void) { int ch; FILE * fp; char fname[50]; printf("Enter the name of the file: "); scanf("%s", fname); fp = fopen(fname, "r"); if (fp == NULL) { printf("Failed to open file. Bye\n"); exit(1); } while ((ch=getc(fp)) != EOF) { putchar(ch); } fclose(fp); return 0; }
代码用了一些我没学过的类似指针的。
8.5创建更友好的用户界面
8.5.1 使用缓存输入
使用缓存输入的弊端是在输入的时候会把\n带进去,前面我写代码的时候需要进行判断,书中用了更好的while循环。
示例代码:
#include <stdio.h> int main(void) { int guess = 1; printf("Pick an integer from 1 to 100. I will try to guess"); printf("it.\nRespond with a y if my guess is right and with"); printf("\nan n if it is wrong.\n"); printf("Uh...is your number %d?\n", guess); while (getchar() != 'y') { printf("Well, then, is it %d?\n", ++guess); } printf("I knew I cound do it!\n"); return 0; }
输出
Pick an integer from 1 to 100. I will try to guessit.
Respond with a y if my guess is right and with
an n if it is wrong.
Uh...is your number 1?
n
Well, then, is it 2?
Well, then, is it 3?
n
Well, then, is it 4?
Well, then, is it 5?
y
I knew I cound do it!
Program ended with exit code: 0
很明显看到了,\n的输入干扰。书中很聪明,再次用了getchar外加while循环,处理数据
#include <stdio.h> int main(void) { int guess = 1; printf("Pick an integer from 1 to 100. I will try to guess"); printf("it.\nRespond with a y if my guess is right and with"); printf("\nan n if it is wrong.\n"); printf("Uh...is your number %d?\n", guess); while (getchar() != 'y') { printf("Well, then, is it %d?\n", ++guess); // 输入的一行就处理首字符,后续的全部掉过,知道读取到\n才到外围的while循环重新读取。 while (getchar() !='\n') { continue; } } printf("I knew I cound do it!\n"); return 0; }
输出
Pick an integer from 1 to 100. I will try to guessit.
Respond with a y if my guess is right and with
an n if it is wrong.
Uh...is your number 1?
n
Well, then, is it 2?
n
Well, then, is it 3?
y
I knew I cound do it!
Program ended with exit code: 0
这个脚本还有一个小瑕疵,就是除了y和以外的首字符输入都当成了n的意思,处理一下
#include <stdio.h> int main(void) { int guess = 1; char response; printf("Pick an integer from 1 to 100. I will try to guess"); printf("it.\nRespond with a y if my guess is right and with"); printf("\nan n if it is wrong.\n"); printf("Uh...is your number %d?\n", guess); while ((response = getchar()) != 'y') { if (response == 'n') printf("Well, then, is it %d?\n", ++guess); else printf("Sorry I understand only y or n.\n"); // 输入的一行就处理首字符,后续的全部掉过,知道读取到\n才到外围的while循环重新读取。 while (getchar() !='\n') { continue; } } printf("I knew I cound do it!\n"); return 0; }
输出
Pick an integer from 1 to 100. I will try to guessit.
Respond with a y if my guess is right and with
an n if it is wrong.
Uh...is your number 1?
x
Sorry I understand only y or n.
n
Well, then, is it 2?
y
I knew I cound do it!
Program ended with exit code: 0
书中的代码还是有瑕疵的,就是第一次输入直接是enter的时候,内部的循环getchar直接没有数据可以读取了。改进代码
#include <stdio.h> int main(void) { int guess = 1; char response; printf("Pick an integer from 1 to 100. I will try to guess"); printf("it.\nRespond with a y if my guess is right and with"); printf("\nan n if it is wrong.\n"); printf("Uh...is your number %d?\n", guess); while ((response = getchar()) != 'y') { if (response == 'n') printf("Well, then, is it %d?\n", ++guess); else printf("Sorry I understand only y or n.\n"); // 输入的一行就处理首字符,后续的全部掉过,知道读取到\n才到外围的while循环重新读取。 if (response != '\n') { while (getchar() !='\n') { continue; } } } printf("I knew I cound do it!\n"); return 0; }
8.5.2 混合数值和字符输入
示例代码
#include <stdio.h> void display(char cr, int lines, int width); int main(void) { int ch; int rows, cols; printf("Enter a character and two integers:\n"); while ((ch = getchar()) != '\n') { scanf("%d %d", &rows, &cols); display(ch, rows, cols); printf("Enter another character and two integers;\n"); printf("Enter a newline to quit.\n"); } printf("Bye.\n"); return 0; } void display(char cr, int lines, int width) { int row, col; for (row = 1; row <= lines; row++) { for (col = 1; col <= width; col++) { putchar(cr); } putchar('\n'); } }
输出
Enter a character and two integers:
c 2 3
ccc
ccc
Enter another character and two integers;
Enter a newline to quit.
Bye.
由于enter按下\n的影响,一下子就输出了。同前面一样,改进这个代码,通过while 循环与getchar的配合
#include <stdio.h> void display(char cr, int lines, int width); int main(void) { int ch; int rows, cols; printf("Enter a character and two integers:\n"); while ((ch = getchar()) != '\n') { // 当无法读取到两个数字直接跳出循环 if (scanf("%d %d", &rows, &cols) != 2) break; display(ch, rows, cols); // 忽略读取到两个数字后面的输入 while (getchar() != '\n') { continue; } printf("Enter another character and two integers;\n"); printf("Enter a newline to quit.\n"); } printf("Bye.\n"); return 0; } void display(char cr, int lines, int width) { int row, col; for (row = 1; row <= lines; row++) { for (col = 1; col <= width; col++) { putchar(cr); } putchar('\n'); } }
输出
Enter a character and two integers:
c 2 3 4
ccc
ccc
Enter another character and two integers;
Enter a newline to quit.
c a 2 3 4
Bye.
Program ended with exit code: 0
8.6输入验证
主要介绍了,scanf可以获取数据,但如果获取的数据形式不对,输入的字符流内容并不会少,他只有在读取到了自己想到的数据,才会减少字符流的数据。但getchar不一样,他会一个一个处理字符,直到没有字符流,阻塞等待用户输入。
示例代码:
#include <stdio.h> #include <stdbool.h> // 验证输入是否是一个整数 long get_long(void); // 验证上面范围是否有效 bool bad_limits(long begin, long end, long low, long high); // 计算两数之间的平方和 double sum_squares(long a, long b); int main(void) { const long MIN = -10000000; const long MAX = +10000000; long start, stop; double answer; printf("This program computes the sum of the squares of " "integers in a range.\nThe lower bound should not " "be less than -10000000 and\nthe upper bound " "should not be more than +10000000.\nEnter the " "limits (enter 0 for both limits to quit):\n" "lower limit: "); start = get_long(); printf("upper limit: "); stop = get_long(); while (start != 0 || stop != 0) { if (bad_limits(start, stop, MIN, MAX)) { printf("Please try again.\n"); } else { answer = sum_squares(start, stop); printf("The sum of the squares of the integers"); printf("from %ld to %ld is %g\n", start, stop, answer); } printf("Enter the limits (enter 0 for both limits to quit):\n" "lower limit: "); start = get_long(); printf("upper limit: "); stop = get_long(); } printf("Done.\n"); return 0; } // 处理输入的字符 long get_long(void) { long input; char ch; while (scanf("%ld", &input) != 1) { while ((ch = getchar()) != '\n') { putchar(ch); } printf(" is not an integer.\nPlease enter an "); printf("integer value, such as 25, 178, or 3: "); } return input; } double sum_squares(long a, long b){ double total = 0; long i; // 类型强制装换 for (i = a; i <= b; i++) { total += (double) i * (double) i; } return total; } bool bad_limits(long begin, long end, long low, long high){ // 默认是通过指标的 bool not_good = false; if (begin > end) { printf("%ld isn't smaller than %ld.\n", begin, end); not_good = true; } if (begin < low || end < low ) { printf("Values must be %ld or greater.\n", low); not_good = true; } if (begin > high || end > high) { printf("Values must be %ld or less.\n", high); not_good = true; } return not_good; }
输出
This program computes the sum of the squares of integers in a range.
The lower bound should not be less than -10000000 and
the upper bound should not be more than +10000000.
Enter the limits (enter 0 for both limits to quit):
lower limit: low
low is not an integer.
Please enter an integer value, such as 25, 178, or 3: 3
upper limit: a bing number
a bing number is not an integer.
Please enter an integer value, such as 25, 178, or 3: 12
The sum of the squares of the integersfrom 3 to 12 is 645
Enter the limits (enter 0 for both limits to quit):
lower limit: 80
upper limit: 10
80 isn't smaller than 10.
Please try again.
Enter the limits (enter 0 for both limits to quit):
lower limit: 0
upper limit: 0
Done.
Program ended with exit code: 0
抄写的时候感觉不够用心,其实这真的是比较好的,模块拆分思路。
8.6.1分析程序
略
8.6.2 输入流和数字
书中介绍了scanf()通过%d,%f可以将传入的字符转换成整数或者浮点数,而getchar与%c则接收所有字符。
话说C语言对处理输入字符确实让我学到很多。
8.7 菜单浏览
就是设计一份菜单让用户使用,书中介绍了具体操作思路。
8.7.1
准备用while 外加 switch
8.7.2 使执行更顺利
略
8.7.3 混合字符和数值输入
示例代码
#include <stdio.h> char get_choice(void); char get_first(void); int get_int(void); void count(void); int main(void){ int choice; // 书中这里又申明了一次函数,不知道为什么还要声明一次? // void count(void); while ((choice = get_choice()) != 'q') { switch (choice) { case 'a': printf("Buy low, sell high.\n"); break; case 'b': putchar('\a'); break; case 'c': count(); break; default: printf("Program error!\n"); break; } } printf("Bye.\n"); return 0; } void count(void) { int n, i; printf("Count how far ? Enter am integer:\n"); // 再次调用函数 n = get_int(); for (i = 1; i <= n; i++) { printf("%d\n", i); } while (getchar() != '\n') { continue; } } char get_choice(void) { int ch; printf("Enter the letter og your choice:\n"); printf("a. advice b. bell\n"); printf("c. count q. quit\n"); // 再次调用函数 ch = get_first(); while ((ch < 'a' || ch > 'c') && ch != 'q') { printf("Please respond with a, b, c, or q.\n"); ch = get_first(); } return ch; } char get_first(void) { int ch; ch = getchar(); while (getchar() != '\n') { continue; } return ch; } int get_int(void){ int input; char ch; while (scanf("%d", &input) != 1) { while ((ch = getchar() != '\n')) { putchar(ch); } printf(" is not an integer.\nPlwase enter an "); printf("integer value, such as 25, -178, or 3"); } return input; }
输出
Enter the letter og your choice:
a. advice b. bell
c. count q. quit
a
Buy low, sell high.
Enter the letter og your choice:
a. advice b. bell
c. count q. quit
count
Count how far ? Enter am integer:
two
is not an integer.
Plwase enter an integer value, such as 25, -178, or 33
1
2
3
Enter the letter og your choice:
a. advice b. bell
c. count q. quit
d
Please respond with a, b, c, or q.
q
Bye.
主要的疑问使主函数内部为什么还要申明一次函数。等后面学习到函数的时候再看了。
8.8 关键概念
C程序把输入作为传入的字节流。getchar()函数把每个字符解释成一个字符编码。scanf()函数以同样的方式看待输入,但是根据装换说明,它可以把字符输入转换成数值。许多操作系统都提供重定向,允许用文件代替简单输入,用文件代替显示器输出。
程序通常接受特殊形式的输入。可以在设计程序时考虑用户在输入时肯能犯的错误,在输入验证部分处理这些错误情况,让程序更强健更友好。
对于一个小型程序,输入验证可能时代码中最复杂的部分。处理这种问题有多种方案。列如,如果用户输入错误类型的信息,可以终止程序,也可以给用户提供有限次或无限次机会重新输入。
8.9 本章小结
略。
8.10 复习题
第一题
抄答案:表达式putchar(getchar())使程序读取下一个输入字符并打印出来。getchar()的返回值时putchar()的参数。但getchar(putchar())是无效的表达式,因为getchar()不需要参数,而putchar()需要一个参数。
第二题
输出H,输出逼一声,输出换行,输出退格
第三题
count < essay > saaayct
第四题
都不是
第五题
EOF是End Of File的简称,意思为读取到文件的结尾,赋值为-1
标准答案:EOF是由getchar()scanf()返回的信号(一个特殊值),表明函数检测到文件结尾。
第六题
a:
If you qu
b:
HJac
第七题
约定为\n
书中描述:C程序处理的是流而不是直接处理文件。流(stream)是一个实际输入或输出映射的理想化数据流。这意味这不同属性和不同种类的输入,由属性更统一的流来辩识。于是,打开文件的过程就是把流与文件相关联,而且读写都通过流来完成。
标准答案: C的标准I/O库把不同的文件映射为统一的流来统一处理。
第八题
答案主要介绍了处理输入的enter符号信号,还有书中的答案示例代码由一点bug%s应该为%d
8.11 编程练习
第一题
(base) shijianongdeMBP:sd shijianzhong$ cat t (base) shijianongdeMBP:sd shijianzhong$ cat main.c #include <stdio.h> int main(void) { unsigned count=0; while (getchar() != EOF) { count++; } printf("%u\n", count-1);
return 0; } (base) shijianongdeMBP:sd shijianzhong$ ./a.out < t 0 (base) shijianongdeMBP:sd shijianzhong$ ./a.out < main.c 149 (base) shijianongdeMBP:sd shijianzhong$
第二题
#include <stdio.h> #include <iso646.h> int main(void) { int i_ch, index=0; while ((i_ch = getchar()) != EOF) { if (i_ch < ' ' and i_ch != 10 and i_ch != 9) { printf("^%c->%d ",i_ch + 64, i_ch); } else if (i_ch >= ' '){ printf("%c->%d ",i_ch, i_ch); } else if (i_ch == 10) printf("\\n->10 "); else if (i_ch == 9) printf("\\t->9 "); index++; while (index % 10 == 0) { printf("\n"); break; } } return 0; }
输出
1234567890 qwertyuiasdfghj zxcvbnm
1->49 2->50 3->51 4->52 5->53 6->54 7->55 8->56 9->57 0->48
\t->9 q->113 w->119 e->101 r->114 t->116 y->121 u->117 i->105 a->97
s->115 d->100 f->102 g->103 h->104 j->106 \t->9 z->122 x->120 c->99
v->118 b->98 n->110 m->109 \n->10 Program ended with exit code: 0
第三题
#include <stdio.h> #include <ctype.h> int main(void) { int ch; int upper, lower; upper = lower = 0; while ((ch = getchar()) != EOF) { if (isupper(ch)) { upper++; } else lower++; } printf("uppers: %d, lowers: %d\n", upper, lower); return 0; }
输出
(base) shijianongdeMBP:sd shijianzhong$ ./a.out < t.txt
uppers: 7, lowers: 8
第四题
#include <stdio.h> #include <ctype.h> #include <iso646.h> int main(void) { int ch; double char_num, word_num; _Bool start = 1; char_num = word_num = .0; while ((ch = getchar()) != EOF) { if (isalpha(ch)) { char_num++; start = 1; } else if (start) { word_num++; start = 0; } } printf("The average word has %.2f character.\n", (char_num / word_num)); return 0; }
(base) shijianongdeMBP:sd shijianzhong$ ./a.out < main.c
The average word has 3.87 character.
第五题
#include <stdio.h> int main(void) { int max = 100; int min = 1; int guess = 50; char answer; printf("Pick an integer from 1 to 100.I will try to guess"); printf("it.\nResponse with a y if my guess is right and with"); printf("\nan n if it is wrong.\n"); printf("Un... is you number %d?\n", guess); while ((answer = getchar()) != 'y') { switch (answer) { case 'u': max = guess; guess = (min + max) / 2; printf("Un... is you number %d?\n", guess); break; case 'l': min = guess; guess = (min + max) / 2; printf("Un... is you number %d?\n", guess); default: break; } } printf("I knew I could do it!\n"); return 0; }
输出
Pick an integer from 1 to 100.I will try to guessit.
Response with a y if my guess is right and with
an n if it is wrong.
Un... is you number 50?
l
Un... is you number 75?
u
Un... is you number 62?
l
Un... is you number 68?
l
Un... is you number 71?
u
Un... is you number 69?
l
Un... is you number 70?
y
I knew I could do it!
Program ended with exit code: 0
第六题
#include <stdio.h> #include <ctype.h> char get_first(void); int main(void) { char ch = get_first(); printf("The resule char is \"%c\"\n", ch); return 0; } char get_first(void) { int ch; while (1) { ch = getchar(); if (! isblank(ch)){ break; } } while (getchar() != '\n') { continue; } return ch; }
输出
bc 12 d
The resule char is "b"
第七题
#include <stdio.h> #include <ctype.h> #include <string.h> #define TAX300 300 * 0.15 #define TAX450 TAX300 + 150 * 0.2 #define FIRST_WAGE 8.75 #define SECOND_WAGE 9.33 #define THIRD_WAGE 10.0 #define FOURTH_WAGE 11.2 int main(void) { double hour_salary = .0; double work_hour, salary, tax; char in_char; _Bool my_condittion = 1; while (my_condittion) { printf("*****************************************************************\n"); printf("Enter the number corresponding to the desired pay rate of action\n"); printf("a) $8.75/hr b) $9.33/hr\n"); printf("c) $10.00/hr d) $11.20/hr\n"); printf("q) quit\n"); printf("*****************************************************************\n"); thisway:if (isalpha(in_char = getchar())){ switch (tolower(in_char)) { case 'a': hour_salary = FIRST_WAGE; break; case 'b': hour_salary = SECOND_WAGE; break; case 'c': hour_salary = THIRD_WAGE; break; case 'd': hour_salary = FOURTH_WAGE; break; case 'q': goto end; // 在case条件下无法break循环,又用了goto break; default: printf("Please re-enter the correct option.\n"); break; } while (getchar() != '\n') { ; } if (hour_salary) { printf("Please enter your working hours per week.\n"); if (scanf("%lf", &work_hour)) { if (work_hour > 40.0) { work_hour = (work_hour - 40) * 1.5 + 40;} salary = work_hour * hour_salary; if (salary <= 300.0) { tax = salary * 0.15; } else if (salary <= 450.0){ tax = TAX300 + (salary - 300) * 0.2; } else tax = TAX450 + (salary - 450) * 0.25; printf("Your all_salary is %.2f, tax is %.2f, net income is %.2f.\n", salary, tax, salary - tax); while (getchar() != '\n') { continue;; } } else printf("You have typed in the wrong information.\n"); } } else{ printf("Please re-enter the correct option.\n"); } } end: printf("Bye,Bye\n"); return 0; }
输出
*****************************************************************
Enter the number corresponding to the desired pay rate of action
a) $8.75/hr b) $9.33/hr
c) $10.00/hr d) $11.20/hr
q) quit
*****************************************************************
abc
Please enter your working hours per week.
40
Your all_salary is 350.00, tax is 55.00, net income is 295.00.
*****************************************************************
Enter the number corresponding to the desired pay rate of action
a) $8.75/hr b) $9.33/hr
c) $10.00/hr d) $11.20/hr
q) quit
*****************************************************************
bcd
Please enter your working hours per week.
40
Your all_salary is 373.20, tax is 59.64, net income is 313.56.
*****************************************************************
Enter the number corresponding to the desired pay rate of action
a) $8.75/hr b) $9.33/hr
c) $10.00/hr d) $11.20/hr
q) quit
*****************************************************************
q
Bye,Bye
Program ended with exit code: 0
第八题
#include <stdio.h> #include <ctype.h> float re_float(void); int main(void) { float num1, num2; char select_ch; while (1) { printf("Enter the operation of your choise:\n"); printf("a.add s.subtract\n"); printf("m.multiply d.divide\n"); printf("q.quit\n"); select_ch = getchar(); if (select_ch == 'q') { printf("Bye.\n"); break; } switch (select_ch) { case 'a': printf("Enter first number: "); num1 = re_float(); printf("Enter second number: "); num2 = re_float(); printf("%g + %g = %g\n", num1, num2, num1 + num2); break; case 's': printf("Enter first number: "); num1 = re_float(); printf("Enter second number: "); num2 = re_float(); printf("%g - %g = %g\n", num1, num2, num1 - num2); break; case 'm': printf("Enter first number: "); num1 = re_float(); printf("Enter second number: "); num2 = re_float(); printf("%g X %g = %g\n", num1, num2, num1 * num2); break; case 'd': printf("Enter first number: "); num1 = re_float(); printf("Enter second number: "); while ((num2 = re_float()) == 0) { printf("Enter a number other than 0: "); } printf("%g / %g = %g\n", num1, num2, num1 / num2); break; default: break; } } return 0; } // 必须要返回一个正确的浮点数 float re_float(void){ float num; char ch; // 处理输入不正确的时候 while (scanf("%f", &num) != 1) { while ((ch = getchar()) != '\n') { putchar(ch); } printf(" is not an number."); printf("Please enter a number, such as 2.5, -1.78E8, or 3: "); } while (getchar() != '\n') { continue;; } return num; }
输出
Enter the operation of your choise:
a.add s.subtract
m.multiply d.divide
q.quit
a
Enter first number: 22.4
Enter second number: one
one is not an number.Please enter a number, such as 2.5, -1.78E8, or 3: 1
22.4 + 1 = 23.4
Enter the operation of your choise:
a.add s.subtract
m.multiply d.divide
q.quit
d
Enter first number: 18.4
Enter second number: 0
Enter a number other than 0: 0.2
18.4 / 0.2 = 92
Enter the operation of your choise:
a.add s.subtract
m.multiply d.divide
q.quit
q
Bye.
Program ended with exit code: 0
浙公网安备 33010602011771号