C语言 —— 愿此世如黄金般辉煌 - 进制转换与操作符详解

目录

[1. 操作符的分类](#1. 操作符的分类)

[2. ⼆进制和进制转换](#2. ⼆进制和进制转换)

[2.1 2进制转10进制](#2.1 2进制转10进制)

[2.2 10进制转2进制](#2.2 10进制转2进制)

[2.3 2进制转8进制](#2.3 2进制转8进制)

[2.4 2进制转16进制](#2.4 2进制转16进制)

[3. 原码、反码、补码](#3. 原码、反码、补码)

[4. 移位操作符](#4. 移位操作符)

[4.1 左移操作符](#4.1 左移操作符)

[4.2 右移操作符](#4.2 右移操作符)

[5. 位操作符:&、|、^、~](#5. 位操作符:&、|、^、~)

[5.1 & 按位与](#5.1 & 按位与)

[5.2 | 按位或](#5.2 | 按位或)

[5.3 ^ 按位异或](#5.3 ^ 按位异或)

[5.4 ~ 按位取反](#5.4 ~ 按位取反)

[6. 结构成员访问操作符](#6. 结构成员访问操作符)

[6.1 什么是结构体](#6.1 什么是结构体)

[6.2 结构体成员的直接访问](#6.2 结构体成员的直接访问)

[6.3 结构体成员的间接访问](#6.3 结构体成员的间接访问)

[7. 操作符的属性:优先级与结合性](#7. 操作符的属性:优先级与结合性)

[7.1 优先级](#7.1 优先级)

[7.2 结合性](#7.2 结合性)


1. 操作符的分类

1. 算术操作符:+ - * / %
2. 移位操作符:<< >>
3. 位操作符:& | ^
4. 赋值操作符:= += -= = /= %= <<= >>= &= |= ^=
5. 单目操作符:! ++ -- & * + - ~ sizeof (类型)
6. 关系操作符:> >= < <= == !=
7. 逻辑操作符:&& ||
8. 条件操作符:?:
9. 逗号表达式:,
10. 下标引用:[ ]
11. 函数调用:( )
12. 结构体成员访问: . ->


2. ⼆进制和进制转换

其实我们经常能听到2进制、8进制、10进制、16进制这样的讲法,那是什么意思呢?其实2进制、8进制、10进制、16进制是数值的不同表⽰形式⽽已
二进制:

2进制中满2进1,2进制的数字每⼀位都是0~1的数字组成:

128 64 32 16 8 4 2 1

十进制12的二进制就是1100,也就是取上面8 4 2 1的前两位

2.1 2进制转10进制

10进制中的123,从右到左依次是个位,十位,百位,每一位都有自己的权重,每一位各自乘以各自的权重然后加和就是表示的值

2进制转换10进制的12也相同

2.2 10进制转2进制

2.3 2进制转8进制

8进制的数字每⼀位是0~7的,0~7的数字,各⾃写成2进制,最多有3个2进制位就⾜够了,⽐如7的⼆进制是111,所以在2进制转8进制数的时候,从2进制序列中右边低位开始向左每3个2进制位会换算⼀个8进制位,剩余不够3个2进制位的直接换算
如:2进制的01101011,换成8进制:0153,0开头的数字,会被当做8进制

2.4 2进制转16进制

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

10 = A/a 11 = B/b 12 = C/c 13 = D/d 14 = E/e 15 = F/f
如:2进制的01101011,换成16进制:0x6b,16进制表⽰的时候前⾯加0x


3. 原码、反码、补码

整数的2进制表示方法有三种,即原码、反码和补码

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

符号位都是⽤0表⽰"正",⽤1表⽰"负"
正整数的原、反、补码都相同
负整数的三种表示方法各不相同

原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码
补码:反码+1就得到补码

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

数据存放内存中其实存放的是补码


4. 移位操作符

移位操作符的操作数只能是整数,移动操作符移动的是二进制位

4.1 左移操作符

移位规则:左边抛弃、右边补0,左移的效果和乘2类似

复制代码
#include <stdio.h>

int main()
{
	int num = 10;
	int n = num << 1;

	printf("n= %d\n", n);
	printf("num= %d\n", num);

	return 0;
}

4.2 右移操作符

与左移操作符的效果相反,右移的效果和除2类似

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

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

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

复制代码
#include <stdio.h>

int main()
{
	int num = 10;
	int n = num >> 1;

	printf("n= %d\n", n);
	printf("num= %d\n", num);

	return 0;
}


对于移位运算符,不要移动负数位,这个是标准未定义的

例如:

复制代码
int num = 10;
num>>-1;

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

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

位操作符的 操作数必须是整数

5.1 & 按位与

当两个对应的二进制位都为 1 时,结果位才为 1,否则为 0,也就是同1为1,不1为0

复制代码
0000000000 0000000000 0000000001 11 a
0000000000 0000000000 0000011000 11 b

0000000000 0000000000 0000000000 11 a & b

5.2 | 按位或

当两个对应的二进制位中只要有一个为 1,结果位就为 1,当两个位都为 0 时,结果位才为 0

也就是有1为1,无1为0

复制代码
0000000000 0000000000 0000000001 01 a
0000000000 0000000000 0000000000 11 b

0000000000 0000000000 0000000001 11 a | b

5.3 ^ 按位异或

当两个对应的二进制位不同(一个为 0,另一个为 1)时,结果位为 1,当两个位相同(都为 0 或都为 1)时,结果位为 0

也就是不同为1,相同为0

复制代码
0000000000 0000000000 0000000001 01 a
0000000000 0000000000 0000000000 11 b

0000000000 0000000000 0000000001 10 a ^ b

5.4 ~ 按位取反

顾名思义,将每个二进制位中的 0 变为 1,1 变为 0

复制代码
0000000000 0000000000 0000000001 01 a

1111 1111 11 1111 1111 11 1111 1111 10 10 ~a

6. 结构成员访问操作符

6.1 什么是结构体

结构是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量,如:
标量、数组、指针,甚⾄是其他结构体

结构体的语法结构:

复制代码
struct tag
{
	member - list;

}variable - list;

描述⼀个学生:

复制代码
struct Stu
 {
   char name[20];//名字
   int age;//年龄 
   char sex[5];//性别
   char id[20];//学号 
 }; //分号不能丢

结构体的定义:

复制代码
struct Point
 {
   int x;
   int y;
 }p1;        //声明类型的同时定义变量p1        
struct Point p2;    //定义结构体变量p2 

结构体的指定顺序初始化:

复制代码
//指定顺序初始化
struct Point p3 = { 10, 20 };
struct Stu        //类型声明
{
	char name[15];//名字
	int age;
	//年龄
};
struct Stu s1 = { "zhangsan", 20 };//初始化
struct Stu s2 = { .age = 20, .name = "lisi" };//指定顺序初始化

结构体嵌套初始化:

复制代码
struct Node
{
	int data;
	struct Point p;
	struct Node* next;

}n1 = { 10, {4,5}, NULL };

//结构体嵌套初始化
struct Node n2 = { 20, {5, 6}, NULL };//结构体嵌套初始化

6.2 结构体成员的直接访问

结构体成员的直接访问是通过点操作符(.)访问的,点操作符接受两个操作数

语法结构:结构体变量.成员名

复制代码
#include <stdio.h>

struct Point
{
	int x;
	int y;
}p = { 1,2 };

int main()
{
	printf("x: %d y: %d\n", p.x, p.y);

	return 0;
}

6.3 结构体成员的间接访问

有时候我们得到的不是⼀个结构体变量,⽽是得到了⼀个指向结构体的指针

语法结构:结构体指针->成员名

复制代码
#include <stdio.h>
struct Point
{
	int x;
	int y;
};

int main()
{
	struct Point p = { 3, 4 };
	struct Point* ptr = &p;

	ptr->x = 10;
	ptr->y = 20;

	printf("x = %d y = %d\n", ptr->x, ptr->y);

	return 0;
}

7. 操作符的属性:优先级与结合性

优先级与结合性决定了表达式求值的计算顺序

7.1 优先级

优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执⾏,各种运算符的优先级是不⼀样的

举个例子:1 3 + 4 * 5;

上⾯⽰例中,表达式 3 + 4 * 5 ⾥⾯既有加法运算符( + ),⼜有乘法运算符( * )。由于乘法的优先级⾼于加法,所以会先计算 4 * 5 ,⽽不是先计算 3 + 4

7.2 结合性

如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符是左结合,还是右结合,决定执⾏顺序

⼤部分运算符是左结合(从左到右执⾏),少数运算符是右结合(从右到左执⾏),⽐如赋值运算符( = )
一般来说:!> 算术运算符 > 关系运算符 > 逻辑运算(&& > ||) > 赋值运算符
优先级链接:

C 运算符优先级 - cppreference.comhttps://zh.cppreference.com/w/c/language/operator_precedence


如宝石般璀璨

相关推荐
勇闯逆流河1 小时前
【数据结构】堆
c语言·数据结构·算法
jz_ddk5 小时前
[学习] RTKLib详解:rtcm2.c、rtcm3.c、rtcm3e与rtcmn.c
c语言·学习·算法
darkchink6 小时前
[LevelDB]LevelDB版本管理的黑魔法-为什么能在不锁表的情况下管理数据?
c语言·数据库·c++·oracle·数据库开发·dba·db
ha20428941946 小时前
c++学习之--- list
c语言·c++·学习·list
JeffersonZU8 小时前
【数据结构】1-4算法的空间复杂度
c语言·数据结构·算法
瓦力wow11 小时前
c语言 写一个五子棋
c语言·c++·算法
hjjdebug12 小时前
c/c++数据类型转换.
c语言·c++·数据类型变换
花火QWQ12 小时前
图论模板(部分)
c语言·数据结构·c++·算法·图论
Pacify_The_North13 小时前
【进程控制二】进程替换和bash解释器
linux·c语言·开发语言·算法·ubuntu·centos·bash
wuqingshun31415913 小时前
经典算法 (A/B) mod C
c语言·开发语言·c++·算法·蓝桥杯