【揭秘!】这里有你从未听过的独特见解,快来点赞关注,开启智慧之旅
目录
1.操作符的分类
算术操作符:+ - * / %
位移操作符: << >>
位操作符 : & | ^
赋值操作符: = += -= *= /= %= <<= >>= &= |= ^=
单目操作符: ! ++ -- & * + - ~ sizeof (类型)
关系操作符: > >= < <= == !=
逻辑操作符: && ||
条件操作符: ? :
逗号表达式: ,
下表引用 : [ ]
函数调用 : ( )
结构体成员访问: . ->
2.二进制和进制转换
我们经常可以听到2进制、8进制、10进制、16进制这样讲法,在我们日常中,最常见的便是10进制。我们知道10进制是每逢10进1。类似的2进制每逢2进1,8进制每逢8进1,16进制每逢16进1。
举个例子:数值15的各种进制的表达式
1 15的2进制:1111
2 15的8进制:17
3 15的10进制:15
4 15的16进制:F
2.1 二进制转十进制
其实10进制的123表示的值是一百二十三,因为10进制的每一位是权重的,10进制的数字从右向左是个位、十位、百位......,分别每一位的权重是:10^0,10^1,10^2......
如下图:
2进制和10进制是类似的,只不过2进制的每一位权重,从右向左是:2^0,2^1,2^2......
举例:2进制的1101
2.2 十进制转二进制
2.3 二进制转八进制
8进制的数字每一位是由0~7的数字组成,各自写成2进制,最多有3个2进制位就够了,比如7的二进制是111,所以在2进制转8进制数的时候,从2进制序列中右边低位开始向左每3个2进制位换算一个8进制位,剩余不够3个2进制位的直接进行换算。
例如:2进制的01101011,换成8进制:0153, 0数字开头的数字会被当做8进制。
2.4 二进制转十六进制
16进制的数字每一位是由0~9,a~f 的数字组成,各自写成2进制,最多有4个2进制就够了,比如 f 的二进制是1111,所以在2进制转换成16进制数的时候,从2进制序列中右边低位开始向左每4个2进制位换算一个16进制,剩余不够4个二进制位的直接换算。
例如:2进制的01101011,换成16进制:0x6b,16进制表示的时候面加0x
3.原码、反码、补码
整数的二进制表示方法有三种,即原码、反码、补码
无符号整数的三种表达式均有符号位和数值位两部分,2进制序列中,最高的1位是被当做符号位,剩余的都是数值位。
注:符号位都是用0表示“正”,用1表示“负”
1.正整数的原、反、补码都相同。
2.负整数的三种表示方法各不相同。
原码:直接将数值按照正负数的形式翻译成二进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
注:反码得到原码也可以使用:取反,+1的操作。
为什么对于整形来说:数据存放在内存中,其实是存放的补码
因为在计算机系统中,数值一律用补码来表示和存储。原因在于,使用补码,可以将符号位和数值域统一处理;同时,加法和减法也可以统一处理(CPU只有加法器),此外补码与原码互相转换,其运算过程是相同的,不需要额外的硬件电路。
4.位移操作符
<< 左移操作符
>> 右移操作符
注:位移操作符的操作数只能是整数
4.1左移操作符
移位规则:左边抛弃、右边补0
#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右移操作符
移位规则:首先右移运算分为两种:
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;
}
逻辑右移1位演示:
算术右移1位演示:
注:对于移位运算符,不要移动负数位,这个标准是未定义的。
5.位操作符:&、|、^、~
1 & //按位与 :有0则0,双1才1
2 | //按位或 :有1则1,双0才0
3 ^ //按位异或 :相同取0,不同取1
4 ~ //按位取反
注:它们的操作数必须是整数。
代码举例:
#include <stdio.h>
int main()
{
int num1 = -3;
int num2 = 7;
printf("%d\n", num1 & num2);
printf("%d\n", num1 | num2);
printf("%d\n", num1 ^ num2);
printf("%d\n", ~0);
return 0;
}
6.单目操作符
单目操作符有这些: ! ++ -- & * + - ~ sizeof (类型)
单目操作符的特点是只有一个操作数,在单目操作符中只有 & 和 * 没有介绍,这两个操作符在指针的时候进行讲解。
7.逗号表达式
1 exp1,exp2,exp3,...expN
逗号表达式,就是用逗号隔开的多个表达式。
逗号表达式 ,从左向右依次执行,整个表达式的结果是最后一个的表达式的结果。
举例:
#include <stdio.h>
int main()
{
int a = 1;
int b = 2;
int c = (a > b, a = b + 10, b = a + 1);
printf("%d", c);
}
//最后输出 13
8.下标访问 [ ] 、函数调用 ( )
8.1 [ ] 下标引用操作符
操作数:一个数组名+一个索引值
1 int arr[10]; //创建数组
2 arr[9] =10; //实用下标引用操作符
3 [ ] 的两个操作数是 arr 和 9
8.2 ( ) 函数调用操作符
接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
#include <stdio.h>
void test1()
{
printf("chixiu\n");
}
void test2(const char* str)
{
printf("%s\n", str);
}
int main()
{
test1(); //这里的( )就是作为函数调用操作符
test2("hello bit."); //这里的( )就是函数调用操作符
return 0;
}
9.结构成员访问操作符
9.1 结构体
C语言已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类型哈是不够的。假如我想和描述学生,描述一本书,这时单一的内置类型是不行的。描述一个学生需要姓名、年龄、学号、身高、体重等;描述一本书需要作者、出版社、定价等。C语言为了解决这个问题,增加了结构体这种定义的数据类型,让程序员可以自己创建合适自己的类型。
结构是一些值的集合,这些值称为成员变量。结构的每一个成员可以是不同类型的变量,如:标量、数组、指针,甚至是其他结构体。
9.2结构体的声明
struct tag
{
member-list;
}variable-list;
描述一个学生:
struct Stu
{
char name[20]; //名字
int age; //年龄
char sex[5]; //性别
char id[20]; //学号
}; //分号不能丢
9.3结构体变量的定义和初始化
//代码1:变量的定义
struct Point
{
int x;
int y;
}p1; //声明类型的同时定义变量p1
struct Point p2; //定义结构体变量p2
// p1 p2 都是全局变量
//代码2:初始化
struct Point p3 = { 10,20 };
struct Stu //类型声明
{
char name[15]; //名字
int age; //年龄
};
struct Stu s1 = { "zhangsan",20 }; //初始化
struct Stu s2 = { .age = 20,.name = "list" }; //指定顺序初始化
//代码3
struct Node
{
int data;
struct Ponit p;
struct Node* next;
}n1 = { 10,{4,5},NULL }; //结构体嵌套初始化
struct Node n2 = { 20,{5,6},NULL }; //结构体嵌套初始化
9.4结构体成员访问操作符
结构体成员的直接访问 使用方式:结构体变量.成员名
结构体成员的直接访问是通过点操作符( . )访问的。点操作符接受两个操作数。如下所示:
#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;
}
结构体成员的间接访问 使用方式:结构体指针->成员名
有时我们得到的不是一个结构体变量,而是得到了一个指向结构体的指针。如下所示:
#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;
}
10.操作符的属性:优先级、结合性
C语言的操作符有两个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序。
优先级:指的是,如果一个表达式包含多个运算符,哪个运算符应该优先执行。各种运算符的优先级是不一样的。
结合性:如果两个运算符优先级相同,优先级没办法确定先计算哪个了,这时候就看结合性了,则根据运算符是左结合还是右结合,决定执行顺序。大部分运算符是左结合(从左到右执行),少数运算符是右结合(从右到左执行),比如赋值运算符( = )。
参考:https://zh.cppreference.com/w/c/language/operator_precedence
用心呈现,只为遇见更好的你!点赞关注,让我们的博客陪伴你成长!
标签:10,进制,int,C语言,二进制,详解,操作符,struct From: https://blog.csdn.net/weixin_58275377/article/details/141114658