程序设计入门——C语言(翁凯版)第四周

发布时间:2024年01月17日

4.1 逻辑类型和运算

4.1.1 逻辑类型

在代码开头#include <stdbool.h>,就可以使用bool、true和false

bool b=2;
bool t=true;
t=2;
printf("%d", t);

输出

1

得到输出的实际上还是整数,而不是true或者false。

4.1.2 逻辑运算

  • 逻辑运算是对逻辑量的运算,结果只有0或1;
  • 逻辑量是逻辑运算或关系运算的结果;

逻辑运算的规律如下
在这里插入图片描述

如果要表示4<x<6,应该是4<x&&x<6而不是4<x<6(4<x<6的结果是1)
将已经学到的运算符的优先级进行比较
在这里插入图片描述
有时候会出现短路的情况

  • 对于&&,左边是false时就不做右边了;
  • 对于||,左边是true时就不做右边了;
  • 所以不要把赋值包括复合赋值放在表达式内。

4.1.3 条件运算和逗号运算

4.1.3.1 条件运算

条件运算的格式为:a?b:c;
其中a、b、c分别是条件、条件满足时的值和条件不满足时的值。
条件运算符的优先级高于赋值运算符,低于其他运算符,是自右向左结合的。

  • w<x?x+w:x<y?x:y;
  • 这是一种嵌套的条件运算,不希望被使用。
4.1.3.2 逗号运算
  • 逗号用来连接两个表达式,并以右边表达式的值作为它的结果;
  • 优先级是最低的,所以两边的表达式会先计算;
  • 组合关系是自左向右,所以左边会先计算,右边表达式的值会留下来作为逗号运算的结果。
int i;
i=3+4,5+6;
printf("%d", i);

输出

7
int i;
i=3+4,5+6;
printf("%d", i);

输出

11

逗号运算主要用在for循环中。

4.2 级联和嵌套的判断

4.2.1 嵌套的if-else

之前已经可以用if语句在两个数中去较大的,那么如何在三个数中去最大的呢?
可以先让前两个数相比较,再取其中较大的与第三个数相比,这两者中较大者即为三个数中的最大数。流程图如下
在这里插入图片描述
代码

int a, b, c;
	scanf("%d %d %d", &a, &b, &c);
	
	int max=0;
	
	if(a>b){
		if(a>c){
			max=a;
		}else{
			max=c;
		}
	}else{
		if(b>c){
			max=b;
		}else{
			max=c;
		}
	}
	
	printf("The max is %d\n", max);

或者

int a, b, c;
	scanf("%d %d %d", &a, &b, &c);
	
	int max=0;
	
	if(a>b)
		if(a>c)
			max=a;
		else
			max=c;
		
	else
		if(b>c)
			max=b;
		else
			max=c;
		
	
	
	printf("The max is %d\n", max);

如果if的条件满足或者不满足时要执行的语句也是if或者if-else语句,这就是嵌套的if语句。
else语句总是和最近的if匹配,缩进格式不能暗示else的匹配。
在if和else后面总是用{},即使只有一条语句。

4.2.2 级联的if-else

如果要计算这样一个分段函数
在这里插入图片描述

if(x>o){
	f=-1;
}else if(x==0){
	f=0;
}else{
	f=2*x;
}

这是级联的if-else语句,基本格式如下

if(expl)
	st1;
else if(exp2)
	st2;
else
	st3;

对于上面分段函数的例子,还有一种代码

if(x<0){
	printf("%d",-1);
}else if(x==0){
	printf("%d",0);
}else{
	printf("%d",2*x);
}

之前的代码是单一出口,这里的代码不是,单一出口更好。

4.3 多路分支

4.3.1多路分支

代码一
在这里插入图片描述
代码二
在这里插入图片描述
这两种代码是等价的。
switch-case的基本格式如下

switch(控制表达式){
	case 常量:
		语句
		...
	case 常量:
		语句
		...
	default:
		语句
		...
}
  • 控制表达式只能是整数的结果;
  • 常量可以是常数,也可以是常数计算的表达式;
  • switch语句可以看做是一种基于计算的跳转,计算控制表达式的值后,程序会跳转到相匹配的case(分指标号)处。分指标号只是说明switch内部位置的路标,在执行完分支的最后一条语句后,如果后面没有break,就会顺序执行下一个case内的语句,直到遇到break或者switch结束。
switch(type)
{
case 1:
case 2:
	printf("你好\n");
	break;
case 3:
	printf("晚上好\n");
case 4:
	printf("再见\n");
	break;
default:
	printf("啊,什么啊?\n");
	break;
}

如果输入1,那么程序将会在进入case1之后再次进入case2,之后退出switch-case,输入3将会进入case3之后进入case4然后退出switch-case。

4.4 循环的例子

4.4.1 循环计算

写一段程序求以2为底x的log值
程序如下

int x;
int ret=0;

//scanf("%d", &x);
x=128;
while(x>1){
	x/=2;
	ret++;
}
printf("log2 of %d is %d.", x, ret);

输出

log2 of 1 is 7.

显然x的输出是不正确的。因为printf里的x是已经计算过的x。
这里有一个小套路,就是在x参与计算之前定义一个t,t=x,将x原本的值储存到t中,最后输出t即可。
为什么程序中定义ret=0?为什么while后的条件是x>1?这些值是如何定出来的呢?
这些值是相互影响的,共同影响循环的次数和结果,需要具体问题具体分析。
来看另一个例子。

int count=100;
while(count>=0){
	count--;
	printf("%d\n",count);
}
printf("发射!\n");
  • 这个循环执行多少次?
  • 循环停下来时候,有没有输出最后的0?
  • 循环结束后,count的值是多少?

小套路:如果要模拟一个很大次数的循环,可以模拟较少的循环次数,然后做出推断。

int n=3;
while(n>=0{
	printf("%d", n);
	n--
}
printf("发射\n");

假设n=3
n 3 2 1 0 -1
输出 3 2 1 0

int n=3;
while(n>=0{
	n--;
	printf("%d", n);
}
printf("发射\n");

n 3 2 1 0 -1
输出 2 1 0 -1

回到之前count=100的例子,三个问题的答案分别是

  • 101;
  • 有;
  • -1。

4.4.2 算平均数

问题:让用户输入一系列正整数,最后输入-1表示输入结束,计算这些数的平均值,输入这些数的个数和平均值。
变量->算法->流程图->程序

  • 变量:一个记录读入的整数;平均数的计算只需每读到一个数就加到一个累加的变量中,到全部数据读完除以个数即可;一个变量记录累加的结果,一个变量记录数的个数。
  • 算法:1.初始化sum和count为0;2.读入number;3.如果number不是-1,将number加入sum,并将count加1,回到2;4.如果number是-1,计算和打印输出sum/count(注意换算成浮点来计算)。
  • 流程图:在这里插入图片描述

程序如下

int main()
{
	int number;
	int sum=0;
	int count=0;
	
	do{
		scanf("%d", &number);
		if(number!=-1){
			sum+=number;
			count++;
		}
	}while(number!=-1);
	/*scanf("%d", &number);
	while(number!=0){
		sum+=number;
		count++
		scanf("%d", &number);
	}
	第一种算法每一轮要对number是否等于-1要做两次判断,比较浪费*/
	printf("%f\n", 1.0*sum/count);
}

4.4.3 猜数

计算机想一个数,用户输入一个数,如果不一样输出大了还是小了,直至猜中,输出猜了多少次。
算法:

  1. 计算机随机想一个数记录到变量number;
  2. 负责记录次数count初始化为0;
  3. 用户输入a;
  4. count递增1;
  5. 判断a和number大小,如果a大输出“大”,a小输出“小”;
  6. 如果a和number不相等,程序回到3;
  7. 否则输出“猜中”和次数,程序结束。

循环的条件是a和number不相等

srand(time(0));//召唤一个随机的整数
int number = rand()%100+1;
int count = 0;
int a = 0;
printf("我已经想好了一个1到100之间的数。");
do{
	printf("请猜这个1到100之间数:");
	scanf("%d", &a);
	count++;
	if(a>number){
	printf("你猜的数大了");
	}else if(a<number){
	printf("你猜的数小了");
	}
}while(a!=number);
printf("太好了,你用了%d次就猜到了答案。\n", count);

100以内的数最多猜7次(二分法)

4.4.4 整数求逆

输入一个正整数,输出逆序的数(注意0的处理)。

  1. 整数%10得到个位数;
  2. 整数/10去掉个位数;
  3. 对2的结果重复进行1、2。

代码如下

int x;
scanf("%d", &x);
int digit;
/*int ret=0;

while(x>0){
	digit=x%10;
	ret=ret*10+digit;
	x/=10;
}
printf("%d", ret);
这种算法可以把逆序排在首位的0省去*/
while(x>0){
	digit=x%10;
	prntf("%d", digit);
	x/=10
}

return 0;

4.5 判断和循环常见的错误

4.5.1 常见错误

if语句的常见错误

  1. 忘了大括号(永远在if和else后面加上大括号,即使只有一条语句);
  2. if后面的分号(不可以加,不然编译器会认为if后面为空,并且后面的{}内的内容正常运行编译器认为没问题,后面调试会用到这一点);
  3. 错误使用==和=(这个犯了。。。if()里的值是零或非零)
  4. if和else后必须加上大括号形成语句块,且大括号内的语句缩进一个tab的位置;
    对于if-else有不同风格
if(x<0){
	f=-1;
}else if(x==0){
	f=0;
}else{
	f=2*x;
}
if(x<0)
{
	f=-1;
}else if(x==0)
{
	f=0;
}else
{
	f=2*x;
}
if(x<0)
{
	f=-1;
}
else if(x==0)
{
	f=0;
}
else
{
	f=2*x;
}
文章来源:https://blog.csdn.net/qq_44845100/article/details/135629638
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。