C语言---操作符详解

1.操作符的分类

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

• 移位操作符: >

• 位操作符: & | ^

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

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

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

• 逻辑操作符: && 、||

• 条件操作符: ? :

• 逗号表达式: ,

• 下标引⽤: []

• 函数调⽤: ()

2.二进制和进制转换

2进制、8进制、10进制、16进制是数值的不同表达形式

2进制:1111
8进制:17     7*8的0次方加1*8的1次方
10进制:15
16进制:F

2进制数字都是0~1组成的

8进制都是0~7的数字组成的

10进制的数字都是由0~9的数字组成

16进制的数字是0~9,a~f的数字组成

二进制满2进一

假设输入的10进制数字是125,一次除以2
然后依次是125 62 31 15 7 3 1 0
  余数依次是 1 0 1 1 1 1 1,所以10进制的125转换的2进制是:1111101


  20用二进制来表达就是10100
2进制   0 1 1 0 1 0 1 1
8进制    1    5     3
   从二进制的右边开始换算成八进制,每3个换算一次
   不足3个的2进制位直接换算,
   2进制的01101011换算成8进制的数字就是153

   注意:0开头的数字,会被当做8进制
 2进制   0 1 1 0 1 0 1 1
16进制      6       b
从二进制序列的最右边开始转换
每4个数字转换一次,不足4个数字的二进制直接转换


二进制右边的1011转换为10进制的数就是11,在16进制中用b表示
二进制左边的0110转换为10进制就是6,在16进制中用6表示


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

如果进行8进制转换成2进制甚至16进制转化为2进制只需要用反思路就可以算出

8进制位中的3换算成2进制就是011

8进制位中的5换算成2进制就是101

16进制的0x47转换为2进制就是01000111,因为7用二进制来表达就是0111,4用二进制来表达就是0100

8进制的047转换为2进制就是100111,因为8进制的7转换为2进制就是111,4转换板为二进制就是100

8进制是以二进制的三个数为一个单位的

16进制是以二进制的四个数为一个单位的

3.原码反码补码

整数的二进制表达形式有3种,即原码、反码和补码

有符号整数的三种表达方式均有符号位和数值位两部分,

2进制位中,最高位的1位是被当做符号位,剩余的都是数值位

符号位都是0表示正,1表示负

一个整型占的是4个字节,10占了8个字节,也就是32个bit位

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

负整数的三种表示方式个不同

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

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

补码:反码+1就是补码----仅针对于负数

负数的反码除了开头的符号位不改变,其他的0变成1,1变成0

int a =10

原码:00000000000000000000000000001010

反码:00000000000000000000000000001010

补码:00000000000000000000000000001010

int a =-10

原码:10000000000000000000000000001010

反码:11111111111111111111111111110101

补码:11111111111111111111111111110110

对于负数,原码反码补码是要计算的,但是正数的原码反码补码都相同

原码取反得到反码,+1得到补码

补码-1取反得到原码,补码取反+1也能得到原码

11111111111111111111111111110110--补码

10000000000000000000000000001001--反码--补码取反

10000000000000000000000000001010---+1==原码--反码+1

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

整数在内存中存储的其实是补码

原码得到补码和补码得到原码都是取反+1

1+(-1)用原码算的话得出来的数是-2

但是用补码算的话就是0

计算的时候都是用补码

4.移位操作符

<<左移操作符

>>右移操作符

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

移动的是存纯在内存中的二进制位---补码

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

整数
int main()
{
    int a = 10;//注意,移动的是存纯在内存中的二进制位---补码
    int b = a << 1;//a向左移动2位
    //10的二进制是1010
    //10放到a里面存储,4个字节,32个比特位
    //00000000000000000000000000001010----10的二进制数
    //a向左移动一位,最左边的被挤出去了,最右边就补上一个0
    //00000000000000000000000000010100----最后打印的b就是20
    printf("%d\n", b);//输出结果是20
    printf("%d\n", a);//结果仍然是10
    return 0;
}



负数
int main()
{
    int a = -1;
    //10000000000000000000000000000001-----   -1的原码
    //11111111111111111111111111111110-----    取反
    //11111111111111111111111111111111-----    +1----   -1的补码
    int b = a << 1;
    //移位后
    //11111111111111111111111111111110---b的补码
    //10000000000000000000000000000001---取反
    //10000000000000000000000000000010---+1---b的原码----   -2

    printf("b=%d\n", b);//打印的是b的原码-2
    printf("a=%d\n", a);//-1

    return 0;
}

右移规则:首先右移运算分两种

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

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

到底采用逻辑右移还是算术右移,取决于编译器

通常采用的都是算术右移

左边用原该值的符号填充,右边的丢弃

int main()
{
    int a = -10;
    //10000000000000000000000000001010---原码
    //11111111111111111111111111110101---取反
    //11111111111111111111111111110110---补码
    //采用算术右移,左边填充原来该值的符号,右边的丢弃
    //11111111111111111111111111111011--右移后的补码
    //10000000000000000000000000000100--取反
    //10000000000000000000000000000101--+1--原码
    //右移后的就是-5


    int b = a >> 1; 
    printf("a=%d\n", a);//-10
    printf("b=%d\n", b);//-5

    return 0;
}

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

& 按位与

| 按位或

^ 按位异或

~ 按位取反

操作数必须是整数

这里的位都是二进制位,只关注与二进制的计算

以下两种操作符只关注真假

&&逻辑与

||逻辑或

int main()
{
    int a = 6;
    //00000000000000000000000000000110---6的补码
    int b = -7;
    //10000000000000000000000000000111--  -7的原码
    //11111111111111111111111111111000--  -7的反码
    //11111111111111111111111111111001--  -7的补码
    int c = a & b;//a和b的补码的二进制位进行运算
    //对应的二进制位,有0则为0,两个同时为1才为1

    //00000000000000000000000000000110---6的补码
    //11111111111111111111111111111001--  -7的补码
    //00000000000000000000000000000000
    printf("c=%d\n", c);//c=0

    return 0;
}


//对应的二进制位,有0则为0,两个同时为1才为1
int main()
{
    int a = 6;
    //00000000000000000000000000000110---6的补码
    int b = -7;
    //10000000000000000000000000000111--  -7的原码
    //11111111111111111111111111111000--  -7的反码
    //11111111111111111111111111111001--  -7的补码
    int c = a | b;//a和b的补码的二进制位进行运算
    //规则:只要有1就是1,两个同时为0才为0

    //00000000000000000000000000000110---6的补码
    //11111111111111111111111111111001--  -7的补码
    //11111111111111111111111111111111----运算出的补码
    //10000000000000000000000000000000---取反
    //10000000000000000000000000000001  +1--转换出的原码
    printf("c=%d\n", c);//c=-1

    return 0;
}


规则:只要有1就是1,两个同时为0才为0
int main()
{
    int a = 6;
    //00000000000000000000000000000110---6的补码
    int b = -7;
    //10000000000000000000000000000111--  -7的原码
    //11111111111111111111111111111000--  -7的反码
    //11111111111111111111111111111001--  -7的补码
    int c = a ^ b;//a和b的补码的二进制位进行运算
    //规则:对应的二进制位上,相同为0,相异为1

    //00000000000000000000000000000110---6的补码
    //11111111111111111111111111111001--  -7的补码
    //11111111111111111111111111111111----运算出的补码
    //10000000000000000000000000000000---取反
    //10000000000000000000000000000001  +1--原码
    printf("c=%d\n", c);//c=-1

    return 0;
}


对应的二进制位上,相同为0,相异为1





//不让创建临时变量(第三个变量),实现两个整数的交换
int main()
{
    int a = 3;
    int b = 5;

    printf("交换前:a=%d b=%d\n", a, b);
    //不存在溢出现象
    a= a ^ b;//111
    b= a ^ b;///222//a ^ b^ b=a  将111中a 的值带到222中
    a= a ^ b;///333//a ^ b^a=b   将222中b的值带到333中
    printf("交换后:a=%d b=%d\n", a, b);
    return 0;
}

011--a
101--b
110---a ^ b    =a
011---a ^ b ^ b=b
101---a ^ b
//3^3=0
//a^a=0
//0^a=a

/*
* 异或是支持交换的
3^3^5=5
3^5^3=5


*/


//另外一种写法
//不让创建临时变量(第三个变量),实现两个整数的交换
int main()
{
    int a = 3;
    int b = 5;
    int c = 0;
    printf("交换前:a=%d b=%d\n", a, b);
    //不存在溢出现象
    c = a;
    a = b;
    b = c;
    printf("交换后:a=%d b=%d\n", a, b);
    return 0;
}
int main()
{
    int a = 0;
    printf("%d\n", ~a);/*结果为 - 1*/
    //~是按(二进制)位取反
    //00000000000000000000000000000000---0的补码
    //11111111111111111111111111111111---
    //10000000000000000000000000000000
    //10000000000000000000000000000001--最后的补码

    return 0;
}

^: 异或操作可以直接比较两个整数的对应位。当两个整数的对应位相同时,异或结果为0;当对应位不同时,结果为1。这意味着异或结果的每一位都直接告诉我们原始两个整数在该位上是否不同。

6.单目操作符

& -- 取地址操作符

  • -- 解引用操作符

如果写的是a&b,---&的意思就是按位与

但如果int a=10;--&a就是取a的地址

双目操作符的时候就是按位与

单目操作符的时候就是取地址

单目操作符有这些:

++

--

&

+

-

~

sizeof

(类型)

7.逗号表达式

exp1,exp2,exp3,exp4

逗号表达式就是用逗号隔开的表达式

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

int main()
{
    int a = 1;
    int b = 2;
    //逗号表达式
    //逗号表达式要从左依次向右计算
    //因为前面表达式的计算可能会影响后面的计算
    int c = (a > b, a = b + 10, a, b = a + 1);
    printf("%d", c);//输出结果是13



    return 0;
}

8.下标访问[]、函数调用()

int main()
{
    int arr[10] = { 1,2,3,4,5 };
    int m =arr[4];//数组中下标是4的元素
    //[]  下标引用操作符--操作数是:arr,4---数组名和下标
    printf("%d", m);//输出结果是5

    return 0;

}
int Add(int x, int y)
{
    return x + y;
}


int main()
{
    printf("hehe\n");//这里的()就是函数调用操作符
    //操作数是:一个是函数名,一个是穿过去的字符串
    printf("%d\n", 100);//这里的操作数:双引号内的字符串
                    //函数名  还有100
    int ret = Add(3, 5);//Add,3,5就是这个函数调用
                        //操作符的操作数
    //函数调用操作符,最少有几个操作数?
    //至少有一个操作数,就是函数名
    return 0;
}

9.结构成员访问操作符

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

结构体的关键字叫struct---

//学生类型
struct Student
{
    //成员变量
    char name[20];//名字
    int age;//年龄
    float score;//成绩
}a4, a5, a6;//也是全局变量


struct Student a3 = {"王",25,68.5};//全局变量

struct point
{
    int x;
    int y;
};


struct S
{
    char ch;
    struct point p;
    int arr[10];
    double d;
};
int main()
{
    struct Student a1 = {"翠花",20, 98.0};//用结构体类型创造结构体变量
    struct Student a2 = {"旺财",18,69.8};//局部变量
    struct S s = { 'a',{4,5},{1,2,3,4,5,6,7},3.14 };
    printf("%c", s.ch);
    printf("坐标是:%d %d\n", s.p.x, s.p.y);
    printf("%d\n", s.arr[0]);
    printf("%lf\n", s.d);
    return 0;
}
//通过结构体的名字加.去查找你存放的数据
//操作符左边是结构体变量.结构体成员名
//如果向往里面输入数据,就将pritnf改成scanf输入数据就行了

10.操作符的属性:优先级、结合性

c语言的操作符有两个重要的属性:优先级、结合性,这两个属性决定了表达式求值的计算顺序

int main()
{
    int r = 3 + 4 * 5;//先算乘法,再算加法


    return 0;
}

优先级

一个表达式包含多个运算符,哪个运算符应该优先执行,各种运算符的优先级是不一样的

当我们明确了优先级和结合性那我们是否能确定一个表达式的计算结果呢?

11.表达式求值

为了获取精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换称为整型提升

char 是否是signed char?

不一定,是取决于编译器的

vs上,char == signed char

char类型的取值范围是-128~127

算术转换

整型提升讨论的是表达式中char和short类型的值

算术转换讨论的是大于等于整型类型的其他类型

1.long double

2.double

3.float

4.unsigned long int

5.long int

6.unsigned int

7.int

从下向上转换--两种不同类型相加,较低档次的会被很转化为较高档次的

double a=10;

int b =10;

a+b的计算中,a会被转化成和b类型一样的double 类型

即是有操作符的优先级和结核性,我们写出的表达式仍然存在潜在风险的,建议不必要写复杂的表达式

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/607210.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【SAP ME 39】SAP ME WebService超时时间设置

禁止废话&#xff0c;直接上图&#xff01;&#xff01;&#xff01; SAP技术官方说明

Dark Reader:夜间模式,启动!

名人说&#xff1a;一点浩然气&#xff0c;千里快哉风。 ——苏轼 创作者&#xff1a;Code_流苏(CSDN)&#xff08;一个喜欢古诗词和编程的Coder&#x1f60a;&#xff09; 目录 一、介绍二、下载安装1、Chrome应用商店&#xff08;需科学&#xff09;2、第三方直链下载 三、使…

深入探索数据链路层:网络通信的基石

⭐小白苦学IT的博客主页⭐ ⭐初学者必看&#xff1a;Linux操作系统入门⭐ ⭐代码仓库&#xff1a;Linux代码仓库⭐ ❤关注我一起讨论和学习Linux系统❤ 前言 在网络通信的宏伟世界中&#xff0c;数据链路层扮演着至关重要的角色。它位于物理层和网络层之间&#xff0c;不仅直接…

HuggingFace烧钱做了一大批实验,揭示多模态大模型哪些trick真正有效

构建多模态大模型时有很多有效的trick&#xff0c;如采用交叉注意力机制融合图像信息到语言模型中&#xff0c;或直接将图像隐藏状态序列与文本嵌入序列结合输入至语言模型。 但是这些trick为什么有效&#xff0c;其计算效率如何&#xff0c;往往解释得很粗略或者或者缺乏充分…

C++ Builder XE EnumWindowsProc遍历所有窗口的名称

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam) { // 这里可以添加你的处理逻辑 // 例如&#xff0c;将句柄添加到列表中或者其他操作 // 这里我们仅仅输出到调试窗口 OutputDebugString(L"枚举窗口句柄: "); char windowHandle[10];…

ROS 2边学边练(45)-- 构建一个能动的机器人模型

前言 在上篇中我们搭建了一个机器人模型(其由各个关节&#xff08;joint&#xff09;和连杆&#xff08;link&#xff09;组成)&#xff0c;此篇我们会通过设置关节类型来实现机器人的活动。 在ROS中&#xff0c;关节一般有无限旋转&#xff08;continuous&#xff09;,有限旋转…

【每日力扣】98. 验证二叉搜索树 与 108. 将有序数组转换为二叉搜索树

&#x1f525; 个人主页: 黑洞晓威 &#x1f600;你不必等到非常厉害&#xff0c;才敢开始&#xff0c;你需要开始&#xff0c;才会变的非常厉害 98. 验证二叉搜索树 给你一个二叉树的根节点 root &#xff0c;判断其是否是一个有效的二叉搜索树。 有效 二叉搜索树定义如下&a…

【优选算法】——双指针——15. 三数之和

目录 1.题目 2.解法&#xff08;排序双指针&#xff09;&#xff1a; 算法思路&#xff1a; 3.代码实现 1.题目 15. 三数之和 提示 给你一个整数数组 nums &#xff0c;判断是否存在三元组 [nums[i], nums[j], nums[k]] 满足 i ! j、i ! k 且 j ! k &#xff0c;同时还满足…

【LLM第三篇】名词解释:RLHF——chatgpt的功臣

RLHF (Reinforcement Learning from Human Feedback) &#xff0c;直译为&#xff1a;“来自人类反馈的强化学习”。RLHF是一种结合了强化学习和人类反馈的机器学习方法&#xff0c;主要用于训练大模型以执行复杂的任务&#xff0c;尤其是当这些任务难以通过传统的奖励函数来精…

重学java 33.API 4.日期相关类

任何事&#xff0c;必作于细&#xff0c;也必成于实 —— 24.5.9 一、Date日期类 1.Date类的介绍 1.概述: 表示特定的瞬间,精确到亳秒 2.常识: a.1000毫秒 1秒 b.时间原点:1970年1月1日 0时0分0秒(UNIX系统起始时间),叫做格林威治时间,在0时区上 c.时区:北京位于东八区,一个时区…

Linux 操作系统线程1

目录 一、线程 1.1线程的基本概念 1.2 线程相关的API函数 1.2.1 线程的创建 1.2.2 线程退出 1.2.3 线程等待函数 1.2.4 获取线程ID 1.2.5 线程取消 1.2.6 线程的清理函数 一、线程 1.1线程的基本概念 线程是属于进程&#xff1b;一个进程可以有多个线程&#xff…

salmon使用体验

文章目录 salmon转录本定量brief模式一&#xff1a;fastq作为输入文件需要特别注意得地方 模式二&#xff1a; bam文件作为输入 salmon转录本定量 brief 第一点是&#xff0c;通常说的转录组分析其中有一项是转录本定量&#xff0c;这是一个很trick的说话&#xff0c;说成定量…

深度学习——前馈全连接神经网络(鸢尾花)

前馈全连接神经网络对鸢尾花数据集进行分类 1.导入所需要的包2.打印训练集和测试集二维数组3.定义模型4.打印模型信息5.权重和偏执6.编译网络和训练网络7.打印二维数据表格8.绘制图像9.查看准确率 1.鸢尾花数据集可以用 from sklearn.datasets import load_iris 方式获取&#…

医院预约挂号|基于Springboot+vue的医院预约挂号系统小程序的设计与实现(源码+数据库+文档)

医院预约挂号系统小程序 目录 基于Springboot&#xff0b;vue的医院预约挂号系统小程序设计与实现 一、前言 二、系统设计 三、系统功能设计 1小程序端 后台功能模块 4.2.1管理员功能 4.2.2医生功能 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选…

jsp 实验16 MVC 表白墙

源代码以及执行结果截图&#xff1a; ExpressWish_Bean.java package web; import java.util.HashMap; import java.util.ArrayList; import java.util.Iterator; public class ExpressWish_Bean { public HashMap<String,ExpressWish> wishList; ArrayList&…

#内部类#

1,概念 如果一个类定义在另一个类的内部&#xff0c;这个内部类就叫做内部类。内部类是一个独立的类&#xff0c;它不属于外 部类&#xff0c;更不能通过外部类的对象去访问内部类的成员。外部类对内部类没有任何优越的访问权限。重点&#xff1a;内部类是一个独立的类 注意&…

JavaEE 多线程详细讲解(2)

1.线程不安全分析 &#xff08;1&#xff09;线程不安全的主要原因就是&#xff0c;系统的抢占式执行&#xff0c;对于内核设计者来说&#xff0c;这是非常方便的一个执行方式&#xff0c;但是这却却导致线程不安全的问题&#xff0c;也有不抢占执行的系统&#xff0c;但是这种…

从心理学角度看,GPT 对人有什么影响?

开启个性化AI体验&#xff1a;深入了解GPT的无限可能 导言 GPT 与我们日常生活的融合标志着技术进步的重大飞跃&#xff0c;为提高效率和创新提供了前所未有的机遇。然而&#xff0c;当我们与这些智能系统日益紧密地交织在一起时&#xff0c;探索它们对个人产生的细微的心理影响…

15-LINUX--线程的创建与同步

一.线程 1.线程的概念 线程是进程内部的一条执行序列或执行路径&#xff0c;一个进程可以包含多条线程。 2.线程的三种实现方式 ◼ 内核级线程&#xff1a;由内核创建&#xff0c;创建开销大&#xff0c;内核能感知到线程的存在 ◼ 用户级线程&#xff1a;线程的创建有用户空…

抖音APP运用的AI技术拆解

1.推荐系统&#xff08;RS&#xff09; 用户画像&#xff1a;根据用户的信息&#xff08;如地区、性别、年龄、收藏、关注......&#xff09;进行分析&#xff0c;构建用户画像&#xff0c;对用户进行分类&#xff1b; 行为分析&#xff1a;将用户的显形行为数据&#xff08;如…
最新文章