1,if语句
-
/******************************************************************************** * @author: Mr.Y * @date: 2022/2/9 15:34 * @description: 统计温度低于0℃的百分比 ********************************************************************************/ #include <stdio.h> int main(void) { const int FREEZING = 0; float temperature; int cold_days = 0; //温度低于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) //判断温度是否低于0℃ 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; } /*** * output * Enter the list of daily low temperatures. * Use Celsius, and enter q to quit. * 12 5 -2.5 0 6 8 -3 -10 5 10 q * 10 days total: 30.0% were below freezing. */
-
if语句被称为分支语句(branching statement)或选择语句(selection statement)。if语句的通用形式如下:
-
if (expression) statement
-
-
如果对expression求值为真(非0),则执行statement;否则,跳过statement。statement可以是一条简单语句或复合语句。如下:
-
if (score > big) printf("Jackpot!\n"); //简单语句 if (joe > ron) { //复合语句 joecash++; printf("You lose, Ron.\n"); }
- 注意:即使if语句由复合语句构成,整个if语句仍被视为一条语句。
-
-
if语句和while语句的区别:
- 如果满足条件可执行的话,if语句只能测试和执行一次,而while语句可以测试和执行多次。
2,if else 语句
-
可以在两条语句之间作选择。
-
if else 格式
-
if (expression) statement1 else statement2
-
如果expression为真,则执行statement1;如果expression为假或0,则执行else后面的statement2。statement1和statement2可以是一条简单语句或复合语句。
-
-
例如上面的语句可修改为
-
if (all_days != 0) printf("%d days total: %.1f%% were below freezing.\n", all_days, 100.0 * (float) cold_days / all_days); else printf("No data entered!\n");
-
-
如果要在if和else之间执行多条语句,必须用花括号把这些语句括起来成为一个块。如下:
-
if (x > 0) { printf("Incrementing x:\n"); x++; } else printf("x <= 0 \n");
-
-
if else和if语句区别
- if语句用于选择是否执行一个行为,而if else语句用于在两个行为之间选择。
1,getchar()和putchar()
-
字符输入/输出函数。
-
getchar()
函数不带任何参数,它从输入队列中返回下一个字符。如下面的语句读取下一个字符输入,并把该字符的值赋给变量ch:-
ch = getchar(); //该语句与下面的语句效果相同 scanf("%c",&ch);
-
-
putchar()
函数打印它的参数。如下面的语句把之前赋给ch的值作为字符打印出来。-
putchar(ch); //该语句与下面的语句效果相同 printf("%c",ch);
-
-
/******************************************************************************** * @author: Mr.Y * @date: 2022/2/9 17:09 * @description: 更改输入,空格不变用户输入的字符后移一位,如输入abc,输出bcd。 ********************************************************************************/ #include <stdio.h> #define SPACE ' ' //SPACE表示单引号-空格-单引号 int main(void) { char ch; ch = getchar(); //读取一个字符 while (ch != '\n') //当一行未结束时 { if (ch == SPACE) //留下空格 putchar(ch); //该字符不变 else putchar(ch + 1); //改变其他字符 ch = getchar(); //获取下一个字符 } putchar(ch); //打印换行符 return 0; } /*** * output * abcd. * bcde/ */
- 上面程序中最后输入的点号(.)被转换成斜杠(/),这是因为斜杠字符对应的ASCII码比点号ASCII码多1。如何让程序只转换字母,保留所有的非字母字符(不只是空格)?解决方案ctype.h。
2,ctype.h系列字符函数
-
/******************************************************************************** * @author: Mr.Y * @date: 2022/2/9 18:04 * @description: 替换输入的字母,非字母字符保持不变 ********************************************************************************/ #include <stdio.h> #include <ctype.h> int main(void) { char ch; while ((ch = getchar()) != '\n') { if (isalpha(ch)) //如果是一个字符,isalpha()是ctype.h内的函数 putchar(ch + 1); //显示该字符的下一个字符 else putchar(ch); //原样显示 } putchar(ch); //显示换行符 return 0; } /*** * output * 注意大小写 * AbCd. * BcDe. */
-
ctype.h头文件中的字符测试函数
函数名 | 如果是下列函数时,返回值为真 |
---|---|
isalnum() | 字母数字(字母或数字) |
isalpha() | 字母 |
isblank() | 标准的空白字符(空格,水平制表符或换行符)或任何其他本地化指定为空白的字符 |
iscntrl() | 控制字符,如Ctrl+B |
isdigit() | 数字 |
isgraph() | 除空格外的任意可打印字符 |
islower() | 小写字母 |
isprint() | 可打印字符 |
ispunct() | 标点符号(除空格或字母数字字符以外的任何可打印字符) |
isspace() | 空白字符(空格,换行符,换页符,回车符,垂直制表符,水平制表符或其他本地化定义的字符) |
isupper() | 大写字母 |
isxdigit() | 十六进制数字符 |
- ctype.h头文件中的字符映射函数
函数名 | 行为 |
---|---|
tolower() | 如果参数是大写字符,该函数返回小写字符;否则,返回原始参数 |
toupper() | 如果参数是小写字符,该函数返回大写字符;否则,返回原始参数 |
3,多重选择else if
-
/******************************************************************************** * @author: Mr.Y * @date: 2022/2/13 16:45 * @description: 计算阶梯电费 ********************************************************************************/ #include <stdio.h> #define RATE1 0.13230 //首次使用360kwh的费率 #define RATE2 0.15040 //接着使用108kwh的费率 #define RATE3 0.30025 //接着再使用252kwh的费率 #define RATE4 0.34025 //使用超过720kwh的费率 #define BREAK1 360.0 //费率的第一个分界点 #define BREAK2 468.0 //费率的第二个分界点 #define BREAK3 720.0 //费率的第三个分界点 #define BASE1 (RATE1 * BREAK1) //使用360kwh的费用 #define BASE2 (BASE1 + (RATE2 * (BREAK2 - BREAK1))) //使用468kwh的费用 #define BASE3 (BASE2 + (RATE3 * (BREAK3 - BREAK2))) //使用720kwh的费用 int main(void) { double kwh; //使用的千瓦时 double bill; //电费 printf("Please enter the kwh used.\n"); scanf("%lf",&kwh); //%lf对应的double类型 if (kwh <= BREAK1) bill = RATE1 * kwh; else if (kwh <= BREAK2) //360~468kwh bill = BASE1 + (RATE2 * (kwh - BREAK1)); else if (kwh <= BREAK3) //468~720千瓦时 bill = BASE2 + (RATE3 * (kwh - BREAK2)); else //超过720kwh bill = BASE3 + (RATE4 * (kwh - BREAK3)); printf("The charge for %.1f kwh is $%1.2f.\n",kwh,bill); return 0; } /*** * output * Please enter the kwh used. * 580 * The charge for 580.0 kwh is $97.50. */
-
可以把多个
else if
语句连成一串使用。如下所示:-
if (soure < 10000) bouns = 0; else if (soure < 1500) bouns = 1; else if (soure < 2000) bouns = 2; else if (soure < 2500) bouns = 4; else bouns = 6; //对于编译器的限制范围,C99标准要求编译器最少支持127层套嵌。
-
4,else与if配对
-
如果程序中有多个if和else,编译器如何判断那个if对应那个else?如下:
-
if (number > 6) if (number < 12) printf("You're close!\n"); else printf("Sorry, you lose a turn!\n");
-
规则是,如果没有花括号,else与离它最近的if匹配,除非最近的if被花括号括起来。
-
3,逻辑运算符
1,3种逻辑运算符
-
逻辑运算符 含义 && 与 || 或 ! 非 -
假设exp1和exp2是两个简单的关系表达式,那么:
- 当且仅当exp1和exp2都为真时,
exp1 && exp2
才为真。 - 如果exp1或exp2为真,则
exp1 || exp2
为真。 - 如果exp1为假,则**!exp1为真;如果exp1为真,则!exp1**为假。
- 当且仅当exp1和exp2都为真时,
-
/******************************************************************************** * @author: Mr.Y * @date: 2022/2/14 20:49 * @description: 统计输入的字符数,包含空格 ********************************************************************************/ #include <stdio.h> #define PERIOD '.' int main(void) { char ch; int charcount = 0; while ((ch = getchar()) != PERIOD) { if (ch != '"' && ch != '\'') //使用&&判断是否满足两个条件 charcount++; } printf("There ard %d non-quote characters.\n",charcount); return 0; } /*** * output * 123456. * There ard 6 non-quote characters. */
-
逻辑运算符的优先级比关系运算符低。
2,iso646.h头文件
-
C99标准新增了可代替逻辑运算符的拼写,它们被定义在iso646.h头文件中。如果在程序中包含该头文件,便可使用and代替**&&,or代替||,not代替!**。使用此方法上述程序可改为。
-
/******************************************************************************** * @author: Mr.Y * @date: 2022/2/14 20:49 * @description: 统计输入的字符数,包含空格 ********************************************************************************/ #include <stdio.h> #include <iso646.h> #define PERIOD '.' int main(void) { char ch; int charcount = 0; while ((ch = getchar()) != PERIOD) { if (ch != '"' and ch != '\'') //使用&&判断是否满足两个条件 charcount++; } printf("There ard %d non-quote characters.\n",charcount); return 0; } /*** * output * 123456789. * There ard 9 non-quote characters. */
-
-
逻辑运算符的备选拼写
传统写法 iso646.h && and || or ! not
3,优先级
- **!运算符的优先级很高,比乘法运算符还高,与递增运算符的优先级相同,只比圆括号的优先级低。&&运算符的优先级比||**运算符高,但是两者的优先级都比关系运算符低,比赋值运算符高。
4,求值顺序
-
逻辑表达式的求值顺序是从左往右。一旦发现有使整个表达式为假的因素,立即停止求值。如下:
-
x != 0 && (20/x) < 5 //只有当x不等于0时,才会对第2个表达式求值。
-
5,范围
-
&&运算符可用于测试范围。如,要测试score是否在90~100的范围内,可以这样写:
-
if (range >= 90 && range <= 100)
-
-
不要模仿数学上的写法:
-
if (90 <= tange <= 100)
-
这样写的问题是代码有语义错误,而不是语法错误,由于<=运算符的求值顺序是从左往右,所以编译器把测试表达式解释为:
(90 <= range) <= 100
。子表达式90 <= range
的值要么是1(为真),要么是0(为假)。这两个值都小于100,所以不管range的值是多少,整个表达式都恒为真。
-
4,条件运算符:?:
-
C提供条件表达式作为表达if else语句的一种便捷方式,该表达式使用**?:条件运算符。该运算符分为两部分,需要3个运算对象,称为三元运算符**,条件运算符是C语言中唯一的三元运算符。下面的代码得到一个数的绝对值:
-
x = (y < 0) ? -y : y;
-
在 = 和 ; 之间的内容就是条件表达式,该语句的意思是”如果y小于0,那么x = -y;否则,x = y“。用if else可以这样表达:
-
if ( y < 0) x = -y; else x = y;
-
-
5,循环辅助:continue和break
- 程序进入循环后,在下一次循环测试之前会执行完循环体中的所有语句。continue和break语句可以根据循环体中的测试结果来忽略一部分循环内容,甚至结束循环。
1,continue语句
-
执行到该语句时,会跳过本次迭代的剩余部分,并开始下一轮迭代。如果continue语句在嵌套循环内,则只会影响包含该语句的内层循环。
-
/******************************************************************************** * @author: Mr.Y * @date: 2022/2/19 17:46 * @description: 使用continue跳过部分循环 ********************************************************************************/ #include <stdio.h> int main(void) { const float MIN = 0.0f; const float MAX = 100.0f; float score; float total = 0.0f; int n = 0; float min = MAX; float max = MAX; printf("Enter the first score (q to quit): "); while (scanf("%f",&score) == 1) { if (score < MIN || score > MAX) { printf("%0.1f is an invalid value. Try again: ",score); continue; //跳转至while循环的测试条件 } printf("Accepting %0.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 %0.1f.\n",n,total / n); printf("Low = %0.1f,high = 0.1f\n",min,max); } else printf("No valid scores were entered.\n"); return 0; } /*** * output * Enter the first score (q to quit):55 * Accepting 55.0: * Enter next score (q to quit):0.1 * Accepting 0.1: * Enter next score (q to quit):-1 * -1.0 is an invalid value. Try again:10 * Accepting 10.0: * Enter next score (q to quit):q * Average of 3 scores is 21.7. * Low = 0.1,high = 0.1f */
-
有两种方法可以避免使用continue,一是省略continue,把剩余部分放在一个else块中:
-
if (score < 0 || score > 100) /*printf()语句*/ else { /*语句*/ }
-
if (score >= 0 && score <= 100) { /*语句*/ }
-
2,break语句
-
程序执行到循环中的break语句时,会终止包含它的循环,并继续执行下一阶段。如果break语句位于嵌套循环内,它只会影响包含它的当前循环。
-
/******************************************************************************** * @author: Mr.Y * @date: 2022/2/20 16:19 * @description: 使用break跳过循环 ********************************************************************************/ #include <stdio.h> int main(void) { const float MIN = 0.0f; const float MAX = 100.0f; float score; float total = 0.0f; int n = 0; float min = MAX; float max = MAX; printf("Enter the first score (q to quit): "); while (scanf("%f",&score) == 1) { if (score < MIN || score > MAX) { printf("%0.1f is an invalid value. Try again: ",score); break; } printf("Accepting %0.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 %0.1f.\n",n,total / n); printf("Low = %0.1f,high = 0.1f\n",min,max); } else printf("No valid scores were entered.\n"); return 0; } /*** * output * Enter the first score (q to quit):12 * Accepting 12.0: * Enter next score (q to quit):14 * Accepting 14.0: * Enter next score (q to quit):a * Average of 2 scores is 13.0. * Low = 12.0,high = 0.1f */
-
在for循环中的break和continue的情况不同,执行完break语句后会直接执行循环后面的第一条语句,连更新部分也跳过。嵌套循环内层的break只会让程序跳出包含它的当前循环,要跳出外层循环还需要一个break。
-
int p,q; scanf("%d",&p); while (p > 0) { printf("%d\n",p); scanf("%d",&q); while (q > 0) { printf("%d\n",P*q); if(q > 100) break; //跳出内层循环 scanf("%d",&q); } if(q > 100) break; //跳出外层循环 scanf("%d",&p); }
-
6,多重选择:switch和break
-
/******************************************************************************** * @author: Mr.Y * @date: 2022/2/20 16:56 * @description: 使用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; } /*** * output * Give me a letter of the alphabet, and I will givean animal name * beginning with that letter. * Please type in a letter; type # to end my act. * a * argali, a wild sheep of Asia * Please type another letter or a #. * b * babirusa, a wild pig of Malay * Please type another letter or a #. * c * coati, racoonlike mammal * Please type another letter or a #. * d * desman, aquatic, molelike critter * Please type another letter or a #. * e * echidna, the spiny anteater * Please type another letter or a #. * f * fisher, brownish marten * Please type another letter or a #. * g * That's a stumper! * Please type another letter or a #. * 1 * I recognize only lowercase letters. * Please type another letter or a #. * q * That's a stumper! * Please type another letter or a #. * # * Bye! */
-
break语句可用于循环和switch语句,但是continue只能用于循环中。
-
switch语句构造
-
switch (整型表达式) { case 常量1: 语句 case 常量2: 语句 default : 语句 }
-
7,goto语句
- 早期版本的BASIC和FORTRAN所依赖的goto语句,在C中仍然可用。没有goto语句C程序也能运行良好。C中建议”谨慎使用,或者根本不用“。