【C语言操作符详解(一)】--进制转换,原反补码,移位操作符,位操作符,逗号表达式,下标访问及函数调用操作符

目录

一.操作符的分类

二.二进制和进制转换

2.1--2进制转10进制

[​编辑 2.1.1--10进制转2进制数字](#编辑 2.1.1--10进制转2进制数字)

2.2--2进制转8进制和16进制

2.2.1--2进制转8进制

2.2.2--2进制转16进制

三.原码,反码,补码

四.移位操作符

4.1--左移操作符

4.2--右移操作符

五.位操作符:&,|,^,~

5.1--位操作符的理解与使用

5.2--相关练习

5.2.1--练习1:不能创建临时变量(第三个变量),实现两个整数的交换。

5.2.2--练习2:编写代码实现:求一个整数存储在内存中的二进制中1的个数

5.2.3--练习3:二进制位置0或者置1

[六.逗号表达式,下标访问 [],函数调用 ()](#六.逗号表达式,下标访问 [],函数调用 ())

6.1--逗号表达式

[6.2--[] 下标引用操作符](#6.2--[] 下标引用操作符)

[6.3--() 函数调用操作符](#6.3--() 函数调用操作符)


前言:上篇文章我们学习了函数递归的相关知识,今天我们将继续操作符的详解学习的第一部分,让大家对于c语言的操作符产生一些新的认识和想法。


一.操作符的分类

1.算术操作符:+ , - , * , / , %

2.移位操作符:<< , >>

3.位操作符:&, | ,^

4.赋值运算符:= , += ,- = ,*= ,/= ,%= ,<<= ,>>= , &= , |= ,^=

5.单目操作符:!,++ ,- - ,& ,* ,+(正),-(负) ,~ ,sizeof ,(类型)

6.关系操作符:> ,>= ,< ,<= ,== ,!=

7.逻辑操作符:&& ,|| ,!

8.条件操作符:exp1?exp2:exp3

9.逗号表达式:,

10.下标引用:【】

11.函数调用:()

12.结构成员访问:. , ->

上述的操作符中,有部分在之前的学习中有提到过,今天继续介绍一部分,其中有部分操作符和二进制有关系,我们先来学习一下二进制和进制转换的相关知识;


二.二进制和进制转换

2.1--2进制转10进制

--其实10进制的123表示的值是一百二十三,为什么是个值呢?其实10进制的每一位都是有权重的,进制的数字从右向左是个位,十位,百位......,分别每一位的权重是10^0,10^1,10^3;

如下图:

2进制和10进制是类似的,只不过2进制的每一位的权重,从右向左是:2^0,2^1,2^2......

如果是2机制的1101,该怎么理解呢?

2.1.1--10进制转2进制数字

简单的10进制数字可以直接通过凑的方法来转2进制;

2.2--2进制转8进制和16进制

2.2.1--2进制转8进制

--8进制的每一位是0~7的,0~7的数字,各自写成2进制,最多有3个2进制位就足够了,比如7的二进制是111,所以2进制转8进制的时候,从2进制序中右边低位开始向左每3个二进制位会换算一个8进制位,剩余不够3个2进制位的直接换算。

如:2进制的01101011,换成8进制:0153,8进制表示的时候前面加0;0开头的数字,会被当作8进制。

2.2.2--2进制转16进制

--16进制的数字每一位是0~9,a~f的,0~9,a~f的数字,各自写成2进制,最多有4个二进制位就足够了。比如f的二进制是1111,所以在2进制转16进制的时候,从2进制序列中右边低位开始向左每4个2进制位会换算一个16进制位,剩余不够4个2进制位的直接换算。

如:2进制的01101011,换成16进制:0x6b, 16进制表示的时候前面加0x


三.原码,反码,补码

--整数2进制的表示方法有三种,即原码,反码和补码(32位)

有符号整数 的三种表示方法均有符号位数值位 两部分,2进制序列中,最高位的1位是被当做符号位的,剩余的都是数值位,符号位都是用0表示正,用1表示负。

正整数的原,反,补码都相同。

负整数的三种表示方法各不相同,变换方式如下。

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

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

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

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

对于整型来说:数据存放内存中其实存放的是补码。

这是为什么呢?

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


四.移位操作符

<< 左移操作符

>> 右移操作符

注意:移位操作符的操作数只能是整数

4.1--左移操作符

--移位规则:左边抛弃,右边补0;

int num=10; 左移一位演示

4.2--右移操作符

1.逻辑右移:左边用0填充,右边丢弃

2.算术右移:左边用原该值的符号位填充,右边丢弃

--是逻辑右移还是算术右移取决于编译器,VS2022中采用的是算术右移。

int num=-1;逻辑右移一位演示

int num=-1;算术右移一位演示

注意:对于移位运算符,不要移动负数位,这个是标准没定义的。


五.位操作符:&,|,^,~

5.1--位操作符的理解与使用

位操作符有:

cpp 复制代码
&      //按位与
|      //按位或
^      //按位异或
~      //按位取反

注意:他们的操作数必须是整数。

我们可以通过一串代码直观了解一下这几个位操作符,注意看注释,来理解是如何使用的。

cpp 复制代码
#include <stdio.h>
int main()
{
    int num1 = -3;
    int num2 = 5;
// &--按位与--对应的二进制位进行与运算,只要有0则为0,两个同时为1,才为1
    printf("%d\n", num1 & num2);
// |--按位或--对应的二进制位进行或运算,只要有1则为1,两个同时为0,才为0
    printf("%d\n", num1 | num2);
// ^--按位异或--对应的二进制位相同为0,相异为1
    printf("%d\n", num1 ^ num2);
// ~--按位取反--二进制位0变为1,1变为0
    printf("%d\n", ~0);
    return 0;
}

5.2--相关练习

5.2.1--练习1:不能创建临时变量(第三个变量),实现两个整数的交换。

cpp 复制代码
int main()
{
	int a = 0;
	int b = 0;
	printf("请输入两个整数:");
	scanf("%d %d", &a, &b);
	printf("交换前:a=%d b=%d\n", a, b);
	a = a ^ b;// a'=a^b;
	b = b ^ a;// b=b^a'=b^a^b=a;
	a = a ^ b;// a=a'^b=a^b^a=b;
	printf("交换后:a=%d b=%d\n", a, b);
	return 0;
}

在这里补充两个重要结论:

cpp 复制代码
a ^ a = 0;
a ^ 0 = a;
//且异或支持交换律;
//如:3 ^ 6 ^ 6 = 3
//    6 ^ 3 ^ 6 = 3

5.2.2--练习2:编写代码实现:求一个整数存储在内存中的二进制中1的个数

cpp 复制代码
int count_bits1_of_n(int n)
{
	//int count = 0;
	//for (int i = 0;i < 32;i++)
	//{
	//	if(((n >> i) & 1)==1)
	//	count++;
	//}
	//return count;
	     //优化方案
	int count = 0;
	while (n)
	{
		n = n & (n - 1);
//用一次这个公式就相当于将一个1变为0,即去掉一个1,当n为0时,1全部去掉,且刚好循环结束
		count++;
	}
}

int main()
{
	int n = 0;
	scanf("%d", &n);
	int ret = count_bits1_of_n(n);
	printf("%d", ret);
	return 0;
}

注意:n=n&(n-1)这个公式的用法在这里很重要。

5.2.3--练习3:二进制位置0或者置1

编写代码将13二进制序列的第五位修改为1,然后再改回0;

cpp 复制代码
int main()
{
	int a = 13;
	a = a | (1 << 4);
	printf("a=%d\n", a);
	a &= ~(1 << 4);
	printf("a=%d\n", a);
	return 0;
}

六.逗号表达式,下标访问 [],函数调用 ()

6.1--逗号表达式

cpp 复制代码
exp1, exp2, exp3, ...expN

逗号表达式,就是用逗号隔开的多个表达式。从左向右依次执行整个表达式的结果是最后一个表达式的结果

cpp 复制代码
//代码1
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗号表达式
c是多少?--c是13;



//代码2
if(a = b + 1,c = a / 2,d > 0)



//代码3
a = get_val();
count_val(a);
while (a > 0)
{
   //业务处理
    //...
   a = get_val();
   count_val(a);
}

如果使⽤逗号表达式,改写:
while (a = get_val(), count_val(a), a>0)
{
   //业务处理
}

6.2--[] 下标引用操作符

--操作数:一个数值名 + 一个索引值(下标)

cpp 复制代码
int arr[10]={0};//创建数组
arr[9] = 10;//运⽤下标引⽤操作符。
[ ]的两个操作数是arr和9。

6.3--() 函数调用操作符

cpp 复制代码
int Add(int x,int y)
{
    return x + y;
}

int main()
{
    printf("hehe");//()是函数调用操作符
    int r = Add(3,5);//()是函数调用操作符
    // ()也是有操作数:函数名和参数都是()的操作数
    //()最少有一个操作数,就是函数名本身
    return 0;
}

结语:操作符详解的第一部分就到此结束了,在下一篇文章中我将继续为大家分享操作符详解的一些其他知识点,感谢大家的支持!

相关推荐
崔高杰1 小时前
On the Biology of a Large Language Model——Claude团队的模型理解文章【论文阅读笔记】其一CLT与LLM知识推理
论文阅读·人工智能·笔记·语言模型·自然语言处理
樂5021 小时前
关于 Web 服务器的五个案例
linux·服务器·经验分享
0509151 小时前
测试基础笔记第十四天
笔记
2301_817031651 小时前
C语言-- 深入理解指针(4)
c语言·开发语言·算法
·醉挽清风·2 小时前
学习笔记—双指针算法—移动零
c++·笔记·学习·算法
Ayanami_Reii2 小时前
Leetcode837.新21点
c++·笔记·算法
爱学习的章鱼哥2 小时前
如何实现一个可视化的文字编辑器(C语言版)?
c语言·编辑器·文本编辑器·程序设计·easyx
灏瀚星空3 小时前
从基础到实战的量化交易全流程学习:1.2 金融市场基础
笔记·python·信息可视化·系统架构·开源
盐烟3 小时前
C语言-函数练习1
c语言·开发语言·笔记
simple_whu3 小时前
Visual Studio C/C++编译器cl.exe的/source-charset与/execution-charset设置项
c语言·c++·visual studio