C语言总结八:操作符详细总结

本文详细总结了C语言中的各种操作符,包括数据的原码、反码、补码和常见进制转换,算术操作符、移位操作符、位操作符,以及赋值操作符、单目操作符、条件操作符等。通过学习,可以深入理解C语言中操作符的使用方法、适用场景和注意事项,提升编程基础。
摘要由CSDN通过智能技术生成

       

目录

一、数据的原码、反码、补码和常见进制及进制转换(铺垫知识)

1.1 数据的原码、反码、补码(重点)

1.2 常见进制

1.2.1 二进制(重点)

1.2.2 八进制

1.2.3 十进制

1.2.4十六进制(重点)

1.3 进制之间的转换(在内存中仍然是以补码进行运算的)

1.3.1 将二进制、八进制、十六进制转换为十进制

1.3.2 将十进制转换为二进制、八进制、十六进制

1.3.3 二进制和八进制、十六进制的转换

二、算术操作符

三、移位操作符

3.1 左移操作符<<

3.2 右移操作符>>

四、位操作符

4.1 练习

五、赋值操作符

六、单目操作符(重点)

6.1 逻辑反操作符!

6.2 负值-、正值+ 操作符

6.3 sizeof 操作符

6.3.1 sizeof计算基本数据类型的所占字节数大小

6.3.2 sizeof 中表达式不参与计算

6.3.3 sizeof计算计算一维数组元素个数和二维数组的行数和列数

6.4.4 数组封装内部不可以用公式计算数组长度!​编辑

6.4 按位取反操作符~(1变为0,0变为1)

6.4.1 练习1 :把整型数字13的二进制数,从低到高的第四位由1改成0

6.5 自增操作符++、自减操作符--

6.6取地址操作符&、解引用操作符或者说间接访问操作符*

6.9 强制类型转换操作符()

七、关系操作符

八、逻辑操作符

8.1 360经典笔试题(考察点:短路运算符)

九、条件操作符

十、逗号表达式

十一、下标引用操作符[ ]

十二、函数调用

十三、结构成员访问

13.1 结构体的理解

13.2 结构体的类型的声明、定义、初始化

13.3 结构体成员的3种访问方式

13.4 结构体数组

十四、表达式求值(重点)

14.1 隐式类型转换

14.1.1 整型提升的概念和意义

14.2.2 如何进行整型提升

14.2 算术转换

14.3 操作符的属性

14.4 问题表达式解析


学习C语言中的各种操作符的使用方法及使用场景,可以让我们对于底层编译器的运算逻辑和过程更加清楚,同时能够减少开发中出现的小错误。本篇博客详细总结C语言中的操作符的使用方法、适用场景、及注意事项,学完本篇博客,可以让我们对于各种运算更加清晰,这也是开发人员的基本功。

操作符分类:

一、数据的原码、反码、补码和常见进制及进制转换(铺垫知识)

        进位制/位置计数法是一种记数方式,故亦称进位记数法/位值计数法,可以用有限的数字符号代表所有的数值。可使用数字符号的数目称为基数或底数,基数为n,即可称n进位制,简称n进制。现在最常用的是十进制,通常使用10个阿拉伯数字0-9进行记数。 对于任何一个数,我们可以用不同的进位制来表示。常用的进制有:二进制、八进制、十进制、十六进制,在计算机中,数据的存储其实存储的是数据的二进制!整数在内存中存放的是数据的补码,因此在内存中对于整数的运算也是以补码进行运算的。下期博客总结数据在内存中的存储,相信会有更加深刻的理解!加油!

1.1 数据的原码、反码、补码(重点)

        数据在内存中都是以二进制的形式存储的,对于整数来说,整数二进制有3种表示形式:原码、反码、补码;有符号整数的三种表示方法均有符号位和数值位两部分,二进制序列中,最高位的1位是被当做符号位,剩余的都是数值位。符号位都是用0表示“正”,用1表示“负”。对于无符号的整数来说,三种表示方法所有位均是数值位。

(1)正整数:原码、反码、补码相同;

(2)负整数:原码、反码、补码必须要进行计算,按照如下规则进行计算:

  1. 按照数据的数值直接写出的二进制序列就是原码;
  2. 原码的符号位不变,其他位按位取反,得到的就是反码;
  3. 反码+1,得到的就是补码;
  4. 补码得到原码也是可以使用:取反,+1的操作。

       对于整数来说,整数中在内存中存储的是补码,这是因为:在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一计算处理; 同时,加法和减法也可以统一处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

     

//举例理解为什么存放的是补码?
#include <stdio.h>
int main()
{
   // 1-1=0如何在内存中计算?CPU只有加法器,因此执行以下运算: 1-1相当于1+(-)1

   //方式1:假设存储的是原码
   //1的原码:00000000 00000000 00000000 00000001
  //-1的原码:10000000 00000000 00000000 00000001
    //结果为:10000000 00000000 00000000 00000010  (-2) 不正确

   //方式2:假设存储的是反码
   //1的反码:00000000 00000000 00000000 00000001
  //-1的反码:11111111 11111111 11111111 11111110
    //结果为:11111111 11111111 11111111 11111111  (一个非常大的负数) 不正确

   //方式3:假设存储的是补码
   //1的补码:00000000 00000000 00000000 00000001
  //-1的补码:11111111 11111111 11111111 11111111
   //结果为:100000000 00000000 00000000 00000000
   上述为33位,最高位会被舍弃,因此最终结果为:
             00000000 00000000 00000000 00000000  (0) 结果正确

 //因此,如果使用补码,计算更加合适!
  return 0;
}

       因此,在计算机内部,数据是以二进制的补码进行存储的,在进行计算的过程当然也是以二进制的补码进行计算的,这是由于数据写入内存与IO设备连接是通过总线通断电来传输数据的,内存条是一个非常精密的部件,包含了上亿个电子元器件,它们很小,达到了纳米级别。这些元器件,实际上就是电路;电路的电压会变化,要么是 0V,要么是 5V,只有这两种电压。5V 是通电,用1来表示,0V 是断电,用0来表示。所以,一个元器件有2种状态,0 或者 1。前面指针初识的时候学过,内存条划分的基本单位为一个字节byte(8个比特位),因此才会有各种数据类型,一个原因是:描述生活中的各种数据,另一个原因是:节省内存使用,更加高效的使用内存。

    内存的换算单位如下:

 为方便快捷进行二进制和十进制的转换,请记住以下数据:

       2^0=1;   2^1=2;       2^2=4;        2^3=8;         2^4=16;       2^5  =32; 

                    2^6=64;     2^7=128;    2^8=256;      2^9=512;     2^10=1024; 

      

//举例理解正数和负数在内存中存放

#include <stdio.h>
int main()
{
   int a = 200;  //正数的原码反码补码均相同
   int b =-200; //负数便需要进行计算

   //a和b在内存中的存储如下:4个字节,一共32个比特位:
  // a的补码: 00000000 00000000 00000000 11001000  (2^7+2^6+2^3=128+64+8=200)

  // b的原码:10000000 00000000 00000000 11001000  (与正数相比,只是符号位变成1了 )
  // b的反码:11111111 11111111 11111111 00110111
  // b的补码:11111111 11111111 11111111 00111000  (内存中存放的便是这个二进制序列)

  //注意:补码往回推原码方法相同!

    return 0;
}

1.2 常见进制

       生活中一个数字默认就是十进制的,表示一个十进制数字不需要任何特殊的格式。但是,表示一个二进制、八进制或者十六进制数字就不一样了,为了和十进制数字区分开来,必须采用某种特殊的写法,具体来说,就是在数字前面加上特定的字符,也就是加前缀。进制也就是进位制。进行加法运算时逢X进一(满X进一),进行减法运算时借一当X,这就是X进制,这种进制也就包含X个数字,基数为X。十进制有 0~9 共10个数字,基数为10,在加减法运算中,逢十进一,借一当十。

1.2.1 二进制(重点)

       二进制由 0 和 1 两个数字组成,使用时必须以0b0B(不区分大小写)开头,二进制数运算规律是逢二进一。

在计算机内部,数据都是以二进制的形式存储的,二进制是学习编程必须掌握的基础。

二进制加减法和十进制加减法的思想是类似的:

  • 对于十进制,进行加法运算时逢十进一,进行减法运算时借一当十;
  • 对于二进制,进行加法运算时逢二进一,进行减法运算时借一当二。

1.2.2 八进制

       八进制由 0~7 八个数字组成,使用时必须以0开头(注意是数字 0,不是字母 o),八进制数运算规律是逢八进一。

八进制有 0~7 共8个数字,基数为8,加法运算时逢八进一,减法运算时借一当八。

1.2.3 十进制

        十进制由 0~9 十个数字组成,没有任何前缀,和我们平时的书写格式一样,十进制数运算规律是逢十进一,不再赘述。

      在printf函数中%d打印的便是有符号的十进制数(因此要把补码转换成原码,然后计算对应的十进制数才是结果),%u打印的是无符号的十进制数(因此,它的所有位都是数值位,直接按位加权求和即可!)

1.2.4十六进制(重点)

       十六进制由数字 0~9、字母 A~F 或 a~f(不区分大小写,它们分别表示十进制数10~15),组成,使用时必须以0x0X(不区分大小写)开头 。十六进制数运算规律是逢十六进一。

     十六进制中,用A来表示10,B表示11,C表示12,D表示13,E表示14,F表示15,因此有 0~F 共16个数字,基数为16,加法运算时逢16进1,减法运算时借1当16。

      在C语言中,地址占4个字节,一共32个比特位,为了展示方便通常用十六进制,因此8位十六进制数便对应着一个地址编号!

1.3 进制之间的转换(在内存中仍然是以补码进行运算的)

1.3.1 将二进制、八进制、十六进制转换为十进制

         二进制、八进制和十六进制向十进制转换都非常容易,就是“按权相加”。所谓“权”,也即“位权”。

假设当前数字是 N 进制,那么:

  • 对于整数部分,从右往左看,第 i 位的位权等于N^i-1
  • 对于小数部分,恰好相反,要从左往右看,第 j 位的位权为N^-j。

       更加通俗的理解是,假设一个多位数(由多个数字组成的数)某位上的数字是 1,那么它所表示的数值大小就是该位的位权。

1.3.2 将十进制转换为二进制、八进制、十六进制

        将十进制转换为其它进制时比较复杂,整数部分和小数部分的算法不一样,下面我们分别讲解。

下表列出了前 17 个十进制整数与二进制、八进制、十六进制的对应关系:

1.3.3 二进制和八进制、十六进制的转换

      其实,任何进制之间的转换都可以使用上面讲到的方法,只不过有时比较麻烦,所以一般针对不同的进制采取不同的方法。将二进制转换为八进制和十六进制时就有非常简洁的方法,反之亦然。

//举例理解对于负数的转换(内存中不论是正数还是负数,都是以补码进行计算,不过整数的原码反码补码均相同)

//十进制数-100转二进制:
-100的原码:10000000 00000000 00000000 01100100
-100的反码:11111111 11111111 11111111 10011011
-100的补码:11111111 11111111 11111111 10011100

//因此-100的二进制为:11111 11111111 11111111 10011100


//二进制数(有符号)  11011100转十进制数
//最高位为符号位代表这是负数,然后推回原码,计算对应的十进制数
       //按位取反: 10100011
    //加1得到原码: 10100100进而计算十进制数   -(2^5+2^2=32+4)=-36

二、算术操作符

       同数学运算一样,C语言中也有  +、- 、*、/、%算术操作符,/ 结果为商的部分,%为余数。

注意事项:

  1. 除了 % 操作符之外,其他的几个操作符可以作用于整数和浮点数。
  2. 对于 / 操作符如果两个操作数都为整数,执行整数除法。而只要有浮点数执行的就是浮点数除法。
  3. % 操作符的两个操作数必须为整数。返回的是整除之后的余数。
#include<stdio.h>
int main()
{
	/*第一种:结果为:1
    int a = 6 / 5;          //1.2
	printf("%d\n",a);
	
	第二种:结果为:1.000000
	float a=6/5;
	printf("%f\n",a);

	第三种:结果为:1.200000
	float a = 6.0/5;
	printf("%f\n",a);

	第四种:结果为:1.200000
	float a = 6/5.0;
	printf("%f\n", a);

	第五种:结果为:1.200000
	float a = 6.0/5.0;
	printf("%f\n", a);*/
	return 0;
}

      在C语言中, C 语言提供一些位运算符,用来操作二进制位。

          1.位运算符只能用于整数类型的数据,不能用于浮点型。

           2. 位运算符的运算过程都是基于二进制的补码运算。

三、移位操作符

  1. >>:右移操作符    
  2. <<:左移操作符

注意事项:

     移位操作符针对的是该数在内存中的补码,移位操作符的操作数只能是整数。并且对于位移运算不要移动负数位,这个是标准未定义的!

int num=10;
num>>-1
  • 28
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

未来可期,静待花开~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值