1、逻辑思维与逻辑问题逻辑思维与逻辑问题-逻辑运算、循环逻辑运算、循环何谓逻辑运算何谓逻辑运算?A和B中至少有一个大于 CA和B全部大于 CA为不大于100的偶数如何用C语言描述关系运算是一种比较运算,将两个值(表达式)进行比较,判断比较的结果是否符合给定的条件。逻辑运算?何谓逻辑运算何谓逻辑运算?用逻辑运算符将关系运算表达式或逻辑量连接起来构成逻辑表达式l回顾:符合下列条件之一都为闰年回顾:符合下列条件之一都为闰年1 1、能被能被400400整除(整除(year%400=0year%400=0)2 2、能被能被4 4整除但不能整除但不能100100整除整除也可通过逻辑运算符将几个条也可通过逻辑运
2、算符将几个条件整合起来件整合起来第 4 页逻辑运算逻辑运算数学式子数学式子:x10 x0 x0如何写为如何写为C C语言语句语言语句?数学式子的英文表达:x0因此,C语言约定了语句:x0 注意:用了二个&而 and 和&作用相同【任务任务3.33.3】猜比赛结果猜比赛结果 l一天,湘潭大学一天,湘潭大学ACM/ICPCACM/ICPC队的四支候选队展队的四支候选队展开比赛。比赛完,开比赛。比赛完,4 4名队长问教练名队长问教练EricEric最后比最后比赛谁赢了。赛谁赢了。EricEric让他们猜:让他们猜:nA A说:说:“不是我们队,也不是不是我们队,也不是C C队。队。”nB B说:说:
3、“是我们或者是我们或者D D队。队。”nC C说:说:“是是A A队,不是队,不是B B队。队。”nD D说:说:“B B猜错了。猜错了。”EricEric说只有一个人猜对了,请问最后是谁赢说只有一个人猜对了,请问最后是谁赢得了比赛?得了比赛?逻辑运算与逻辑表达式逻辑运算与逻辑表达式 说话人说的话写成关系表达式A“不是我们队”winner!=A“不是C队”winner!=CB“是我们”winner=B“是D队”winner=DC“是A”winner=A“不是B”winner!=Bl每个子句之间的关系和每个子句之间的关系和D D所说的话,我们没有所说的话,我们没有办法用已学的知识进行处理。在这里
4、我们要办法用已学的知识进行处理。在这里我们要引入一个新的计算引入一个新的计算逻辑运算。逻辑运算。逻辑运算逻辑运算l 逻辑与逻辑与n&na&ba&bua a与与b b往往是关系表达式,往往是关系表达式,a a与与b b同时为真,则表达式为真,否则为同时为真,则表达式为真,否则为假假A0011B0101A&B0001逻辑运算逻辑运算l 逻辑或逻辑或n|na|ba|bua a与与b b只要有只要有1 1个为真,则表达式为真,否则为假个为真,则表达式为真,否则为假A0011B0101A|B0111逻辑运算逻辑运算l 逻辑非逻辑非n!n!a a ua a为假,则表达式为真,否则为假为假,则表达式为真,否
5、则为假A01!A10l优先级上!最高,优先级上!最高,&比比|高高l不记得就全部打上括号不记得就全部打上括号使用逻辑表达式表示使用逻辑表达式表示4 4个人说的话个人说的话说话人说的话写成逻辑表达式A“不是我们队,也不是C队。”winner!=A&winner!=CB“是我们或者D队”winner=B|winner=DC“是A,不是B队”winner=A&winner!=BD“B猜错了。”!(winner=B|winner=D)枚举法的思路枚举法的思路 l分析任务分析任务4-34-3,我们可以依次假设,我们可以依次假设A A,B B,C C,D D为为winnerwinner,l然后测试然后测试
6、A A,B B,C C,D D所说的所说的4 4句话,看是否满句话,看是否满足足“只有一个人猜对了只有一个人猜对了”的条件,即只有一的条件,即只有一句话的逻辑表达式结果为真的。句话的逻辑表达式结果为真的。l如果满足,则我们的假设成立,否则我们的如果满足,则我们的假设成立,否则我们的假设错误。假设错误。l枚举法,又叫穷举法,即把所有可能的情况枚举法,又叫穷举法,即把所有可能的情况都进行一次计算,最后得到整个问题的计算都进行一次计算,最后得到整个问题的计算结果。结果。状态赋值表达式1winner=A2winner=B3winner=C4winner=Dl“只有一个人猜对只有一个人猜对”等价于只有一
7、句话的逻等价于只有一句话的逻辑表示式结果为真,那么我们可以将这辑表示式结果为真,那么我们可以将这4 4句话句话的逻辑结果累加,如果结果为的逻辑结果累加,如果结果为1 1,则表明只有,则表明只有一句话的逻辑结果为真。一句话的逻辑结果为真。winner=winner=A A说话人说的话代入逻辑表达式值Awinner!=A&winner!=CA!=A&A!=C0Bwinner=B|winner=DA=B|A=D0Cwinner=A&winner!=BA=A&A!=B1D!(winner=B|winner=D)!(A=B|A=D)1winner=winner=B B说话人说的话代入逻辑表达式值Awin
8、ner!=A&winner!=CB!=A&B!=C1Bwinner=B|winner=DB=B|B=D1Cwinner=A&winner!=BB=A&B!=B0D!(winner=B|winner=D)!(B=B|B=D)0说话人说的话代入逻辑表达式值Awinner!=A&winner!=CC!=A&C!=C0Bwinner=B|winner=DC=B|C=D0Cwinner=A&winner!=BC=A&C!=B0D!(winner=B|winner=D)!(C=B|C=D)1winner=winner=C Cl笨笨的写法笨笨的写法l如果题目有如果题目有100100人怎么办?人怎么办?l这么
9、写太麻烦了,也没有必要。这么写太麻烦了,也没有必要。n每次的测试计算是一样,只是每次的测试计算是一样,只是winnerwinner的值不一样的值不一样n我们需要依次遍历我们需要依次遍历winnerwinner的可能状态,即一个一的可能状态,即一个一个测试个测试循环结构循环结构 l循环结构是计算机程序中最常用的结构,它循环结构是计算机程序中最常用的结构,它能充分地利用计算机上擅长做重复运算的特能充分地利用计算机上擅长做重复运算的特点。点。lC C语言中可以使用语言中可以使用forfor语句,语句,whilewhile语句和语句和do-do-whilewhile语句实现循环结构,语句实现循环结构,
10、l其中其中forfor是用得最多,也是最灵活的一种是用得最多,也是最灵活的一种 for for语句语句 for(for(表达式表达式1;1;表达式表达式2;2;表达式表达式3)3)循环体(语句组);循环体(语句组);nforfor语句中表达式语句中表达式1 1,2 2,3 3都可以都可以缺省缺省n但括号中的但括号中的“;”不能缺少。不能缺少。n表达式表达式2 2缺省时,那么循环判断缺省时,那么循环判断结束条件为永真。结束条件为永真。使用使用forfor循环解题的实例循环解题的实例 l(1)(1)输入输入n n个整数,求这个个整数,求这个n n个整数的累加和。个整数的累加和。一共输入一共输入n+
11、1n+1个整数,第一个整数为个整数,第一个整数为n n。l求求n n(n0n0)个自然数中最大的一个。一共输)个自然数中最大的一个。一共输入入n+1n+1个自然数,第一个整数为个自然数,第一个整数为n n。解决任务4-3 循环程序设计循环程序设计练习练习1 1l求求100100以内的奇数、偶数之和以内的奇数、偶数之和l1 1、需要用到的变量需要用到的变量:i i被判断的数被判断的数=100=100sdsd:用于存放奇数的和用于存放奇数的和,se:,se:用于存放偶数的和用于存放偶数的和l2 2、如何判断奇数和偶数?如何判断奇数和偶数?l3 3、哪些内容要作为循环体?哪些内容要作为循环体?l4
12、4、有无要从键盘输入的数?输出什么数?有无要从键盘输入的数?输出什么数?循环程序设计循环程序设计练习练习2 2l输出一行字母,所输出的字母和个数从键盘输出一行字母,所输出的字母和个数从键盘输入输入例如:例如:输入:输入:C C,5 5 则输出:则输出:CCCCCCCCCC输出一行字母输出一行字母1 1、需要的变量:需要的变量:ch-ch-存放字母、存放字母、n-n-字母的个字母的个数、数、i-i-循环控制变量循环控制变量2 2、循环体的内容?循环体的内容?3 3、如果是输出一行数字?如果是输出一行数字?循环嵌套循环嵌套l如何输出一数字正方形?如何输出一数字正方形?111111111122222
13、22222333333333344444444445555555555需要重复执行练习需要重复执行练习2中的循环中的循环即循环嵌套即循环嵌套循环嵌套循环嵌套l一个循环体内包含着另一个一个循环体内包含着另一个完整完整的循环结构的循环结构,就称为循环嵌套。,就称为循环嵌套。l内嵌的循环中又可以嵌套循环,从而构成多内嵌的循环中又可以嵌套循环,从而构成多重循环重循环嵌嵌嵌套嵌套 for for 循环循环套循环套循环如果一个如果一个forfor循环出现在另一个循环出现在另一个forfor循环中,则循环中,则称它为嵌套循环称它为嵌套循环for(i=1;imax1;i+)for(j=0;j =max2;j+
14、)外层循环内层循环嵌套的循环控制变量不能相同内循环变化快,外循环变化慢循环嵌套循环嵌套举例举例l1 1、数字塔(数字塔(P50-3.8)P50-3.8)l2 2、九九乘法表九九乘法表1 1*1=11=12 2*1=2 21=2 2*2=42=43 3*1=3 31=3 3*2=6 32=6 3*3=93=9:9 9*1=9 91=9 9*2=18 92=18 9*3=27 93=27 9*9=819=81循环结构的循环结构的 3 3 种类型种类型for 循环while 循环do.while 循环whilewhile语句语句 while(while(表达式表达式)循环体(语句块);循环体(语句块
15、);l 为了使循环测试表达式为假,为了使循环测试表达式为假,使得循环结束,那么在循环使得循环结束,那么在循环体中,必须修改表达式中的体中,必须修改表达式中的一些变量的值,使得循环有一些变量的值,使得循环有结束的可能,否则就会出现结束的可能,否则就会出现死循环。死循环。while while 语句和语句和forfor语句语句都是在循环前先判断条件都是在循环前先判断条件while 语句说明语句说明表达式1;while(表达式2)for的循环体语句;表达式3;把for语句改写成while语句for(表达式1;表达式2;表达式3)循环体语句while 和和 for 的比较的比较for(for(i=1i
16、=1;i=10i=10;i+i+)sum=sum+isum=sum+i;i=1;循环变量赋初值while(i=10)循环条件 sum=sum+i;i+;循环变量的改变循环体dodo 循环体(语句块);循环体(语句块);while(while(表达式表达式);l 与与whilewhile不同的是,不同的是,do-do-whilewhile是先执行一次循环体,是先执行一次循环体,再进行循环结束测试,所以再进行循环结束测试,所以它至少会执行一次循环体。它至少会执行一次循环体。与while不同的是,do-while是先执行一次循环体,再进行循环结束测试,所以它至少会执行一次循环体。void main(
17、)void main()int count,number;int count,number;count=0;count=0;printf(Input a number:);printf(Input a number:);scanf(%d,&number);scanf(%d,&number);if(number 0)number=-number;if(number 0)number=-number;dodo number=number/10;number=number/10;count+;count+;while(number!=0);while(number!=0);printf(It con
18、tains%d digits.n,printf(It contains%d digits.n,count);count);程序解析统计一个整数的位数程序解析统计一个整数的位数Input a number:12534It contains 5 digits.Input a number:-99It contains 2 digits.Input a number:0It contains 1 digits.while(number!=0)number=number/10;count+;l while while 是先判别条件,再决定是否循环;是先判别条件,再决定是否循环;l do-while d
19、o-while 是先至少循环一次,然后再根据是先至少循环一次,然后再根据循环的结果决定是否继续循环。循环的结果决定是否继续循环。while 和和 do-while 的比较的比较真假表达式循环体语句do-while的下一条语句循环体语句真假while的下一条语句表达式循环体语句例例:斐波拉挈数列斐波拉挈数列题目:古典问题:有一对兔子,从出生后第题目:古典问题:有一对兔子,从出生后第3个月起个月起每个月都生一对兔子,小兔子长到第三个月后每个每个月都生一对兔子,小兔子长到第三个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少?子总数为多少?
20、1.程序分析:兔子的规律为数列程序分析:兔子的规律为数列1,1,2,3,5,8,13,21.2.程序源代码:程序源代码:void main()long f1,f2;/定义变量定义变量int i;f1=f2=1;/给变量赋值给变量赋值for(i=1;i=20;i+)/for循环结构循环结构 printf(“%12ld%12ld”,f1,f2);/输出变量输出变量f1,f2的值的值.if(i%2=0)printf(n);/*控制输出,每行四个控制输出,每行四个*/f1=f1+f2;/*前两个月加起来赋值给第三个月前两个月加起来赋值给第三个月*/f2=f1+f2;/*前两个月加起来赋值给第三个月前两
21、个月加起来赋值给第三个月*/求求的近似值的近似值使用格里高利公式求使用格里高利公式求的近似值,要求精确到的近似值,要求精确到最后一项的绝对值小于最后一项的绝对值小于101055。11114357#include#include void main()void main()int flag,t;int flag,t;double item,pi;double item,pi;flag=1;flag=1;t=1;item=1.0;t=1;item=1.0;pi=0;pi=0;while(fabs(item)=0.00001)while(fabs(item)=0.00001)item=flag it
22、em=flag*1.0/t;1.0/t;pi=pi+item;pi=pi+item;flag=-flag;flag=-flag;t=t+2;t=t+2;pi=pi pi=pi*4;4;printf(“pi=%fn”,pi);printf(“pi=%fn”,pi);程序解析求程序解析求的近似值的近似值pi=3.141613 item=0.0?fabs(item)0.00001break break 语句语句l用用breakbreak语句可以结束语句可以结束switchswitch结构和循环。结构和循环。#include /头文件main()int a,b;/定义变量for(a=1,b=0;a=1
23、00;a+)/for循环/循环体printf(“Enter%d b:”,a);scanf(%d,&b);if(b=100)break;/当b的值为100时,循环终止 Break语句强行结束循环,转向执行循环语句下面的语句。跳转语句跳转语句 =continue 语句让封闭循环进行下一次迭代遇到该语句时,跳过循环体中剩余的语句,控制权传递给下一次循环在while循环和dowhile循环中,程序控制权传递给条件测试语句在for循环中,continue影响循环的增量部分,然后执行条件测试continue通用语法:可以结束本次循环,即忽略循环体中剩余的语句。continue continue 语句语句#
24、include /头文件头文件main()int num;/定义变量定义变量for(num=1;num=100;num+)/for循环循环/循环体循环体if(num%9=0)/判断是否是判断是否是9的倍数的倍数continue;/跳过本次循环执行下次循跳过本次循环执行下次循环环printf(“%dt”,num);/不是不是9的倍数则输出的倍数则输出 打印1-100之间不能被整除的数【任务任务3-43-4】丑数丑数l当一个自然数只含有质因子当一个自然数只含有质因子2 2,3 3,5 5,7 7的时的时候,我们称这个数为丑数。现在给你一个自候,我们称这个数为丑数。现在给你一个自然数,请判断这个数是
25、否是丑数。然数,请判断这个数是否是丑数。解题思路解题思路l(1)(1)枚举测试枚举测试2 2到到7 7的因子,如果为的因子,如果为4 4和和6 6就跳就跳过测试;过测试;l(2)(2)不断地用因子去试除自然数不断地用因子去试除自然数x x,直到因子,直到因子不能整除自然数不能整除自然数x x;l(3)(3)如果如果x x为为1 1,则直接跳出测试,这个数为,则直接跳出测试,这个数为丑数;丑数;l(4)(4)如果所有因子测试完,如果所有因子测试完,x x不为不为1 1,则这个,则这个数包含非数包含非2 2,3 3,5 5,7 7的因子,不为丑数。的因子,不为丑数。l如果为如果为4 4和和6 6就
26、跳过测试;就跳过测试;ncontinuecontinuencontinuecontinue语句的意思是循环体后面的工作都不做语句的意思是循环体后面的工作都不做了,直接跳回循环最前面去了,直接跳回循环最前面去 l如果如果x x为为0 0,则直接跳出测试,则直接跳出测试nbreakbreaknbreakbreak语句的作用在于跳出本层循环,直接到循语句的作用在于跳出本层循环,直接到循环体外。环体外。breakbreak语句语句 和和continuecontinue语句语句-练习练习3 3l 输入一个正整数输入一个正整数m m,判断它是否为素数判断它是否为素数算法:除了算法:除了1 1和和m m,不
27、能被其它数整除。,不能被其它数整除。设设 i i 取值取值 2,2,m-1 m-1 u如果如果m m不能被该区间上的任何一个数整除,即对每个不能被该区间上的任何一个数整除,即对每个i i,m%i m%i 都不为都不为0 0,则,则m m是素数是素数u只要找到一个只要找到一个i i,使使m%im%i为为0 0,则,则m m肯定不是素数肯定不是素数m%2%3%4%5%(m-1)m%2%3%4%5%(m-1)不是素数不是素数|=0 =0|=0 =0是素数是素数&!=0 !=0&!=0 !=0 nm m不可能被大于不可能被大于 m/2 m/2 的数整除的数整除 i i 取值取值 2,2,m-1 m-1
28、、2,2,m/2 m/2、2,2,mfor(i=2;i m/2)printf(yesn)else printf(non”);l求求500以内的全部素数,每行输出以内的全部素数,每行输出10个个l将一个正整数逆序输出将一个正整数逆序输出循环小结循环小结l循环程序的实现要点:循环程序的实现要点:n归纳出归纳出哪些操作需要反复执行?哪些操作需要反复执行?循环体循环体n这些操作在什么情况下重复执行这些操作在什么情况下重复执行?循环条件循环条件l选用合适的循环语句选用合适的循环语句for while do-whilefor while do-whilel循环具体实现时考虑(循环条件):循环具体实现时考虑(循环条件):n事先给定循环次数,首选事先给定循环次数,首选forforn通过其他条件控制循环,考虑通过其他条件控制循环,考虑whilewhile或或do-do-whilewhile