2022-11-11

条件运算符:?:

条件运算符。 该运算符分为两部分, 需要 3 个运算对象。 带一个运算对象的运算符称为一元运算符, 带两个运算对象的运算符称为二元运算符。 以此类推, 带 3 个运算对象的运算符称为三元运算符。 条件运算符是C语言中唯一的三元运算符。

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。

该程序使用的变量都是int类型, 除法的计算结果(sq_feet /COVERAGE) 会被截断。

小结: 条件运算符

条件运算符: ?:

一般注解:

条件运算符需要3个运算对象, 每个运算对象都是一个表达式。

循环辅助: continue和break

程序进入循环后, 在下一次循环测试之前会执行完循环体中的所有语句。 continue 和break语句可以根据循环体中的测试结果来忽略一部分循环内容, 甚至结束循环。

continue语句

3种循环都可以使用continue语句。 执行到该语句时, 会跳过本次迭代的剩余部分, 并开始下一轮迭代。 如果continue语句在嵌套循环内, 则只会影响包含该语句的内层循环。

while循环读取输入, 直至用户输入非数值数据。 循环中的if语句筛选出无效的分数。

有两种方法可以避免使用continue, 一是省略continue, 把剩余部分放在一个else块中:

if (score < 0 || score > 100)

/* printf()语句 */

else

/*语句*/

另一种方法是, 用以下格式来代替:

if (score >= 0 && score <= 100)

{

 /*语句 */

使用continue的好处是减少主语句组中的一级缩进。 当语句很长或嵌套较多时, 紧凑简洁的格式提高了代码的可读性。

continue还可用作占位符。 循环读取并丢弃输入的数据,直至读到行末尾:while (getchar() != '\n');

对于while和 do while 循环, 执行 continue 语句后的下一个行为是对循环的测试表达式求值。

count = 0;

while (count < 10)

ch = getchar();

if (ch == '\n')

continue;

putchar(ch);

count++;

}

该循环读取10个字符(除换行符外, 因为当ch是换行符时, 程序会跳过count++;语句) 并重新显示它们, 其中不包括换行符。 执行continue后, 下一个被求值的表达式是循环测试条件

对于for循环, 执行continue后的下一个行为是对更新表达式求值, 然后是对循环测试表达式求值。

break语句

程序执行到循环中的break语句时, 会终止包含它的循环, 并继续执行下一阶段。break和continue。如果break语句位于嵌套循环内, 它只会影响包含它的当前循环。

break还可用于因其他原因退出循环的情况。

在for循环中的break和continue的情况不同, 执行完break语句后会直接执行循环后面的第1条语句, 连更新部分也跳过。 嵌套循环内层的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);

}

多重选择:switch和break

switch语句

要对紧跟在关键字 switch 后圆括号中的表达式求值。表达式是刚输入给 ch的值。 然后程序扫描标签(这里指, case 'a' :、case 'b' :等) 列表, 直到发现一个匹配的值为止。 然后程序跳转至那一行。如果有default :标签行, 就跳转至该行; 否则, 程序继续执行在switch后面的语句。

break语句让程序离开switch语句, 跳至switch语句后面的下一条语句如果没有break语句, 就会从匹配标签开始执行到switch末尾。

break语句可用于循环和switch语句中, 但是continue只能用于循环中。 尽管如此, 如果switch语句在一个循环中, continue便可作为switch语句的一部分。 这种情况下, 就像在其他循环中一样, continue让程序跳出循环的剩余部分, 包括switch语句的其他部分。C语言的case一般都指定一个值, 不能使用一个范围。

switch在圆括号中的测试表达式的值应该是一个整数值(包括char类型) 。 case标签必须是整数类型(包括char类型) 的常量或整型常量表达式(即, 表达式中只包含整型常量) 。 不能用变量作为case标签。

只读每行的首字符

animals.c的另一个独特之处是它读取输入的方式。当输入dab时, 只处理了第1个字符。 这种丢弃一行中其他字符的行为, 经常出现在响应单字符的交互程序中。

while (getchar() != '\n')

continue; /* 跳过输入行的其余部分 */

循环从输入中读取字符, 包括按下Enter键产生的换行符。 注意, 函数的返回值并没有赋给ch, 以上代码所做的只是读取并丢弃字符。 由于最后丢弃的字符是换行符, 所以下一个被读取的字符是下一行的首字母。 在外层的while循环中, getchar()读取首字母并赋给ch。

多重标签

如果ch是字母i, switch语句会定位到标签为case 'i' :的位置。 由于该标签没有关联break语句, 所以程序流直接执行下一条语句, 即i_ct++;。如果 ch是字母I, 程序流会直接定位到case 'I' :。 本质上, 两个标签都指的是相同的语句。

严格地说, case 'U'的 break 语句并不需要。 因为即使删除这条 break 语句, 程序流会接着执行switch中的下一条语句, 即default : break;。 所以, 可以把case 'U'的break语句去掉以缩短代码。 但是从另一方面看, 保留这条break语句可以防止以后在添加新的case(例如, 把y作为元音) 时遗漏break语句

如果使用ctype.h系列的toupper()函数可以避免使用多重标签, 在进行测试之前就把字母转换成大写字母


小结: 带多重选择的switch语句

关键字: switch

程序根据expression的值跳转至相应的case标签处。 然后, 执行剩下的所

有语句, 除非执行到break语句进行重定向。 expression和case标签都必须是整数值(包括char类型) , 标签必须是常量或完全由常量组成的表达式。 如果没有case标签与expression的值匹配, 控制则转至标有default的语句(如果有的话) ; 否则, 将转至执行紧跟在switch语句后面的语句。

switch和if else

何时使用switch? 何时使用if else?如果是根据浮点类型的变量或表达式来选择, 就无法使用 switch。 如果根据变量在某范围内决定程序流的去向, 使用 switch 就很麻烦, 这种情况用if就很方便:

if (integer < 1000 && integer > 2)

使用switch要涵盖以上范围, 需要为每个整数(3~999) 设置case标签。 但是, 如果使用switch, 程序通常运行快一些, 生成的代码少一些。

goto语句

goto语句有两部分: goto和标签名。 标签的命名遵循变量命名规则,

goto part2;

要让这条语句正常工作, 函数还必须包含另一条标为part2的语句, 该语句以标签名后紧跟一个冒号开始:

part2: printf("Refined analysis:\n");

避免使用goto

goto的常见情况

处理包含多条语句的if语句:

if (size > 12)

goto a;

goto b;

a: cost = cost * 1.05;

flag = 2;

b: bill = cost * flag;

转换成等价的C代码, 标准C用复合语句或块来处理这种情况

if (size > 12)

cost = cost * 1.05;

flag = 2;

bill = cost * flag;

C通过if else表达二选一更清楚:

if (ibex > 14)

sheds = 3;

else

sheds = 2;

help = 2 * sheds;

创建不确定循环:

readin: scanf("%d", &score);

if (score < O)

goto stage2;

lots of statements

goto readin;

stage2: more stuff;

C用while循环代替:

scanf("%d", &score);

while (score <= 0)

lots of statements

scanf("%d", &score);

more stuff;


跳转至循环末尾, 并开始下一轮迭代。 C使用continue语句代替。

跳出循环。 C使用break语句。 实际上, break和continue是goto的特殊形式。 使用break和 continue 的好处是: 其名称已经表明它们的用法, 而且这些语句不使用标签, 所以不用担心把标签放错位置导致的危险。

小结: 程序跳转

关键字: break、 continue、 goto

这3种语句都能使程序流从程序的一处跳转至另一处。

break语句:

所有的循环和switch语句都可以使用break语句。 它使程序控制跳出当前循环或switch语句的剩余部分, 并继续执行跟在循环或switch后面的语句。

switch (number)

case 4: printf("That's a good choice.\n");

break;

case 5: printf("That's a fair choice.\n");

break;

default: printf("That's a poor choice.\n");

}

continue语句:

所有的循环都可以使用continue语句, 但是switch语句不行。 continue语句使程序控制跳出循环的剩余部分。 对于while或for循环, 程序执行到continue语句后会开始进入下一轮迭代。 对于do while循环, 对出口条件求值后, 如有必要会进入下一轮迭代。

goto语句:

goto语句使程序控制跳转至相应标签语句。 冒号用于分隔标签和标签语句。 标签名遵循变量命名规则。 标签语句可以出现在goto的前面或后面。

关键概念

C语言通过if、 if else和switch语句, 以及条件运算符(?:) 可以实现智能选择。

if 和 if else 语句使用测试条件来判断执行哪些语句。 所有非零值都被视为 true, 零被视为false。 测试通常涉及关系表达式(比较两个值) 、 逻辑表达式(用逻辑运算符组合或更改其他表达式) 。

如果要测试两个条件, 应该使用逻辑运算符把两个完整的测试表达式组合起来。

本章小结

if语句使用测试条件控制程序是否执行测试条件后面的一条简单语句或复合语句。 如果测试表达式的值是非零值, 则执行语句; 如果测试表达式的值是零, 则不执行语句。 if else语句可用于二选一的情况。 如果测试条件是非零, 则执行else前面的语句; 如果测试表达式的值是零, 则执行else后面的语句。 在else后面使用另一个if语句形成else if, 可构造多选一的结构。

测试条件通常都是关系表达式, 即用一个关系运算符(如, <或==) 的表达式。 使用C的逻辑运算符, 可以把关系表达式组合成更复杂的测试条件

在多数情况下, 用条件运算符(?:) 写成的表达式比if else语句更简洁。

ctype.h系列的字符函数(如, issapce()和isalpha()) 为创建以分类字符为基础的测试表达式提供了便捷的工具。switch 语句可以在一系列以整数作为标签的语句中进行选择。 如果紧跟在 switch 关键字后的测试条件的整数值与某标签匹配, 程序就转至执行匹配的标签语句, 然后在遇到break之前, 继续执行标签语句后面的语句

break、 continue和goto语句都是跳转语句, 使程序流跳转至程序的另一处。 break语句使程序跳转至紧跟在包含break语句的循环或switch末尾的下一条语句。 continue语句使程序跳出当前循环的剩余部分, 并开始下一轮迭代。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,133评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,682评论 3 390
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,784评论 0 350
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,508评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,603评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,607评论 1 293
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,604评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,359评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,805评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,121评论 2 330
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,280评论 1 344
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,959评论 5 339
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,588评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,206评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,442评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,193评论 2 367
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,144评论 2 352

推荐阅读更多精彩内容