getchar()/putchar()
getchar()函数不带任何参数,它从输入队列中返回下一个字符。
例如,下面的语句读取下一个字符输入,并把该字符的值赋给变量ch:
ch = getchar();
该语句与下面的语句效果相同:
scanf("%c", &ch);
putchar()函数打印它的参数。
例如,下面的语句把之前赋给ch的值作为字符打印出来:
putchar(ch);
该语句与下面的语句效果相同:
printf("%c", ch);
由于这些函数只处理字符,所以它们比更通用的scanf()和printf()函数更 快、更简洁。而且,注意 getchar()和 putchar()不需要转换说明,因为它们只处理字符。
ctype.h
//替换输入的字母,非字母字符保持不变
#include <stdio.h>
#include <ctype.h> // 包含isalpha()的函数原型
int main(void)
{
char ch;
while ((ch = getchar()) != '\n')
{
if (isalpha(ch)) // 如果是一个字符,
putchar(ch + 1); // 显示该字符的下一个字符
else // 否则,
putchar(ch); // 原样显示
}
putchar(ch); // 显示换行符
return 0;
}
/*
下面是该程序的一个输出示例,
注意大小写字母都被替换了,除了空格和标点符号:
Look! It's a programmer!
Mppl! Ju't b qsphsbnnfs!
*/
逻辑运算符
1、运算符
与 &&
或 ||
非 !
2、假设exp1和exp2是两个简单的关系表达式:
当且仅当exp1和exp2都为真时,exp1 && exp2才为真;
如果exp1或exp2为真,则exp1 || exp2为真;
如果exp1为假,则!exp1为真;如果exp1为真,则!exp1为假。
3、ios646.h头文件
与 and
或 or
非 not
4、注意书写格式:
//correct
if (range >= 90 && range <= 100)
//error
if (90 <= range <= 100)
举例:
// wordcnt.c -- 统计字符数、单词数、行数
#include <stdio.h>
#include <ctype.h> // 为isspace()函数提供原型
#include <stdbool.h> // 为bool、true、false提供定义
#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; // 如果c在单词中,inword 等于 true
printf("Enter text to be 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 = 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 be analyzed (| to terminate):
Reason is a
powerful servant but
an inadequate master .
|
characters = 55, words = 9, lines = 3, partial lines = 0
*/
条件运算符:?
x = (y < 0) ? -y : y;
在=和;之间的内容就是条件表达式,该语句的意思是:
“如果y小于0,那 么x = -y;否则,x = y”。
用if else可以这样表达:
if (y < 0)
x = -y;
else
x = y;
条件表达式的通用形式如下:
expression1 ? expression2 : expression3
//如果 expression1 为真(非 0),那么整个条件表达式的值与 expression2的值相同;
//如果expression1为假(0),那么整个条件表达式的值与expression3的值相同。
需要把两个值中的一个赋给变量时,就可以用条件表达式。
典型的例子是,把两个值中的最大值赋给变量:
max = (a > b) ? a : b;
//如果a大于b,那么将max设置为a;否则,设置为b。
通常,条件运算符完成的任务用 if else 语句也可以完成。
但是,使用条件运算符的代码更简洁,而且编译器可以生成更紧凑的程序代码。
continue
3种循环都可以使用continue语句。
执行到该语句时,会跳过本次迭代的剩余部分,并开始下一轮迭代。
如果continue语句在嵌套循环内,则只会影响包含该语句的内层循环。
break
程序执行到循环中的break语句时,会终止包含它的循环,并继续执行下一阶段。
如果break语句位于嵌套循环内,它只会影响包含它的当前循环。
switch
#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; type # to end my act.\n");
while ((ch = getchar()) != '#')
{
if ('\n' == ch)
continue;
if (islower(ch))
switch (ch)
{
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 mammal\n");
break;
case 'd':
printf("desman, aquatic, molelike critter\n");
break;
case 'e':
printf("echidna, the spiny anteater\n");
break;
case 'f':
printf("fisher, brownish marten\n");
break;
default:
printf("That's a stumper!\n");
}
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;
}
//假设用户一开始就按下Enter键,那么程序读到的首个字符就是换行 符。下面的代码处理这种情况:
if (ch == '\n')
continue;
switch (整型表达式)
{
case 常量1:
语句 <--可选
case 常量2:
语句 <--可选
default : <--可选
语句 <--可选
}
何时使用switch?何时使用if else?
你经常会别无选择。
如果是根据浮点类型的变量或表达式来选择,就无法使用 switch。
如果根据变量在某范围内决定程序流的去向,使用switch就很麻烦,这种情况用if就很方便。
goto
goto语句使程序控制跳转至相应标签语句。
冒号用于分隔标签和标签语句。
标签名遵循变量命名规则。
标签语句可以出现在goto的前面或后面。
形式:
goto label ;
label : statement
编程练习
1
编写一个程序读取输入,读到#字符停止,
然后报告读取的空格数、换行符数和所有其他字符的数量。
#include <stdio.h>
int main(void)
{
char ch;
printf("Please type in a letter; type # to end.\n");
int space_num = 0;
int n_num = 0;
int other = 0;
while ((ch = getchar()) != '#')
{
if ('\n' == ch)
n_num++;
else if (' ' == ch)
space_num++;
else
other++;
}
printf("spaces: %d, newlines: %d, others: %d \n",space_num,n_num,other);
return 0;
}
2
编写一个程序读取输入,读到#字符停止。
程序要打印每个输入的字符以及对应的ASCII码(十进制)。
一行打印8个字符。
建议:使用字符计数和求模运算符(%)在每8个循环周期时打印一个换行符。
#include <stdio.h>
int main(void)
{
char ch;
printf("Please type in a letter; type # to end.\n");
int num = 0;
while ((ch = getchar()) != '#')
{
printf("%c:%d ", ch, ch);
num++;
if (num % 8 == 0)
printf("\n");
}
return 0;
}
/*
Please type in a letter; type # to end.
abcdefghijklmnopqrstuvwxyz#
a:97 b:98 c:99 d:100 e:101 f:102 g:103 h:104
i:105 j:106 k:107 l:108 m:109 n:110 o:111 p:112
q:113 r:114 s:115 t:116 u:117 v:118 w:119 x:120
y:121 z:122
*/
3
编写一个程序,读取整数直到用户输入0。
输入结束后,程序应报告用户输入的偶数(不包括 0)个数、这些偶数的平均值、输入的奇数个数及其奇数的平均值。
//课后答案
#include <stdio.h>
int main(void)
{
int n;
double sumeven = 0.0;
int ct_even = 0;
double sumodd = 0.0;
int ct_odd = 0;
while (scanf("%d", &n) == 1 && n != 0)
{
if (n % 2 == 0)
{
sumeven += n;
++ct_even;
}
else // n % 2 is either 1 or -1
{
sumodd += n;
++ct_odd;
}
}
printf("Number of evens: %d", ct_even);
if (ct_even > 0)
printf(" average: %g", sumeven / ct_even);
putchar('\n');
printf("Number of odds: %d", ct_odd);
if (ct_odd > 0)
printf(" average: %g", sumodd / ct_odd);
putchar('\n');
printf("\ndone\n");
return 0;
}
4
使用if else语句编写一个程序读取输入,读到#停止。
用感叹号替换句号,用两个感叹号替换原来的感叹号,最后报告进行了多少次替换。
#include <stdio.h>
int main(void)
{
char ch;
int n = 0;
printf("please enter:");
while ((ch = getchar()) != '#')
{
if (ch == '.')
{
putchar('!'); //注意:not printf
n++;
}
else if (ch == '!')
{
putchar('!');
putchar('!');
n++;
}
else
{
putchar(ch);
}
}
printf("%d times\n", n);
return 0;
}
/*
please enter:1.2.3!!
1!2!3!!!!
*/
5
使用switch重写练习4。
#include <stdio.h>
int main(void)
{
char ch;
int n1 = 0;
int n2 = 0;
printf("please enter , enter # to quit:");
while ((ch = getchar()) != '#')
{
switch (ch)
{
case '.':
putchar('!');
n1++;
break;
case '!':
putchar('!');
putchar('!');
n2++;
break;
default:
putchar(ch);
}
}
printf("\n%d times\n", n1 + n2);
return 0;
}
/*
please enter , enter # to quit:1.2.3!!#
1!2!3!!!!
4 times
*/
6
编写程序读取输入,读到#停止,报告ei出现的次数。
注意
该程序要记录前一个字符和当前字符。
用“Receive your eieio award”这 样的输入来测试。
#include <stdio.h>
int main(void)
{
char ch;
int e = 0;
int n = 0;
printf("please enter , enter # to quit:");
while ((ch = getchar()) != '#')
{
if (ch == 'e')
e = 1;
else if ((ch == 'i') && (e = 1))
n++;
e = 0;
}
printf("\n%d times\n", n);
return 0;
}
/*
please enter , enter # to quit:Receive your eieio award#
3 times
please enter , enter # to quit:eieieieiei
5 times
*/
7
编写一个程序,提示用户输入一周工作的小时数,然后打印工资总额、税金和净收入。
做如下假设:
a.基本工资 = 1000美元/小时
b.加班(超过40小时) = 1.5倍的时间
c.税率: 前300美元为15%
续150美元为20%
余下的为25%
用#define定义符号常量。
不用在意是否符合当前的税法。
#include <stdio.h>
#define BT 40
#define BW 1000
#define OT 1.5
#define T1 0.15
#define T2 0.2
#define T3 0.25
#define A1 300
#define A2 150
int main(void)
{
float t;
float bw, tax, net;
printf("please enter your hours:");
scanf("%f", &t);
if (t > 0)
{
if (t <= BT)
bw = t * BW;
else
bw = BT * BW + (t - BT) * OT * BW;
if (bw < A1)
tax = bw * T1;
else if (bw > A1 && bw <= (A1 + A2))
tax = A1 * T1 + (bw - A1) * T2;
else
tax = A1 * T1 + A2 * T2 + (bw - A1 - A2) * T3;
net = bw - tax;
printf("Wage is %.2f Taxex is %.2f Net is %.2f\n", bw, tax, net);
}
else
printf("Your hours too short\n");
return 0;
}
/*
please enter your hours:30
Wage is 30000.00 Taxex is 7462.50 Net is 22537.50
please enter your hours:50
Wage is 55000.00 Taxex is 13712.50 Net is 41287.50
*/
8
修改练习7的假设a,让程序可以给出一个供选择的工资等级菜单。
使用switch完成工资等级选择。
运行程序后,显示的菜单应该类似这样:
Enter the number corresponding to the desired pay rate or action:
- $8.75/hr 2) $9.33/hr
- $10.00/hr 4) $11.20/hr
- quit
如果选择 1~4 其中的一个数字,程序应该询问用户工作的小时数。
程序要通过循环运行,除非用户输入5。
如果输入 1~5 以外的数字,程序应提醒用户输入正确的选项,然后再重复显示菜单提示用户输入。
使用#define创建符号常量表示各工资等级和税率。
#include <stdio.h>
#define BT 40
#define OT 1.5
#define T1 0.15
#define T2 0.2
#define T3 0.25
#define A1 300
#define A2 150
#define BW1 8.75
#define BW2 9.33
#define BW3 10.00
#define BW4 11.20
void menu();
int main(void)
{
int n;
float t;
float BW;
float bw, tax, net;
menu();
printf("Your choice:");
while (scanf("%d", &n) != 0)
{
if (n > 0 && n < 5)
{
switch (n)
{
case 1:
BW = BW1;
break;
case 2:
BW = BW2;
break;
case 3:
BW = BW3;
break;
case 4:
BW = BW4;
break;
}
printf("please enter your hours:");
scanf("%f", &t);
if (t > 0)
{
if (t <= BT)
bw = t * BW;
else
bw = BT * BW + (t - BT) * OT * BW;
if (bw < A1)
tax = bw * T1;
else if (bw > A1 && bw <= (A1 + A2))
tax = A1 * T1 + (bw - A1) * T2;
else
tax = A1 * T1 + A2 * T2 + (bw - A1 - A2) * T3;
net = bw - tax;
printf("Wage is %.2f Taxex is %.2f Net is %.2f\n", bw, tax, net);
}
else
printf("Your hours too short\n");
menu();
}
else if (n == 5)
break;
else
{
printf("Please re-enter!\n");
menu();
}
}
return 0;
}
void menu()
{
printf("Enter the number corresponding to the desired pay rate or action:\n");
printf("1) $8.75 / hr\n");
printf("2) $9.33 / hr\n");
printf("3) $10.00 / hr\n");
printf("4) $11.20 / hr\n");
printf("5) quit\n");
}
/*
Enter the number corresponding to the desired pay rate or action:
1) $8.75 / hr
2) $9.33 / hr
3) $10.00 / hr
4) $11.20 / hr
5) quit
Your choice:0
Please re-enter!
Enter the number corresponding to the desired pay rate or action:
1) $8.75 / hr
2) $9.33 / hr
3) $10.00 / hr
4) $11.20 / hr
5) quit
2
please enter your hours:50
Wage is 513.15 Taxex is 90.79 Net is 422.36
Enter the number corresponding to the desired pay rate or action:
1) $8.75 / hr
2) $9.33 / hr
3) $10.00 / hr
4) $11.20 / hr
5) quit
5
*/
9
编写一个程序,只接受正整数输入,然后显示所有小于或等于该数的素数。
习题答案:
链接:https://pan.baidu.com/s/1BoOvG7lHztEFGm3ypjgU7A 提取码:t6k0
#include <stdio.h>
#include <stdbool.h>
int main(void)
{
int limit;
int num;
int div;
bool numIsPrime; // use int if stdbool.h not available
printf("Enter a positive integer: ");
while (scanf("%d", &limit) == 1 && limit > 0)
{
if (limit > 1)
printf("Here are the prime numbers up through %d\n", limit);
else
printf("No primes.\n");
for (num = 2; num <= limit; num++)
{
for (div = 2, numIsPrime = true; (div * div) <= num; div++)
if (num % div == 0)
numIsPrime = false;
if (numIsPrime)
printf("%d is prime.\n", num);
}
printf("Enter a positive integer (q to quit): ");
}
printf("Done!\n");
return 0;
}
10
1988年的美国联邦税收计划是近代最简单的税收方案。
它分为4个类别,每个类别有两个等级。
下面是该税收计划的摘要(美元数为应征税的收入):
例如,一位工资为20000美元的单身纳税人,应缴纳税费0.15×17850+0.28×(20000−17850)美元。
编写一个程序,让用户指定缴纳税金的种类和应纳税收入,然后计算税金。
程序应通过循环让用户可以多次输入。
#include <stdio.h>
int menu()
{
int type;
printf("Types and Taxes:\n");
printf(" 1.single 17850.00\n");
printf(" 2.head 23900.00\n");
printf(" 3.married 29750.00\n");
printf(" 4.divorced 14875.00\n");
printf(" 5.exit\n");
printf("Please enter your type:\n");
scanf("%d", &type);
return type;
}
int main(void)
{
int type;
double B;
double wage;
double tax;
do
{
type = menu();
if (type == 5)
break;
switch (type)
{
case 1:
B = 17850.00;
break;
case 2:
B = 23900.00;
break;
case 3:
B = 29750.00;
break;
case 4:
B = 14875.00;
break;
}
printf("Please enter your wages:\n");
scanf("%lf", &wage);
if (wage > 0)
{
if (wage < B)
{
tax = wage * 0.15;
}
else
{
tax = B * 0.15 + (wage - B) * 0.28;
}
printf("Your taxes is %.2f\n", tax);
}
else
printf("error");
} while (1);
return 0;
}
/*
Types and Taxes:
1.single 17850.00
2.head 23900.00
3.married 29750.00
4.divorced 14875.00
5.exit
Please enter your type:
1
Please enter your wages:
50000
Your taxes is 11679.50
Types and Taxes:
1.single 17850.00
2.head 23900.00
3.married 29750.00
4.divorced 14875.00
5.exit
Please enter your type:
5
若要在调试停止时自动关闭控制台,请启用“工具”->“选项”->“调试”->“调试停止时自动关闭控制台”。
按任意键关闭此窗口...
*/
11
ABC邮购杂货店出售的洋蓟售价为 2.05 美元/磅,甜菜售价为 1.15 美元/磅,胡萝卜售价为 1.09美元/磅。
在添加运费之前,100美元的订单有 5%的打折优惠。
少于或等于5磅的订单收取6.5美元的运费和包装费,5磅~20磅的订单收取14美元的运费和包装费,超过20磅的订单在14美元的基础上每续重1磅增加0.5美元。
编写一个程序,在循环中用switch语句实现用户输入不同的字母时有不同的响应,即输入a的响应是让用户输入洋蓟的磅数,b 是甜菜的磅数,c是胡萝卜的磅数,q 是退出订购。
程序要记录累计的重量。
即,如果用户输入4 磅的甜菜,然后输入5磅的甜菜,程序应报告9磅的甜菜。
然后,该程序要计算货物总价、折扣(如果有的话)、运费和包装费。
随后,程序应显示所有的购买信息:物品售价、订购的重量(单位:磅)、订购的蔬菜费用、订单的总费用、折扣(如果有的话)、运费和包装费,以及所有的费用总额。
#include <stdio.h>
#include <string.h>
//洋蓟 artichokes
//甜菜 sugar beet
//胡萝卜 carrot
#define AP 2.05
#define SP 1.15
#define CP 1.09
void menu()
{
printf("What do you want:\n");
printf("a. artichokes\n");
printf("b. sugar beet\n");
printf("c. carrot\n");
printf("q. exit\n");
}
int main(void)
{
char ch;
float n;
float sum = 0;
float P;
float price;
float sum_price = 0;
float end_price;
float count = 0;
float fp; //运费包装费 freight and packing
float num[32];
float unit[32];
char type[32];
int i = 1;
menu();
printf("Please enter:");
scanf("%s", &ch);
if (ch != 'q' && ch != 'a' && ch != 'b' && ch != 'c')
{
printf("error\n\n");
menu();
printf("Please enter:");
scanf("%s", &ch);
}
while (ch != 'q')
{
switch (ch)
{
case 'a':
printf("How many pounds of artichokes do you need? ");
P = AP;
break;
case 'b':
printf("How many pounds of sugar beets do you need? ");
P = SP;
break;
case 'c':
printf("How many pounds of carrots do you need? ");
P = CP;
break;
}
scanf("%f", &n);
num[i] = n;
sum = sum + n;
price = n * P;
unit[i] = P;
type[i] = ch;
sum_price = sum_price + price;
i++;
menu();
printf("Please enter:");
scanf("%s", &ch);
}
if (ch == 'q')
{
if (sum_price >= 100)
{
count = 0.05;
}
if (sum <= 5)
{
fp = 6.5;
}
else if (sum > 5 && sum <= 20)
{
fp = 14;
}
else
{
fp = 14 + (sum - 20) * 0.5;
}
end_price = sum_price - sum_price * count + fp;
char ty[32] = "";
for (int k = 1; k <= i - 1; k++)
{
switch (type[k])
{
case 'a':
strcat(ty, "artichokes");
break;
case 'b':
strcat(ty, "sugar beet");
break;
case 'c':
strcat(ty, "carrot ");
break;
}
printf("类别 单价 重量 总计\n");
printf("%s %9.2f %15.2f %16.2f\n\n", ty,unit[k], num[k], unit[k] * num[k]);
memset(ty, 0, sizeof(ty)); //清空字符串
}
printf("总价 %.f\n\n", sum_price);
printf("折扣 运包费 总费用\n");
printf("%.2f %10.2f %10.2f\n", count, fp, end_price);
}
return 0;
}