操作符详解(上) (C语言)

操作符详解(上)

  • [一. 进制转换](#一. 进制转换)
    • [1. 二进制](#1. 二进制)
    • [2. 二进制的转换](#2. 二进制的转换)
  • [二. 原码 补码 反码](#二. 原码 补码 反码)
  • [三. 操作符的分类](#三. 操作符的分类)
  • [四. 结构成员访问操作符](#四. 结构成员访问操作符)
    • [1. 结构体的声明](#1. 结构体的声明)
    • [2. 结构体成员访问操作符](#2. 结构体成员访问操作符)

一. 进制转换

1. 二进制

在学习操作符之前,我们先了解一些2进制、8进制、10进制等的问题,我们在平时的学习中经常听到关于进制转换的问题,其实就是数字的表达形式不同,比如我们将数字15用不同的进制表示出来:

(另外16进制前面加的是0x,8进制前面加的是0)

我们重点介绍一下二进制:

首先我们还是得从10进制讲起,其实10进制是我们⽣活中经常使用的,我们已经形成了很多尝试:

• 10进制中满10进1

• 10进制的数字每一位都是0~9的数字组成

其实二进制也是一样的

• 2进制中满2进1

• 2进制的数字每⼀位都是0~1的数字组成

那么1101 就是二进制的数字了。

2. 二进制的转换

(1) 2进制转8进制 :比如15的二进制是1111,那么换成8进制就是利用15除以8看每次的余数和商,那么8进制就是17,其实8进制的每⼀位是有权重的,8进制的数字从右向左是个位、⼗位、百位...,分别每⼀位的权重是8^0^、8^1^、8^2^...那么15也就是8^0^ *7+8^1^ *1,这就是15从二进制转成了8进制。

(2) 10进制转2进制 :道理是一样的,10进制的每⼀位是有权重的,10进制的数字从右向左是个位、⼗位、百位...,分别每⼀位的权重是 10^0^ , 10^1^ , 10^2^...比如123用10进制表示就是123,而转为2进制:

二. 原码 补码 反码

当我们掌握了2进制等的转换,我们就要了解一下计算机中对于整数的三种表现形式,即整数的原码、补码、反码有符号整数 的三种表示方法均有符号位数值位 两部分,2进制序列中,最高位的1位是被当做符号位,剩余的都是数值位。
符号位都是用0表示"正",用1表示"负" 。(一个整型是由四个字节组成,一个字节占8个bit位,所以一共由32个bit组成)
正整数的原、反、补码都相同
负整数的三种表示方法各不相同

原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码。

反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。

补码:反码+1就得到补码。

补码得到原码也是可以使用:取反,+1的操作。

比如:15的原码补码反码是00000000000000000000000000001111

而 -15的原码是10000000000000000000000000001111,反码11111111111111111111111111110000(符号位不变,其他位按位取反),补码是11111111111111111111111111110001(末尾加1,得2进1,反码加1就是补码)

对于整形来说:数据存放内存中其实存放的是补码。为什么呢?

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

三. 操作符的分类

(1) 移位操作符 :<<左移操作符 --------- >>右移操作符,注意移位操作符只能适用于整数 !并且移动的是二进制位中的补码

下面展示一些 内联代码片

复制代码
javascript 复制代码
//左移操作符
int main()
{
	int a = 10;
	int b = a << 1;
	printf("%d %d", a, b);
	return 0;
}

对于左移操作符来说原理只有一种就是左边抛弃,右边补0

对于右移操作符也是一样的都是移动的2进制中的补码,右移操作符有两种方式:左边用0填充,右边补0左边用原该值的符号位填充,右边丢弃

(2) 位操作符 :&(按位与) |(按位或) ^(按位异或) ~(按位取反)

位操作符一般是由两个操作数来完成的,并且也只能用于整数。
& :对两个数的补码 进行运算(一个0一个1是0,两个1才是1)
| : 也是补码进行运算(只要有1就是1,两个0才是0)
^ : 相同为0相异为1(异或是支持交换律的)
~ : 单个数字 (按2进制的补码取反)

比如给大家举一个例子,不能创建临时变量(第三个变量),实现两个整数的交换。

下面展示一些 内联代码片

复制代码
javascript 复制代码
int main()
{
	int a = 3;
	int b = 9;
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	printf("%d %d\n", a,b);
	return 0;
}

在也就用到了位操作符^,后面大家多对这些运算符号进行实践,也会发现它们的实用性和便捷感。

(3)单目操作符 :! ++ -- & * - ~

这些都是单个数字完成的,特点就是只有一个操作数,很多符号我们也都认识。

!: 对一个表达式取反操作,即如果表达式为真,则结果为假。

++ -- : 比如1++就是1本身加上1等于2,1--就是1本身减去1等于0(但是需要注意的点是++放在1之前和1之后是不一样的)
& :取地址操作符

  • :解引用操作符
    在单目操作符中只有 & 和 * 没有介绍,这2个操作符我们在后期学习指针的时候会详细的介绍。
    (4) 逗号表达式 :1 exp1, exp2, exp3, ...expN
    逗号表达式,就是⽤逗号隔开的多个表达式。逗号表达式,从左向右依次执行。整个表达式的结果是最后⼀个表达式的结果。
    (5) 下标访问[]、函数调用()

四. 结构成员访问操作符

1. 结构体的声明

什么结构体 ?在C语言中已经提供的内置类型比如char、short、int等,但是只有这些内置类型是不够的,所以增加了结构体 这种自定义的数据类型。其实结构体就是一些值的集合,类型不一定相同。struct 是结构体关键字。

结构体的声明:

下面展示一些 内联代码片

复制代码
javascript 复制代码
struct student
{
	//成员变量
	char name[20];
	int age;
	float score;	 
};

int main()
{
	int a = 0;
	struct student s1;
	struct student s2;
	return 0;
}

上述代码就是结构体的创建,首先我们就使用struct创建了一个结构体,包括字符型、整型等,然后这就相当于一个类型了,再看我们下面的代码,就像int a一样我们使用struct student也创建变量s1、s2等,当然像代码中的变量属于局部变量,如果需要全局变量我们可以定义在函数的外部。另外我们可以直接在结构体定义的括号外面直接定义变量(也是全局变量)。

2. 结构体成员访问操作符

结构体成员的直接访问 :结构体成员的直接访问是通过点操作符(.)访问的。点操作符接受两个操作数,使用方式:结构体变量.成员名

结构体成员的间接访问 :有时候我们得到的不是⼀个结构体变量,而是得到了⼀个指向结构体的指针。使用方式:结构体指针->成员名 ,如下所示:

以上就是操作符的部分解析,下一部分我也会及时更新。

相关推荐
WilenWu1 分钟前
线性和二次判别分析
人工智能·算法·机器学习
小蟒天天向上6 分钟前
1、案例二:使用Pandas库进行进行机器学习建模步骤【Python人工智能】
人工智能·python·pandas
2402_857589367 分钟前
概率预测的奥秘:深入sklearn模型的预测机制
人工智能·python·sklearn
不会倒的鸡蛋7 分钟前
深入理解数组及其操作
数据结构·算法·数组
chian-ocean10 分钟前
排序(冒泡排序、选择排序、插入排序、希尔排序)-->深度剖析(一)
数据结构·算法·排序算法
无水先生12 分钟前
高斯过程的数学理解
人工智能·算法·机器学习
常驻客栈12 分钟前
EtherCAT主站IGH-- 4 -- IGH之datagram_pair.h/c文件解析
c语言·ethercat主站·ethercat·常驻客栈·igh·ethercat主站igh
2023Fighting15 分钟前
哈希表(C++实现)
c++·哈希算法·散列表
只想摆烂@15 分钟前
C# 如何单纯的优化循环
开发语言·c#
阑梦清川41 分钟前
C++多态~~的两个特殊情况
开发语言·c++