C语言操作符详解

操作符的分类

• 算数操作符 : + - * / %
• 移位操作符 : <<  、 >>
• 位操作符 : &  、 | 、  ^
• 赋值操作符 : = += -= *= /= %= <<= >>= &= |= ^=
• 单目操作符 : !、 ++ -- & * + - ~ sizeof ( 类型 )
• 关系操作符 : > >= < <= == !=
• 逻辑操作符 : && ||
• 条件操作符 : ? :
• 逗号表达式 : ,
•下标引用操作符 : []
• 函数调用操作符 : ()
• 结构成员访问操作符 : .    、  ->

进制转换

        二进制与十进制

        在生活中我们最常用的是十进制(十进制满10进1,十进制的每一位都是0~9的数字组成),其实二进制也同样如此(二进制满2进1,二进制的每一位都是0~1的数字组成的)。10进制的数字从右向左是个位、⼗位、百位....,分别每⼀位的权重是 10^0 , 10^1 , 10^2 ...如下:

2进制和10进制是类似的,只要把10换成2就行了。

如果你想要在二进制和十进制之间进行转换:

十进制转二进制:只需要将十进制数依次除二,直到余数为0.由下往上依次所得的余数就是10进制转换出的2进制。

二进制转十进制:将每一位的值乘上权重值就是十进制数了。

二进制与八进制

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

二进制与十六进制

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

原码、反码、补码

         整数的2进制表⽰⽅法有三种,即原码、反码和补码。有符号整数的三种表⽰⽅法均有符号位和数值位两部分,2进制序列中,最⾼位的1位是被当做符号位,剩余的都是数值位。符号位都是⽤0表⽰“正”,⽤1表⽰“负”。
        
正整数的原、反、补码都相同。
负整数的三种表⽰⽅法各不相同。
原码:直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。
反码:将原码的符号位不变,其他位依次按位取反就可以得到反码。
补码:反码+1就得到补码。
反码得到原码也是可以使⽤:取反,+1的操作。
         对于整形来说:数据存放内存中其 实存放的是补码。
        原因是 :在计算机系统中,数值⼀律⽤补码来表⽰和存储。原因在于,使⽤补码,可以将符号位和数值域统⼀处理;同时,加法和减法也可以统⼀处理(CPU只有加法器)此外,补码与原码相互转换,其运算过程是相同的,不需要额外的硬件电路。

移位操作符

包括: << 左移操作符和 >> 右移操作符

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

左移操作符

移位规则:左边抛弃,右边补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;
}

右移操作符

移位规则:先右移后,分逻辑右移(左边用0填充,右边丢弃)和算数右移(左边的原该值的符号位填充,右边丢弃),大多数情况下都是算数右移。

警告:对于移位运算符,不要移动负数位,这个是标准未定义的。例如:
int num = 10 ;
num>> -1 ; //error

位操作符(&、| 、^ 、~)

&          按位与 有0则0,全1才1

|           按位或  有1则1,全0才0

^          按位异或    相同为0,相异为1
~          按位取反

注: 他们的操作数必须是整数。 因为计算使用的是它们的二进制形式。

 下面举几个例子:

#include <stdio.h>
int main()
{int num1 = -3;int num2 = 5;printf("%d\n", num1 & num2);printf("%d\n", num1 | num2);printf("%d\n", num1 ^ num2);printf("%d\n", ~0);return 0;
}
#include <stdio.h>
int main()
{int num1 = -3;//10000000000000000000000000000011     -3的原码//11111111111111111111111111111100     -3的反码//11111111111111111111111111111101     -3的补码   int num2 = 5;//00000000000000000000000000000101     5的原反补码printf("%d\n", num1 & num2);//5//11111111111111111111111111111101     -3的补码   //00000000000000000000000000000101     5的原反补码//00000000000000000000000000000101     & 有0则0,全1才1printf("%d\n", num1 | num2);//-3//11111111111111111111111111111101     -3的补码   //00000000000000000000000000000101     5的原反补码//11111111111111111111111111111101     | 有1则1,全0才0    补码//10000000000000000000000000000011     原码printf("%d\n", num1 ^ num2);//-8//11111111111111111111111111111101     -3的补码   //00000000000000000000000000000101     5的原反补码//11111111111111111111111111111000     ^ 相同为0,相异为1   补码//10000000000000000000000000001000     原码printf("%d\n", ~0);//-1//00000000000000000000000000000000     0的原反补码//11111111111111111111111111111111     ~ 按位取反 补码//10000000000000000000000000000001     原码return 0;

逗号表达式

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

如(exp1, exp2, exp3, …expN)
逗号表达式,从左向右依次执⾏。整个表达式的结果是最后⼀个表达式的结果。
int a = 1;
int b = 2;
int c = (a>b, a=b+10, a, b=a+1);//逗号表达式
c是多少?

答案是13,从左向右依次计算,a  = b + 10 = 12, b = a + 1 = 13.

if (a =b + 1, c=a / 2, d > 0)

这同样是逗号表达式,前两步也可以提出来放在if语句的上面。

a = get_val();
count_val(a);
while (a > 0)
{//业务处理a = get_val();count_val(a);
}//如果使⽤逗号表达式,改写:
while (a = get_val(), count_val(a), a>0)
{//业务处理
}

这就是逗号表达式的几种方式。

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

1、下标引用操作符

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

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

2、函数调用操作符

 接收一个或者多个操作符:第⼀个操作数是函数名,剩余的操作数就是传递给函数的参数。

#include <stdio.h>
void test1()
{printf("hehe\n");
}
void test2(const char *str)
{printf("%s\n", str);
}
int main()
{test1(); //这⾥的()就是作为函数调⽤操作符。test2("hello bit.");//这⾥的()就是函数调⽤操作符。return 0;
}

结构成员访问操作符

1、结构体

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

         C语⾔已经提供了内置类型,如:char、short、int、long、float、double等,但是只有这些内置类 型还是不够的,假设我想描述学⽣,描述⼀本书,这时单⼀的内置类型是不⾏的。描述⼀个学⽣需要名字、年龄、学号、⾝⾼、体重等;描述⼀本书需要作者、出版社、定价等。C语⾔为了解决这个问题,增加了结构体这种⾃定义的数据类型,让程序员可以⾃⼰创造适合的类型。

结构的声明

struct tag
{
        member- list ;
}variable- list ;
描述⼀个学⽣:
struct Stu
{
char name[ 20 ]; // 名字
int age; // 年龄
char sex[ 5 ]; // 性别
char id[ 20 ]; // 学号
}; // 分号不能丢

结构体变量的定义和初始化

//代码1:变量的定义
struct Point
{int x;int y;
}p1; //声明类型的同时定义变量p1struct Point p2; //定义结构体变量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="lisi"};//指定顺序初始化//代码3
struct Node
{int data;struct Point p;struct Node* next; 
}n1 = {10, {4,5}, NULL}; //结构体嵌套初始化struct Node n2 = {20, {5, 6}, NULL};//结构体嵌套初始化

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;
}

结构体成员的间接访问

有时候我们得到的不是⼀个结构体变量,⽽是得到了⼀个指向结构体的指针。
即: 结构体指针->成员名
如下所⽰:
#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;
}

操作符的优先级与结合性

        两个属性决定了表达式求值的计算顺序

优先级

        优先级指的是,如果⼀个表达式包含多个运算符,哪个运算符应该优先执⾏。各种运算符的优先级是不⼀样的。这里之前讲过,不过多阐述。

结合性

如果两个运算符的优先级相同,那就要看结合性了,大部分的运算符是从左向右结合,少数运算符从右向左执行,如赋值运算符。

结合性参考:https://zh.cppreference.com/w/c/language/operator_precedence

表达式求值

整型提升

C语⾔中整型算术运算总是⾄少以缺省整型类型的精度来进⾏的。
为了获得这个精度,表达式中的字符和短整型操作数在使⽤之前被转换为普通整型,这种转换称为整 型提升。
整型提升的意义:
        表达式的整型运算要在CPU的相应运算器件内执⾏,CPU内整型运算器(ALU)的操作数的字节⻓度⼀般就是int的字节⻓度,同时也是CPU的通⽤寄存器的⻓度。
因此,即使两个char类型的相加,在CPU执⾏时实际上也要先转换为CPU内整型操作数的标准⻓度。
通⽤CPU(general-purpose CPU)是难以直接实现两个8⽐特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种⻓度可能⼩于int⻓度的整型值,都必须先转换为int或unsigned int,然后才能送⼊CPU去执⾏运算
char a,b,c;
...
a = b + c;
        这里 b 和 c 的值首先被提升为普通整型,然后再执⾏加法运算,加法运算完成之后,结果将被截断,然后再存储于a中。
如何进⾏整体提升呢?
1. 有符号整数提升是按照变量的数据类型的符号位来提升的
2. ⽆符号整数提升,⾼位补0
// 负数的整形提升
char c1 = -1 ;
变量 c1 的⼆进制位 ( 补码 ) 中只有 8 个⽐特位:
1111111
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为 1
提升之后的结果是:
11111111111111111111111111111111
// 正数的整形提升
char c2 = 1 ;
变量 c2 的⼆进制位 ( 补码 ) 中只有 8 个⽐特位:
00000001
因为 char 为有符号的 char
所以整形提升的时候,⾼位补充符号位,即为 0
提升之后的结果是:
00000000000000000000000000000001
// ⽆符号整形提升,⾼位补 0

算术转换 

        如果某个操作符的各个操作数属于不同的类型,那么除⾮其中⼀个操作数的转换为另⼀个操作数的类型,否则操作就⽆法进⾏。下⾯的层次体系称为寻常算术转换。
long double
double
float
unsigned long int
long int
unsigned int
int
        如果某个操作数的类型在上⾯这个列表中排名靠后,那么⾸先要转换为另外⼀个操作数的类型后执⾏运算。

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

阅读《极客时间 | Kafka核心技术与实战》(一)【Kafka入门】

阅读《极客时间 | Kafka核心技术与实战》 为什么要学习Kafka消息引擎系统ABC一篇文章带你快速搞定Kafka术语我应该选择哪种Kafka&#xff1f;聊聊Kafka的版本号 为什么要学习Kafka 如果你是一名软件开发工程师的话&#xff0c;掌握 Kafka 的第一步就是要根据你掌握的编程语言去…

移动光猫gs3101超级密码及改桥接模式教程

文章目录 超级管理员账号改桥接模式路由器连接光猫&#xff0c;PPPOE拨号即可&#xff01;附录&#xff1a;如果需要改桥接的话不知道拨号密码咋办打开光猫Telnet功能Telnet 登录 参考文章 移动光猫吉比特GS3101超级账号获取更改桥接 移动光猫gs3101超级密码及改桥接模式教程 …

单片机——FLASH(2)

文章目录 flash &#xff08;stm32f40x 41x的内存映射中区域详解&#xff09;flash写数据时 flash &#xff08;stm32f40x 41x的内存映射中区域详解&#xff09; Main memory 主存储区 放置代码和常数 System memory 系统存储区 方式bootloader代码 OTP区 一次性可编程区 选项…

AR人脸106240点位检测解决方案

美摄科技针对企业需求推出了AR人脸106/240点位检测解决方案&#xff0c;为企业提供高效、精准的人脸识别服务&#xff0c;采用先进的人脸识别算法和机器学习技术&#xff0c;通过高精度、高速度的检测设备&#xff0c;对人脸进行快速、准确地定位和识别。该方案适用于各种应用场…

spring boot和spring cloud项目中配置文件application和bootstrap加载顺序

在前面的文章基础上 https://blog.csdn.net/zlpzlpzyd/article/details/136060312 日志配置 logback-spring.xml <?xml version"1.0" encoding"UTF-8"?> <configuration scan"true" scanPeriod"10000000 seconds" debug…

Flink流式数据倾斜

1. 流式数据倾斜 流式处理的数据倾斜和 Spark 的离线或者微批处理都是某一个 SubTask 数据过多这种数据不均匀导致的&#xff0c;但是因为流式处理的特性其中又有些许不同 2. 如何解决 2.1 窗口有界流倾斜 窗口操作类似Spark的微批处理&#xff0c;直接两阶段聚合的方式来解决…

【开源】SpringBoot框架开发超市账单管理系统 JAVA+Vue+SpringBoot+MySQL

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块三、系统设计3.1 总体设计3.2 前端设计3.3 后端设计在这里插入图片描述 四、系统展示五、核心代码5.1 查询供应商5.2 查询商品5.3 新增超市账单5.4 编辑超市账单5.5 查询超市账单 六、免责说明 一、摘要 1.1 项目介绍 基于…

Adobe Camera Raw for Mac v16.1.0中文激活版

Adobe Camera Raw for Mac是一款强大的RAW格式图像编辑工具&#xff0c;它能够处理和编辑来自各种数码相机的原始图像。以下是关于Adobe Camera Raw for Mac的一些主要特点和功能&#xff1a; 软件下载&#xff1a;Adobe Camera Raw for Mac v16.1.0中文激活版 RAW格式支持&…

EMQX Enterprise 5.3 发布:审计日志、Dashboard 访问权限控制与 SSO 一站登录

EMQX Enterprise 5.3.0 版本已正式发布&#xff01; 新版本带来多个企业特性的更新&#xff0c;包括审计日志&#xff0c;Dashboard RBAC 权限控制&#xff0c;以及基于 SSO&#xff08;单点登录&#xff09;的一站式登录&#xff0c;提升了企业级部署的安全性、管理性和治理能…

C遗漏知识(个人向)

之前C语言遗漏的一些。 数据在内存中的存储 原码、反码、补码 整数的2进制表⽰⽅法有三种&#xff0c;即 原码、反码和补码 正整数的原、反、补码都相同。 负整数的三种表⽰⽅法各不相同。 原码&#xff1a;直接将数值按照正负数的形式翻译成⼆进制得到的就是原码。 反码&…

Project 2019下载安装教程,保姆级教程,附安装包和工具

前言 Project是一款项目管理软件&#xff0c;不仅可以快速、准确地创建项目计划&#xff0c;而且可以帮助项目经理实现项目进度、成本的控制、分析和预测&#xff0c;使项目工期大大缩短&#xff0c;资源得到有效利用&#xff0c;提高经济效益。软件设计目的在于协助专案经理发…

云计算 - 弹性计算技术全解与实践

一、引言 在过去的十年里&#xff0c;云计算从一个前沿概念发展为企业和开发者的必备工具。传统的计算模型通常局限于单一的、物理的位置和有限的资源&#xff0c;而云计算则通过分布式的资源和服务&#xff0c;为计算能力带来了前所未有的"弹性"。 弹性&#xff1a;…

浅谈分布式系统

常见基本概念 在正式引入架构演进之前&#xff0c;先了解几个比较重要的概念做前置介绍。 应用(Application)/系统(System) 一个应用&#xff0c;就是一个/一组服务器程序 模块(Module)/组件(Component) 一个应用&#xff0c;里面有很多个功能。每个独立的功能&#xff0c;就可…

Unity AnimationRigging无法修改权重?

个人理解&#xff0c;已解决无法修改权重的问题: unity自带的动画系统是在FixUpdate和Update之后LateUpdate之前执行&#xff0c;如果在这FixedUpdate或Update函数内更新AnimationRigging内的权重后&#xff0c;内部动画系统会覆盖权重的修改&#xff0c;导致无法正确更新&…

外贸邮件群发如何做?外贸邮件群发靠谱吗?

外贸邮件群发有哪些平台&#xff1f;外贸群发邮件用什么邮箱&#xff1f; 外贸邮件群发是许多企业在开展国际贸易时常用的营销手段&#xff0c;它不仅能够快速地将产品信息和促销活动传达给目标客户&#xff0c;还能够有效地建立和维护客户关系。下面&#xff0c;就让蜂邮探讨…

创建TextMeshPro字体文件

相比于Unity的Text组件&#xff0c;TextMesh Pro提供了更强大的文本格式和布局控制&#xff0c;更高级的文本渲染技术&#xff0c;更灵活的文本样式和纹理支持&#xff0c;更好的性能以及更易于使用的优点。但unity自带TextMeshPro字体不支持中文。这里使用普通字体文件生成Tex…

2023年12月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python等级考试(1~6级)全部真题・点这里 一、单选题(共25题,共50分) 第1题 一个非零的二进制正整数,在其末尾添加两个“0”,则该新数将是原数的?( ) A:10倍 B:2倍 C:4倍 D:8倍 答案:C 二进制进位规则是逢二进一,因此末尾添加一个0,是扩大2倍,添加两个0…

天线阵列车载应用——第1章 介绍 1.1节 汽车工业中的天线阵列:应用和频率范围

1.1 汽车工业中的天线阵列:应用和频率范围 无线通信系统的发展需要新的技术来支持更高质量的通信、新的服务和应用。近年来&#xff0c;汽车无线通信市场得到了极大的扩展。现代汽车使用不同的服务:AM/FM收音机、卫星广播(SDARS)、移动电话通信、数字音频广播(DAB)、远程无钥匙…

【Docker与微服务】基础篇

1 Docker简介 1.1 docker是什么 1.1.1 问题&#xff1a;为什么会有docker出现&#xff1f; 假定您在开发一个项目&#xff0c;您使用的是一台笔记本电脑而且您的开发环境具有特定的配置。其他开发人员身处的环境配置也各有不同。您正在开发的应用依赖于您当前的配置且还要依…

机器人运动学林沛群——变换矩阵

对于仅有移动&#xff0c;由上图可知&#xff1a; A P B P A P B o r g ^AP^BP^AP_{B org} APBPAPBorg​ 对于仅有转动&#xff0c;可得&#xff1a; A P B A R B P ^AP^A_BR^BP APBA​RBP 将转动与移动混合后&#xff0c;可得&#xff1a; 一个例子 在向量中&#xff…