前言
本文主要是对操作符知识的补充,主要从二进制和补码的角度来了解一些特殊的操作符。
一、进制之间的转换
(1)进制?
数值的不同表示方法。
二进制:0和1组成。 八进制:0-7组成。(书写时以0开头) 十进制:0-9组成。
十六进制:0-9+a-f(A-F)组成(a-f表示9-15),书写时以0x开头。
(2)其它进制转十进制
按权重值进行计算。

(3)十进制转二进制
Ⅰ.凑

Ⅱ.短除法

(4)二进制转八进制
一个八进制位由3个二进制位组成。(07—111)

(5)二进制转十六进制
一个十六进制位由4个二进制位组成。(0xf—1111)

(6)十进制转八进制、十六进制
十进制→二进制→八/十六进制
二、原码、反码、补码
(1)定义
都是数的二进制表示形式
(2)组成形式
符号位(1表示负数,0表示正数)+数的二进制形式
原码:组成形式(正数的原码、反码、补码相同)
反码:符号位不变,其它位取反
补码:a.反码+1
b.与原码互为逆运算(取反+1得到原码)
注:计算机中,存储和计算以补码形式计算
三、移位操作符(对二进制的位进行操作)
(1)左移操作符(<<)
左边移动,右边补0
Ⅰ.正数
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main() {
int a = 2;
printf("%d", a << 1);
}
//00000000 00000000 00000010
//00000000 00000000 00000100
//左移1位10变为100,结果由2变为4
Ⅱ.负数
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main() {
int a = -2;
printf("%d", a << 1);
}
//100000000 00000000 00000000 0000010 原码
//111111111 11111111 11111111 1111110 补码
//11111111 11111111 11111111 11111100 左移
//10000000 00000000 00000000 00000100 左移后的原码,由-2变为-4
(2)右移操作符(>>)
逻辑右移:左边补0,右边抛弃
算数右移:左边补符号位数字,右边抛弃(编译器默认算数右移)
四、位操作符——&、|、^、~(对二进制的位进行操作)
(1)&(按位与)
全为1,才为1。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
int main() {
int a=3, b=6;
printf("%d", a & b);
}
//a 00000000 00000000 00000000 00000011
//b 00000000 00000000 00000000 00000110
// 00000000 00000000 00000000 00000010(结果为2)
(2)|(按位与)
只要有1,则为1。
int main(){
int a = 5, b = 2;
printf("%d", a | b);
}
//a 00000000 00000000 00000000 00000101
//b 00000000 00000000 00000000 00000010
// 00000000 00000000 00000000 00000111(结果为7)
(3)^(按位异或)
相同为0,异反之
#include <stdio.h>
int main() {
int a = 7, b = 9;
printf("%d", a ^ b);
}
//a 00000000 00000000 00000000 00000111
//b 00000000 00000000 00000000 00001001
// 00000000 00000000 00000000 00001110(结果为14)
(4)~(按位取反)
每一位取反。
#include <stdio.h>
int main() {
int a = 6;
printf("%d", ~a);
}
// a 00000000 00000000 00000000 00000110
//~a 11111111 11111111 11111111 11111001 补码
// 10000000 00000000 00000000 00000111 原码(结果为-7)
注:&、|、^为双目操作符,~为单目操作符。
(5)练习
不创建第三个变量,实现两个数的交换。
//a^a的值为0,0^b的值为b
#include <stdio.h>
int main() {
int a = 3, b = 5;
printf("变换前:a=%d,b=%d\n", a, b);
a = a ^ b;
b = a ^ b;//a^b^b(最终结果为a)
a = a ^ b;//a^b^a(最终结果为b)
printf("变换后:a=%d,b=%d", a, b);
}
五、结构体
(1)what
结构体是一种自定义类型,将任意的数据类型(成员)封装为一个整体。
(2)语法
#define _CRT_SECURE_NO_WARNINGS 1
//结构体的语法
//struct 结构体类型名称{
// 数据类型 成员名1;
// ……………………
// };
#include <stdio.h>
struct student {
char name[10];
int age;
int high;
float weight;
};
(3)结构体变量名的定义
①全局变量
在分号前面加上变量名(“}g_变量1,g_变量2;”)
②局部变量
语法:struct 结构体名称 变量名1,变量名2;
(4)结构体变量的初始化
struct student one = {"小明",18,188,78.2f};
①顺序
语法:struct 结构体名 变量名={成员值1,成员值2}
②乱序
语法:struct 结构体名 变量名={.成员名x=成员值1,.成员名y=成员值2}
struct student two = { .weight = 80.3f,.high = 160,.age = 18,.name = "小红" };
(5)结构体内容的打印
语法:结构体变量名.成员名
printf("姓名:%s 年龄:%d 身高:%d 体重:%.2f",one.name,one.age,one.high,one.weight);
六、操作符的优先级和结合性
优先级:不同操作符运算时的先后顺序。
结合性:同等优先级下的计算顺序。
如下图所示:
https://en.cppreference.com/w/c/language/operator_precedence.html
七、整形提升与算数转换
(1)整型提升
在计算过程中,所有宽度小于整型的数据类型先提升为整型再进行计算。
#define _CRT_SECURE_NO_WARNINGS 1
//整型提升
#include <stdio.h>
int main(){
char a = 126;
//00111111 1 2 4 8 16 32 64 128
char b = 7;
//00000111
char c = a + b; //133
//a 00000000 00000000 00000000 00111111
//b 00000000 00000000 00000000 00000111
//c 00000000 00000000 00000000 10000101
//char c 10000101
// 11111111 11111111 11111111 10000101 原码
// 10000000 00000000 00000000 01111011 补码 (-123)
//
printf("%d", c);
}
(2)算数转换
int类型宽度以上的,小转大再运算。
八、结语
下一篇展开指针的学习。
1389

被折叠的 条评论
为什么被折叠?



