当前位置: 首页 > article >正文

【C语言】操作符2(含操作符的应用)

1、单目操作符

        单目操作符有下面几种:

        !、++、--、&(取地址)、*(指针)、+(正号)、-(负号)、~、sizeof、(类型)

        其中就还有&和*操作符还没有学习过,这个我们在后面学习指针的时候会详细来讲的。

2、逗号表达式

        逗号表达式就是用逗号隔开的表达式。如下所示:

        exp1,exp2,exp3,.......expN

        有N个表达式,然后每个表达式用逗号分隔开来。

        其规律为:

        每一个表达式都会进行运算,但是整个逗号表达式的结果是最后一个表达式的结果。

        下面我们通过一个代码来感受一下:

        

           看上面的逗号表达式:先进行a和b比大小,此时不会改变a,b的值,然后这个结果也不是整             个逗号表达式的结果所以也没有给c赋值,然后就是对下一个表达式运算,此时a的值就变                成了12但是也不会赋值给,然后第三个表达式a没有进行任何赋值操作而且也不是最后一                个表达式,所以还是没有对c赋值,然后最后一个表达式使得b的值为13且此时的值也就是              整个逗号表达式的值,所以此时c的值为13

           

               逗号表达式的妙用:

               

                    如上,修改前的代码在使用循环前需要对a进行处理,然后才开始进行循环,然后在                        循环体内在进行完业务出处理后又需要对a进行处理。这时我们可以在循环的判断条                        件语句中使用逗号语句,然后将判断的那个语句放在逗号表达式的最后一个表达式,                      然后对于a的处理的表达式放在前面,这样就可以不用在循环前对a进行操作了。而且                      在循环后也还会对a处理才进行判断,也没有影响原来的逻辑。

3、下标访问呢操作符[ ]、函数调用操作符()

         这两个操作符我们在前面学习数组和函数的时候已经非常熟悉了。

         下标访问操作符[ ]:

         其是一个双目操作符,其操作数,一个为数组名,一个为索引(下标)

         下面为其使用例子:

          

          函数调用操作符():

          接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数,            而且是必须有函数名这个操作数的,参数的操作数可以有也可以没有,这个看你函数需要实            现功能来决定。比如我们之前写的猜数字游戏和扫雷游戏,我们定义了个实现菜单功能的函            数,其操作数就只有函数名字了没有参数。

          

              

4、结构成员访问操作符

        在这里我们先简单了解一下结构体后续还会专门学习结构体

   1、结构体

         c语言提供了内置类型,如:char、int、short、long、float、double等。但是实际上只有这             些内置类型还是不能满足我们的需求的,假设我要描述一个学生描述一本书,,这时候单一           的数据类型是不行的。

         描述一个学生:名字、年龄、学号、身高、体重等。

         描述一本书:作者、出版社、定价等。

         c语言中为了解决这个问题,增加了结构体这种自己定义的数据类型,让使用者可以根据自             己的需求来定义合适的数据类型。

         

   2、结构体的声明 

        使用关键字:struct  结构体名

         

        上面为结构体的声明,成员列表则为我们需要的具体的数据了,变量列表就是可以在那边创             建结构体变量,也可以省略,但是注意:后面的分号不可以省略。下面我们定义一个学生的           结构体来看看     

         

     3、结构体变量的定义和初始化

          定义:

          结构体的定义有两种方法:

          1、在创建结构体的时候在最后直接写出这个变量,注意后面的分号!!!

            

         2、和定义结构体有一点类似,使用struct关键字然后加上一个名字,然后再加上这个变量的                名字。

                 

       初始化:

       结构体的初始化和数组差不多,也是使用大括号。

       

       第一个初始化就会按照结构体中的数据顺序的初始化,即第一个"zhangsan"就是name的,然         后20就是age的了,第二种就是指定初始化,这个就在要初始化的那个数据加.即可。   

      若结构体中的一个成员也是结构体的话:

      

         这个时候在初始化中要对结构体中的这个结构体成员进行初始化,我们在大括号内再使用大           括号将这个结构体成员的初始化即可。

         

     4、结构成员访问操作符   

          直接访问:

          结构体成员的直接访问是通过点操作符(.)访问的。点操作符接受两个操作数。如下所⽰:

         

          使用方式:结构体变量.成员名 

          间接访问:

          有的时候我们得到的不是一个结构体变量,而是得到了一个指向结构体的指针,这个时候我            们就使用间接访问的方式来访问结构体,即:(->)符号。这里我们就只做简单介绍,因为            还涉及到指针的知识。

5、操作符的属性:优先级,结合性

        C语言的操作符有两个重要的属性:优先性和结合性,这两个属性决定了表达式求值的计算            顺序。

1、优先级

      优先级指的是如果一个表达式包含多个运算符,那么那个运算符先执行呢。各种运算符的优先        级是不一样的。

      如下所示:

      3+4*5;

      上面的表达式中既有加法运算又有乘法运算,由于乘法运算的优先级高于加法,所以表达式是        先计算4*5然后再计算加法。

      运算符的优先级顺序很多下面为其具体情况:

      • 圆括号( () )

      • ⾃增运算符( ++ ),⾃减运算符( -- )

      • 单⽬运算符( + 和 - )

      • 乘法( * ),除法( / )

      • 加法( + ),减法( - )

      • 关系运算符( < 、 > 等)

      • 赋值运算符( = )

      

2、结合性            

      当两个运算符的优先级是一样的时候咋办呢,这个时候优先级就没有办法确定先计算谁了。

      这个时候就得看结合性了,根据运算符是左结合,还是右结合,决定其执行顺序。其中大部分        运算符是左结合(从左到右执行),少数运算符是右结合(从右往左执行)例如:赋值运算符        =。 

     下面为运算符的优先级和结合性:

      

6、整型提升和算术转换

 1、整型提升       

      C语言中整型算术运算总是至少以缺省(默认)整型数据的精度来进行的,为了获得这个精            度,表达式中的字符和整型操作数在使用之前转换为普通整型,这种转换为:整型提升。

      整型提升的意义:

      表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字        节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型        的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度

      通用CPU是难以直接实现两个8比特字节直接相加运算。所以,表达式中各种长度可能小于int       长度的整型值,都必须先转换为int或者unsigned int ,然后才能进入CPU去执行运算

     如下面的运算: 

    

       这里的b和c都是char类型的数据,在进行后面的运算时候,,会先将其整型提升,提升为普           通整型int,然后在执行加法运算,在加法运算完成后 ,这个时候会有四个字节,要存入a中,         因为a也为char类型数据,所以结果要截断,从四个字节截断成1个字节,也就是将前面三个           字节去掉,然后在存储给a。那么整型提升是如何进行的呢?

       整型提升的方法:

       1、有符号整型提升是按照变量的数据类型的符号位来提升的,高位补符号位

       2、无符号整型提升,高位补0

       下面我们通过一个实例来理解:

        

       

2、算术转换 

     如果某个操作符的各个操作数属于不同的类型,那么我们得将其转换位同一种类型,否则操作       就无法进行。下面的层次体系为寻常算术转换

    

      其等级由上往下降。

7、问题表达式解析  

        表达式1:

        

       表达式2:

   

     同上,操作符的优先级只能决定⾃减--的运算在+的运算的前⾯,但是我们并没有办法得知+操         作符的左操作数的获取在右操作数之前还是之后求值,所以结果是不可预测的,是有歧义的。 

    表达式3:

   

     上面的表达式在不同的编译环境下的结果是不同的。

      

   表达式4: 

      

          上面的表达式虽然在大部分的编译器上结果是一样的。

          但是对于fun()-fun()*fun();这个语句我们只能通过操作符的优先级得知:先算乘法再算减法

          但是函数调用的先后顺序是没办法得知的。

  表达式5:

          

  

 建议:即使有了操作符的优先级和结合性,我们写出的表达式依然有可能不能通过操作符的属性               确定唯⼀的计算路径,那这个表达式就是存在潜在⻛险的,建议不要写出特别复杂的表达               式。 我们可以将其分割成几个表达式,这样对于代码的理解也更加容易,还有后期对于代             码的维护也更加容易。


http://www.kler.cn/a/401573.html

相关文章:

  • 小学知识相关链接
  • 阿里云轻量应用服务器可以用在哪些场景呢
  • 《YOLO:目标检测领域的璀璨之星》
  • 网络安全之信息收集-实战-2
  • 青训营刷题笔记09
  • 【mongodb】社区版8:改变配置bindip和授权
  • Spire.PDF for .NET【页面设置】演示:更改 PDF 页面大小
  • 外汇市场中的羊群效应:如何克服盲目追随
  • CC工具箱使用指南:【CAD导出界址点Excel】
  • Windows多JDK版本管理工具JVMs
  • 了解鱼叉式网络钓鱼攻击的社会工程学元素
  • 软件工程期末复习-用例建模
  • 适应等保的Windows系统和Linux系统安全加固V1.2.0版本
  • [安洵杯 2019]iamthinking-parse_url绕过thinkphp6.0反序列化
  • 高亮变色显示文本中的关键字
  • 诗韵--代码之外的生活
  • 让conda的python能够使用系统的apt安装的包
  • k8s 中传递参数给docker容器
  • 如何基于Netty手写简单的Tomcat?
  • React合成事件及其核心思想详解