scanf函数收尾+循环分支语句(上)
文章目录
- scanf函数收尾
- scanf的返回值
- 占位符
- 赋值忽略符
- 分支和循环(上)
- if语句
- else 语句
- 分支中包含多条语句
- 嵌套 if
- 关系操作符
- 条件操作符
- 逻辑操作符:&&、||、!
- 逻辑取反运算符 !
- 逻辑与运算符
- 逻辑或运算符
- 短路
- 总结
scanf函数收尾
scanf()处理占位符时会自动过滤空白字符,包括空格,制表符,换行符等,因此用户输入的数据之间有一个或者多个空格不影响scanf()解读数据,我们使用回车键将输入分为几行,也不影响解读
这里给大家介绍一下上面例子中的-2.2e3的意思,这里的e3指的是乘上十的三次方即-2.2*1000
scanf()处理用户输入的原理是哦用户的输入先放入缓存,等到摁下回车键后,按照占位符对缓存进行解读解读用户输入时,会从上一次解读遗留的的第一个字符开始,直到读完缓存或者遇到第一个不符合条件的字符为止
这里可以看到在读取第一个整数的时候读到了-3后面是小数点不符合整数的定义就不读了因此-3就是a的值,然后读第二个占位符从上次解读遗留的第一个字符即小数点开始,因为第二个占位符就是要读取一个小数因此一直读到#前
scanf的返回值
scanf() 的返回值是一个整数,表示成功读取的变量个数。
如果没有读取任何项,或者匹配失败,就会返回 0。
如果在成功读取任何数据之前发生了读取错误或者遇到读取到文件结尾,则返回常量 EOF(-1)。
EOF —— end of file,文件结束标志。
如果我们想要实现 EOF 的效果,则输入的时候输入三个 Ctrl+Z(只有 VS 需要输入三个,这个跟编译器有关),按 Ctrl+Z 会让 scanf 的读取发生错误。
平常我们使用scanf没有接收它的返回值的时候会有提示在vs上它会希望我们去接受它的返回值
我们忽略即可
占位符
scanf() 常用的占位符与 printf() 的占位符基本一致
- %c:字符
- %d:整数
- %f:float 类型浮点数
- %lf:double 类型浮点数
- %Lf:long double 类型浮点数
- %s:字符串
- %[]:在方括号中指定一组匹配的字符比如(%[1-5])遇到不在集合中的字符匹配将会停止
以上所有的占位符中除了%c之外都会自动忽略空白字符,%c不忽略空白字符总是返回当前第一个字符无论是不是空格
上面实例可以看到并没有输出y,////是为了明显的看到效果
如果我们想跳过字符前的空白字符呢?我们只需要写成scanf(" %c",&ch)即可,在%c的前面加上一个空格,表示跳过空白字符
这里我要特别说一下占位符%s
之前我们打印字符串是 printf(“%s”,“abcdef”);遇到字符串的结束标志\0打印才算结束,我们使用char来存放字符,那我们使用什么来存放字符串呢?这里给大家简单介绍一下数组,后面的更新会详细介绍,数组里面可以存放多个字符,char只能存放一个,字符串是多个字符组成的因此我们使用字符数组char pyz[20],我们将字符串存入数组的时候不用取地址了因为数组的名字就是数组的首地址
%s其实不能简单地等同于字符串他的规则是从当前第一个非空白字符开始读取直到遇到空白字符(空格,换行符,制表符等)为止
这里我们可以看到只打印了pyz
因为%s不会包含空白字符所以无法用来读取多个单词,除非多个%s一起使用,scanf()遇到%s占位符,会在字符串变量末尾存储一个空字符\0
scanf()将字符串读入字符数组时不会检测字符串是否超过了在数组长度,所以存储字符串时很可能会超过数组的边界导致其他的后果,这也是为什么vs会认为scanf不安全的原因,为了避免这种情况,我们使用%s占位符时指定一下读入字符串的最长长度写成%[m]s,其中[m]是一个整数表示读取字符串的最大长度后面的字符将被丢弃
指定长度后可以看到只取了前四个字符,注意这里的%4s不是%5s是因为字符串最后还有一个\0作为结束标识符也要占一位
那我们如果想要它读取到空格呢?此时只需要把%s输入为%[^\n]s即可,这个指的是读取一个字符串直到遇到\n为止
赋值忽略符
我们在输入的时候不是随便乱输的,我们要遵循输入格式
这个实例中我们直接输入的日期但是打印在屏幕上的并不是我们预期的效果,这是为什么呢?其实我们仔细观察一下我们输入的时候占位符是%d-%d-%d当我们输入值的时候我们也要遵循这样的书写方式去输入
为了避免这种情况scanf()提供了一个赋值忽略符(*),只要把 * 加在任何占位符的百分号后面该占位符就不会返回值,解析后将被丢弃
加上*后无论中间是用空格隔开还是/都可以按照我们预期的效果输出
分支和循环(上)
C 语言是结构化的程序设计语言,这里的结构指的是顺序结构、选择结构、循环结构。C 语言是能够实现这三种结构的,我们还可以使用
if、switch实现分支结构,使用for、while、do while实现循环结构。
if语句
if 语句的语法形式如下:
if(表达式)语句表达式成立则语句执行,表达式不成立则语句不执行。
在 C 语言中,0 为假,非 0 为真,也就是说如果表达式的结果是 0 那么语句不会执行,如果结果是非零则语句会执行。
例子:输入一个值判断是否为奇数
else 语句
如果不是奇数那就是偶数。如果任意一个整数需要我们判断是奇数还是偶数,此时就需要 if…else… 语句。语法形式如下:
if(表达式)语句else语句2例子:输入一个数,判断是奇数还是偶数,打印出结果。
分支中包含多条语句
在 if 和 else 中默认只有一条语句,如果有多条语句的话需要用 {} 来括起来,不然会报错。
嵌套 if
在 if else 语句中,else 可以和另一个 if 语句连用,构成多重判断
比如输入一个整数,判断是 0 还是正数或者负数
关系操作符
C 语言用于比较的表达式称之为“关系表达式”,里面使用的运算符就称为“关系运算符”,主要有下面这些:
>大于运算符<小于运算符>=大于等于运算符<=小于等于运算符- ==相等运算符
- !=不相等运算符
关系表达式通常返回0或1表示真假
C语言中0表示假所有的非零值表示真比如1>10返回0,13>1返回值为1
关系表达式通常用于if或while结构,上面我们在进行if语句的讲解中的表达式就用到了关系操作符
需要注意一点就是=和==的区别,=是赋值两个等号是判断是否相等
这个例子是如果a的值等于5那么执行下面的语句,那如果我们把双等号换成=呢?
我们可以看到没有任何变化,但是这并不代表这两个符号是等价的,其实这个例子曲解了代码本来的意思,该代码是要判断a的值是否等于5,如果等于的话返回值为1那么执行下面的语句,但这个实例是把5赋值给了a,那么此时是一个非零值if判断为真,那么执行下面的语句,因此在我们编写代码的时候如果一个变量和一个常量值比较相等的时候,建议将常量值放在==的左边
修改后就不会出现上面实例的错误了
还有一个需要注意的是多个关系运算符不宜连用
为什么会这样呢?其实是因为关系运算符是从左到右计算先算的90<=a为返回值为0然后计算0<=100为真则执行下面的语句,如果我们想要表达a是否在90和100之间那么我们因该使用下面的写法
90<=a&&a<=100条件操作符
条件操作符也叫三目操作符,需要接受三个操作数,形式如下:
exp1?exp2:exp3条件操作符的计算逻辑是:如果 exp1 为真,那么 exp2 计算,计算结果为整个表达式的结果;如果 exp1 为假,那么 exp3 计算,计算结果为整个表达式的结果。
注意:如果像上图中那样使用,一定要记得加上括号,不然会报错,因为操作符的优先级。
当然还有另一种更简洁的写法:
c=(a>10?10:0)逻辑操作符:&&、||、!
逻辑运算符提供逻辑判断功能,用于构建更复杂的表达式。
!:逻辑取反运算符(改变单个表达式的真假)&&:逻辑与运算符,表达并且的意思(两侧的表达式都为真则为真,否则为假)||:逻辑或运算符,就是或者的意思(两侧至少有一个表达式为真则为真,否则为假)
逻辑取反运算符 !
| a | !a |
|---|---|
| 非 0 | 0 |
| 0 | 1 |
intmain(){inta=0;scanf("%d",&a);//如果a为真则打印aif(a)printf("%d",a);//如果a为假那么打印0if(!a)//如果a为假那么!a为真printf("0");return0;}逻辑与运算符
&& 就是与运算,也是并且的意思。&& 是一个双目操作符,使用的方法是 a && b。&& 两边的表达式都是真的时候,整个表达式才是真;只要有一个是假的,那么整个表达式就是假的。
如果我们想要表示 18 周岁到 50 周岁的人购买成人票,该如何表示呢?
逻辑或运算符
||就是或运算符,||也是一个双目操作符,使用方式是a || b,||两边的表达式只要有一个是真的,那么整个表达式都是真的;两边的表达式都为假,整个表达式才是假。
比如我们说一周中周六或者周日是休息日,那么用代码怎么表达?
短路
C语言逻辑运算符还有一个特点,就是它总是先对左侧的表达式求值,再对右边的表达式求值,如果左边的表达式满足逻辑运算符的条件,就不再对右边的表达式求值,这种情况就是“短路”。
if(a>0&&a<5)上面这个表达式中,如果
a>0为假,那么即使不判断a<5,整个表达式也是 0。
所以对于&&,如果左边的表达式结果为 0,那么将不会对右边的表达式进行计算。
对于||操作符同理,如果左边的表达式是非 0,那么不用去计算右边的表达式。
这种仅仅根据左操作数就知道整个表达式的结果,不再对右操作数进行计算的运算,称之为短路求值。
总结
本文系统地介绍了 C 语言中scanf函数的使用细节以及分支和循环结构的基础知识。
第一部分:scanf函数收尾
scanf的返回值:返回成功读取的变量个数。读取失败返回 0,发生错误或遇到文件结尾返回EOF。- 占位符:详细讲解了
%c、%d、%f、%lf、%Lf、%s、%[]等常用占位符的特性。特别指出%c不忽略空白字符,而其他占位符会自动忽略。对于%s,说明了其读取规则(遇到空白字符停止)、潜在的安全风险(可能越界)以及如何通过%[m]s和%[^\n]s来限制长度或读取包含空格的整行。 - 赋值忽略符
*:介绍了如何使用*来跳过某些输入项的赋值,从而灵活处理输入格式。
第二部分:分支和循环(上)
if与else语句:讲解了if和if...else...的基本语法,强调在 C 语言中0为假,非0为真。并通过实例演示了如何判断奇偶数。- 分支中的多条语句:说明如果
if或else分支需要执行多条语句,必须使用{}将它们括起来。 - 嵌套
if:介绍了如何使用else if实现多重判断。 - 关系操作符:介绍了
>、<、>=、<=、==、!=等关系运算符,并重点强调了=(赋值)与==(相等判断)的区别,以及多个关系运算符不宜连用(应使用逻辑运算符连接)。 - 条件操作符(三目运算符):介绍了
exp1 ? exp2 : exp3的语法和计算逻辑。 - 逻辑操作符:讲解了逻辑非
!、逻辑与&&、逻辑或||的用法和真值表,并通过实例说明了&&和||的“短路求值”特性。
本文内容详实,配有丰富的代码示例和运行截图,适合 C 语言初学者巩固scanf函数和基础流程控制语句的知识。
