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

1. 操作符的分类

算术操作符: + 、- 、* 、/ 、%

移位操作符: <<  >>

位操作符: &  |  ^  `

赋值操作符: = 、+= 、 -= 、 *= 、 /= 、%= 、>= 、&= 、|= 、^=

• 单⽬操作符: !、++、--、&、*、+、-、~ 、sizeof、(类型) 

关系操作符: > 、>= 、< 、<= 、 == 、 != 

逻辑操作符: && 、|| 

条件操作符: ?  :

逗号表达式: ,

下标引⽤: []

函数调⽤: ()

结构成员访问: . 、 ->

上面的这些操作符中,我们在前面的博客已经讲过算术操作符、赋值操作符、逻辑操作符、条件操作符和部分的单目操作符,继续介绍另一部分,但是在这之前我们要知道一下二进制和进制转换的知识。

2.二进制

我们之前知道有很多进制,其实这些进制就是数组的不同表示形式而已。

比如:数值15的各种进制的表现形式:

15的2进制:1111
15的8进制:17
15的10进制:15
15的16进制:F

在讲二进制的时候我们首先要先从10进制来讲起,10进制在我们的生活中经常用。

10进制满10进1        10进制的数字每一位都是0-9的数字组成

二进制中满2进1        2进制的数字每一位都是0-1的数字组成

3   2进制和其他进制的转换

3.1  2进制转10进制数字

我们通过观察不难发现,10进制数其实就是字从右向左是个位、⼗位、百位....,分别每⼀位的权重是 10 , 10 , 10 ...

C语言--操作符的详解(上)_第1张图片

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

C语言--操作符的详解(上)_第2张图片

3.2 10进制转2进制数字

10进制的125转换的二进制:1111101

C语言--操作符的详解(上)_第3张图片

3.3 2进制转8进制和16进制 

3.3.1  2进制转8进制

8进制的数字每⼀位是0~7的,0~7的数字,各⾃写成2进制,最多有3个2进制位就⾜够了,⽐如7的⼆ 进制是111,所以在2进制转8进制数的时候,从2进制序列中右边低位开始向左每3个2进制位会换算⼀ 个8进制位,剩余不够3个2进制位的直接换算。(转2从右3个二进制为一组不够时左边补0)

如:2进制的01101011,换成8进制:0153,0开头的数字,会被当做8进制。

C语言--操作符的详解(上)_第4张图片

3.3.2 2进制转16进制

16进制的数字每⼀位是0~9,a ~f 的,0~9,a ~f 的数字,各⾃写成2进制,最多有4个2进制位就⾜够了, ⽐如 f 的⼆进制是1111,所以在2进制转16进制数的时候,从2进制序列中右边低位开始向左每4个2进 制位会换算⼀个16进制位,剩余不够4个⼆进制位的直接换算。(转2从右边4个为一组,不够时补0)

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

4. 原码、反码和补码

在整数的2进制表示方法有3种,即原码、反码和补码。有符号整数的三种表⽰⽅法均有符号位和数值位两部分,2进制序列中最高位为符号位,其余都是数值位。

符号位都是⽤0表⽰“正”,⽤1表⽰“负”。
int num=10;
//10是存放在整型变量num中,占4个字节==32bit位
//0      0000000000000000000000000001010
  |                    |
符号位                  数值位  

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

负整数的三种表示⽅法各不相同。

原码:直接将数值按照正负数的形式翻译成⼆进制;

反码:将原码的符号位不变,其他位依次按位取反;

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

注:反码得到原码也可以直接使用:取反,+1的操作。

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

因为:

5. 移位操作符

<< 左移操作符

>> 右移操作符

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

5.1 左移操作符

移位规则:左边抛弃、右边补0

比如; 有int num=10,执行num<<

C语言--操作符的详解(上)_第5张图片

 5.2 右移操作符

移位规则:⾸先右移运算分两种:

 (右移是逻辑右移还是算术右移,是取决于编译器的实现!!!,大部分的编译器是算术右移)

#include 
int main()
{
     int num = 10;
     int n = num>>1;
     printf("n= %d\n", n);
     printf("num= %d\n", num);
     return 0;
}

 逻辑右移:C语言--操作符的详解(上)_第6张图片

 算术右移:
C语言--操作符的详解(上)_第7张图片

6. 位操作符:&、|、^、~

& //按位与
| //按位或
^ //按位异或
~ //按位取反

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

代码使用:

#include 
int main()
{
     int num1 = -3;
     //10000000000000000000000000000011——原码
     //11111111111111111111111111111100——反码
     //11111111111111111111111111111101——补码
     int num2 = 5;
     //00000000000000000000000000000101——补码
     printf("%d\n", num1 & num2);//按(2进制)位与(只要有0就是0,两个同时为1才是1)
     printf("%d\n", num1 | num2);//按(2进制)位或(只要有1就是1,两个同时为0才是0)
     printf("%d\n", num1 ^ num2);//按(2进制)位异或(相同位0;相异为1)
     printf("%d\n", ~num2);//按(2进制)位取反(补码取反)
     return 0;
}

实践的运用:

不能创建临时变量(第三个变量),实现两个数的交换。

#include
int main()
{
	int a = 5;
	int b = 3;
	//a = a + b;
	//b = a - b;
	//a = a - b;
	这种写法的缺陷是:a和b如果非常大,求和后结果超过了整型的最大值
	a = a ^ b;
	b = a ^ b;
	a = a ^ b;
	//异或的特点
	//a^a=0;
	//0^a=a;
	printf("a=%d b=%d\n", a, b);
	return 0;
}

练习1:求⼀个整数存储在内存中的⼆进制中1的个数。

#include
int main()
{
	int a = 3;//如果考虑负数的话就写位int unsinged int a;
	int count = 0;
	int i = 0;
	for (i = 0; i < 32; i++)
	{
		if (((a >> i) & 1) == 1)//a&1=1说明a的二进制最后一位为1,反之为0;
		{
			count++;
		}
	}
	printf("%d ", count);
    //方法2:
    while (a)
	{
		if (a % 2 == 1)
		{
			count++;
			a /= 2;
		}
	}
	printf("%d ", count);
    //方法3
    while (a)
	{
		a = a & (a - 1);
		count++;
	}
    printf("%d ", count);
	return 0;
}

练习2:⼆进制位置0或者置(编写代码将13⼆进制序列的第5位修改为1,然后再改回0)

#include
int main()
{
	int n = 13;
	int a = n | (1 << 4);
	int b=n& ~(1 << 4);
	printf("%d %d\n", a, b);
	return 0;
}

7.  单⽬操作符

单⽬操作符有这些: !、++、--、&、*、+、-、~ 、sizeof、(类型)

8. 逗号表达式

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

exp1, exp2, exp3, …expN

逗号表达式,从左向右依次执⾏。整个表达式的结果是最后⼀个表达式的结果。

C语言--操作符的详解(上)_第8张图片

 9. 下标访问[]、函数调⽤()

9.1 [ ] 下标引⽤操作符

操作数:⼀个数组名 + ⼀个索引值

int arr[10];//创建数组
arr[9] = 10;//实⽤下标引⽤操作符。
[ ]的两个操作数是arr和9。

9.2 函数调⽤操作符

#include 
void test1()
{
      printf("hehe\n");
}

int main()
{
     test1(); //这⾥的()就是作为函数调⽤操作符。
  return 0;
}

 C语言--操作符的详解(上)_第9张图片

你可能感兴趣的:(C语言,c语言,开发语言)