操作符详解 [ 2 ]

1.逗号表达符

 

exp1,exp2,exp3,...expN

逗号表达式,就是用逗号隔开的多个表达式。

逗号表达式的特点是:

逗号表达式中的表达式会从左往右依次执行,整个表达式的结果是最后一个表达式的结果。

例子如下:

从左到右依次计算

a > b为假输出0,但没有变量存储它,不用管 ; a = b + 10 ,有赋值,a = 12 ; a !=0,为真,输出1,但是没有变量存储它,不用管 ; b = a + 1 ,有赋值,且为最后一个输出最终结果 -- 13 (记得用括号括起来)


2.下标引用,函数调用和结构成员

1.下标引用操作符 [ ]

操作数:一个数组名 + 一个索引值 ,下标引用操作符有两个操作数,分别是一个数组名和一个索引值

如 arr[ 9 ] -- 这个的操作数分别是 arr 和 9

2.函数调用操作符 ()

函数调用操作符接受一个或多个操作数:

“第一个操作数是函数名,剩余的操作数就是传递给函数的参数”

注意函数调用操作符只出现在函数的调用中,而函数的实现里的括号则不是函数调用操作符,而是我们的编程语法中必须出现的括号

下面那个函数调用中的操作符才是函数调用操作符,上面函数的实现里的括号则是我们编程的语法要求

 3.访问一个结构的成员

结构体是什么?结构体是由一批数据组合而成的结构型数据

c语言中创建变量需要我们引入类型,其中c语言给我们提供了几个固定的基本类型(int char....)

而当我们想要创建一个由多个不同的基本类型变量组合而成的结构体变量时,我们需要声明什么样的类型呢?

此时c语言给我们提供了一个灵活的选项,那就是允许我们自己创建类型来适配我们建立的结构体变量,而这个类型被我们称为结构体类型,那么如何创建一个结构体类型呢?

1.结构体类型的创建

struct xxx -- 结构体类型名

{

    结构体类型包含的变量

       如 int a;

        cahr c

        ......

}

2.结构体类型的使用

结构体类型作为结构体变量的声明使用,和我们平时的变量声明位置一致,且都是类型名 + 变量名 + 赋值操作

如 struc stu  a = {"张三“,20,”321564“ }

注意事项:结构体类型的类型名,是struct xxx ; 同时结构体变量的赋值操作要用花括号括起来,花括号内的赋值顺序与我们创建结构体类型时花括号内的变量顺序一致

 

 打印结构体变量的方法如上

注意事项

1.结构体变量由多个成员变量复合而成,但打印的时候我们只能一个个打印出复合在其中的成员变量。

2.打印结构体变量中的某一个成员变量时一.就用对应的打印类型声明符 二.用点操作符来访问结构体变量中的这个变量,格式如下  

结构体变量名 . 成员名(我们要访问的结构体变量中的那个成员变量的变量名)

s1.name

3.访问或者操纵结构体变量中的某一个成员变量时,要用.操作符来进行访问和操作

4.结构体变量也是一个变量,我们也需要为它开辟内存空间来存放它,既然有了内存空间,那这个空间就一定有地址,有地址我们就有指针,而结构体变量的指针类型就是

结构体类型名*  指针变量名

在用解引用操作符来找回结构体变量并且想通过这种方式来访问其内的成员变量时,依然是用 . 操作符,但是和之前不同的一点是,*指针变量名要用括号括住! 

当然除了上面这种方式我们还可以用   结构体指针操作 ->  来直接访问成员变量

 存有结构体地址的指针和结构体中的成员变量的变量名,用 -> 结构体指针操作符可以直接从指针访问成员变量


搞这么多操作符是为了什么?

是为了表达式求值

而表达式求值的顺序一部分是由操作符的优先性和结合性决定的,

同时,有些表达式的操作数在求值的过程中可能需要转换为其他类型

比如转换形式1 -- 隐式类型转换 -- 隐式就是在在我们看不到的地方转换

C的整型算术运算总是至少以默认整型类型的的精度来计算,而为了或得这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换被称为整型提升,而整型提升就是一种隐式类型转换1 -- 整型提升

如: char a, b ,c

...

a = b + c;

b 和c 的值被提升为普通整型,然后再执行加法运算

加法运算完成之后,结果被截断,然后再存储于a中 

整型提升的具体实例

触发整型提升的条件:

1.出现用于各类算术运算。包括加(+)、减(-)、乘(*)、除(/)、求余(或称模运算,%)、自增(++)、自减(--)共七种。

2. 执行算术运算的对象是char字符类型  /  short 短整型 或者是这两个的无符号版

满足上面这两个条件的时候就会发生整型提升。


在开始讲整型提升的时候必须得啰嗦两句:

1.拥有char字符类型的变量中所存储的并不是字符,而是字符的ascii码值,而真正存储到内存中的则是这个ascii 码值的补码

2.正数的原反补相同,负数的原码除符号位按位取反-- 反码 +1 -- 补码

5.c语言中存进内存空间的二进制均规定为补码!!!!!!!!,而计算机输出给我们的数则是基于补码编译过来的原码对应的十进制数。

3.当我们声明一个变量的类型时,如果只有int , char .... 等等,那么计算机会默认我们建立的是一个有符号数,也就是说这个变量存储的二进制数据有符号位,如果想存储无符号位的二进制数则必须用unsigned来修饰类型

4.对于二进制来说 ,若有一位等于0-1,则该位变成1,且其左边一位退1

如 010 - 1 = 001

5.计算机中进行的各种运算是基于我们给定的数的补码实现的!!!,即计算机计算的时候用的都是补码

6.计算机数据均是以补码形式存储,对数据进行操作时也是在对补码进行操作!!

7.如果我们存进char类型的数超出了ascii码最大值,或者低于ascii码最小值而我们仍要输出字符类型的char时,我们得到的结果规定为 ? 字符


具体过程为 : 一次截断 -- 补为整型 -- 二次截断(取决存到哪)

1.首先我们对存到short / char 类型变量中的值做类型判断

如 char a = 1; 1是整型 ,应由4个字节,32个比特的空间来存储,但是!!

 char 类型-- 1个字节 short类型 -- 2个字节,也就是说我们提供的内存空间并不足以存储整型

2.此时计算机就会自动帮我们进行截断,即超出八个比特的二进制数被直接舍弃,然后再将舍弃后得到的八个比特存到char或short中

3.判断是否有算术运算+char/short类型操作数(只要有算术运算符和char/short类型操作数同时出现就算是),有的话这个操作数自动从8个bit为扩张到32个bit位(以char为例)

规则是 有符号位的话:扩张的二进制数均取符号位,无符号位的话均取0

4.扩张完后进行运算,若将运算结果再一次存到char / short 的话,则要发生第二次截断!,此时我们才能够得到最终的补码


隐式类型转换2 -- 算术转换

1.char和short没有算术转换,只有整型提升,且无论一个算术操作符的左右分别是char char 还是 short short 还是 short char,都一定会发生的整型转换

而非char,short 的类型能发生的转换则是算术转换,且是在操作数两边的类型不同时才会发生

那么什么是算术转换呢?

-- 如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数转换为另一个操作数的类型,否则操作就无法进行。

转换的规律是低字节的类型转换为高字节的类型

 

(打印sizeof的时候用的是 %u)


操作符的属性

一个表达式的计算分为两步

1.判断是否需要类型转换,若需要则转换,否则不转换

2.判断表达式中的运算顺序 -- 优先级 + 结合性判断(必须在优先级都相同的情况下才考虑结合性) 

相邻操作符不相同的情况下就会出现优先级,优先级高的先计算

如上图,+ 号优先级比 * 号高,所以先算 * 号 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值