【C语言拓展】运算符、scanf与scanf_s的区别、特点

简介: 【C语言拓展】运算符、scanf与scanf_s的区别、特点

前言

本节课讲的是拓展提升:运算符,为什么vs高版本不能使用scanf,scanf_s与scanf的区别与优缺点

strcpy与strcpy_s的区别与优缺点


提示:以下是本篇文章正文内容,下面案例可供参考

一、运算符

运算符

运算符优先级与结合性的本意是先后结合哪个子表达式,相当于先分组,分组完 毕后,从左向右依次计算

int a = 1, b = 4, c = 8, d = 12, e = 99, f; 
f = a + b - c * d / e;

结合过程如下:

1、乘除优先级高,先结合,乘除同级从左到右结合即按优先级先结合乘法/除法,乘除结合性从左到右,所以先结合 c*d,然后/e

2、再结合加减,同级从左到右结合,即先结合 a+b,然后结合减法

3、最后结合赋值运算符


此表达式先算 a+b,而不是 c*d,所以优先级与结合性不是单纯的谁先算谁后算。我 们正常脑算看待优先级可以以先算后算来处理,不会影响结果

for循环最通用的写法

在for循环前写循环控制变量

//最通用的写法: 
int i ; //即循环控制变量的定义位置
for (i = 0; i < 5; i++) 
//在 vs2013 以上版本可以如下写:
for (int i = 0; i < 5; i++) 
 //但是该写法很多编译器都不支持,所以建议使用上边那种,以增加代码移植性

真短路或"||"

逻辑运算符:|| 读 或

运算规则:

真 || 真 为真 结果 1 真 || 假 为真 结果 1 假 || 真 为真 结果 1 假 || 假 为假 结果 0

真短路 || : 因为“真 || 表达式”结果一定是真,即“表达式”不管是什么都不改变结果,

所以“表达式”就不执行了,执行也是浪费时间,举例如下:

int a = 1, b = 1;
5 || (a=66) || (b=87);

过程:(依据优先级结合性执行即可)

5 为真,子表达式 5 || (a=2)中发生短路,所以(a=2)不执行,子表达式 5 || (a=2)结果 为真,即 1。 剩下 1 || (b=2),1 为真,短路||,所以(b=2)不执行,表达式 1 || (b=2)结果为真。 最终整个表达式结果为真,即 1,a、b 值保持 1 不变。

0 || (a=2) || (b=2);

过程:(依据优先级结合性执行即可)

短路原理的目的:增加程序执行效率

假短路与"&&"

逻辑运算符:&& 读 与

运算规则:

真 && 真 为真 结果 1 真 && 假 为假 结果 0 假 && 真 为假 结果 0 假 && 假 为假 结果 0

假短路&&:因为“假 && 表达式”结果一定是假,即“表达式”不管是什么都不改变结果

int a = 2, b = 2;
0 && (a=0) && (b=0);

过程:(依据优先级结合性执行即可)

0 为假,子表达式 0 && (a=0)发生短路,不执行(a=0),子表达式 0 && (a=0)为假, 即 0。剩下 0 && (b=0),0 为假,子表达式 0 && (b=0)发生短路,不执行(b=0),子表达 式 0 && (b=0)为假,即 0。 最终整个表达式结果为假,即 0,a、b 保持 2 不变

&&和||混合短路

与(&&)、或( || )混合短路:

执行原则:按照优先级与结合性分组,然后从左到右计算,遇到短路就短路,&&优

先级高于 ||

短路原理与代码优化

短路原理对代码优化的警示 真短路或: (条件 1) || (条件 2) 为真概率大的条件放左边,可以减少两个条件同时执行的概率,从而增加程序执行效率。

两个条件都判断执行的概率是 80% 假短路与:

(条件 1) & & (条件 2)

为假概率大的条件放左边,可以减少两个条件同时执行的概率,从而增加程序执行效率。

二、scanf与scanf_s

scanf_s是什么:scanf_s 与 scanf _s 版本的函数是 C11 标准的新函数,非_s 就是旧版 C 语言函数,新编译器建议大家使用新 版本的_s 函数

如何在vs高版本使用scanf

scanf 在高版本 vs 报错问题解决办法

1、声明宏 : #define _CRT_SECURE_NO_WARNINGS

2、关掉 sdl : 属性->c/c+±>常规->sdl 检查

3、scanf_s

scanf_s比scanf安全?

scanf_s 比 scanf 安全? 主要体现在越界问题中的处理措施 scanf 是在程序结束后报异常中断,不会立即中断

缺点 1,假设数万行代码,有数百个 scanf 输入,这时很难短时间内定位到越界点。

缺点 2,越界操作可能会侵害其他变量的空间,导致未知的莫名其妙的错误。

缺点3,程序不结束,其问题可能会像蝴蝶效应,影响越来越离谱。

scanf_s 会执行失败,变量输入不成功,函数返回值为 0

优点 1,可能及时知道错误点,并及时做出相应处理

优点 2,不会导致越界问题,所以不会侵害其他变量空间

三、strcpy与strcpy_s

参数的区别:

//参数使用区别 
strcpy_s(str, 20, "hello "); //参数 2 表示参数 1 的字节数 
strcpy(str, "hello w");

为啥要使用strcpy_s?

strcpy_s 比 strcpy 安全? 主要体现在越界问题中的处理措施 strcpy 是在程序结束后报异常中断,不会立即中断,跟 scanf 越界情况 1 样

缺点 1,假设数万行代码,有数百个 strcpy 使用,这时很难短时间内定位到越界点。

缺点 2,越界操作可能会侵害其他变量的空间,导致未知的莫名其妙的错误。

缺点3,程序不结束,其问题可能会像蝴蝶效应,影响越来越离谱。

strcpy_s 会立即中断,即函数调用位置中断,跟 scanf_s 处理方式不同

优点 1,立即知道错误点,并及时做出相应处理

优点 2,不会导致越界问题,因为直接停下了,不会往下运行了,所以不会侵害其他变

量空间


相关文章
|
6天前
|
C语言
c语言运算符
C的运算符有以下几种: 算术运算符:+、-、*、/、% 结合方向自左向右 关系运算符:>、<、==、>=、<=、!= 逻辑运算符:!、&&、|| 位运算符<<、>>、~、|、^、& 赋值运算符:=及符号扩展赋值运算符(+=、-=、*=、/=) 条件运算符:? : 逗号运算符:, 指针运算符:*、& 求字节运算符:sizeof 强制类型转换运算符:((类型)) 分量运算符:.、-> 下标运算符:[]
14 4
|
15天前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别
pymalloc 和系统的 malloc 有什么区别
|
11天前
|
程序员 C语言 开发者
pymalloc 和系统的 malloc 有什么区别?
pymalloc 和系统的 malloc 有什么区别?
|
1月前
|
存储 C语言
C语言中a 和&a 有什么区别
在C语言中,&quot;a&quot; 是一个变量的名字,代表存储在内存中的某个值。而&quot;&a&quot; 则是获取该变量的内存地址,即变量a在计算机内存中的具体位置。这两者的主要区别在于:&quot;a&quot; 操作的是变量中的值,&quot;&a&quot; 操作的是变量的内存地址。
115 23
|
29天前
|
存储 C语言
C语言:普通局部变量、普通全局变量、静态局部变量、静态全局变量的区别
C语言中,普通局部变量在函数内部定义,作用域仅限于该函数;普通全局变量在所有函数外部定义,作用域为整个文件;静态局部变量在函数内部定义但生命周期为整个程序运行期;静态全局变量在所有函数外部定义,但仅在定义它的文件内可见。
41 10
|
1月前
|
程序员 编译器 C语言
C中的 malloc 和C++中的 new 有什么区别
在C语言中,`malloc`函数用于在运行时分配内存,返回指向所分配内存的指针,需显式包含头文件 `&lt;stdlib.h&gt;`。而在C++中,`new`不仅分配内存,还对其进行构造初始化,且直接使用类型声明即可,无需额外包含头文件。`new`还支持数组初始化,能更好地融入C++的面向对象特性,而`malloc`仅作为内存分配工具。使用完毕后,`free`和`delete`分别用于释放`malloc`和`new`分配的内存。
51 21
|
26天前
|
存储 C语言
C语言:结构体与共用体的区别
C语言中,结构体(struct)和共用体(union)都用于组合不同类型的数据,但使用方式不同。结构体为每个成员分配独立的内存空间,而共用体的所有成员共享同一段内存,节省空间但需谨慎使用。
|
30天前
|
存储 编译器 C语言
C语言函数的定义与函数的声明的区别
C语言中,函数的定义包含函数的实现,即具体执行的代码块;而函数的声明仅描述函数的名称、返回类型和参数列表,用于告知编译器函数的存在,但不包含实现细节。声明通常放在头文件中,定义则在源文件中。
|
30天前
|
存储 C语言
C语言指针与指针变量的区别指针
指针是C语言中的重要概念,用于存储内存地址。指针变量是一种特殊的变量,用于存放其他变量的内存地址,通过指针可以间接访问和修改该变量的值。指针与指针变量的主要区别在于:指针是一个泛指的概念,而指针变量是具体的实现形式。
|
1月前
|
存储 编译器 C语言
C语言:数组名作为类型、作为地址、对数组名取地址的区别
在C语言中,数组名可以作为类型、地址和取地址使用。数组名本身代表数组的首地址,作为地址时可以直接使用;作为类型时,用于声明指针或函数参数;取地址时,使用取地址符 (&),得到的是整个数组的地址,类型为指向该类型的指针。