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.mzph.cn/news/673934.shtml

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

相关文章

音视频色彩:RGB/YUV

目录 1.RGB 1.1介绍 1.2分类 1.2.1RGB16 1)RGB565 2)RGB555 1.2.2RGB24 1.2.3RGB222 2.YUV 2.1介绍 2.2分类 2.2.1 YUV444 2.2.2 YUV 422 2.2.3 YUV 420 2.3存储格式 2.3.1 YUYV 2.3.2 UYVY 2.3.3 YUV 422P 2.3.4 YUV420P/YUV420SP 2.3.5 YU12 和…

IS-IS 接口认证密码平滑更换

拓扑图 配置 AR1、AR2建立ISIS level-2邻居关系&#xff0c;并配置接口认证密码为huawei sysname AR1 # isis 1is-level level-2network-entity 49.0000.0000.0000.0001.00 # interface GigabitEthernet0/0/0ip address 12.1.1.1 255.255.255.0 isis enable 1isis authentica…

Spark安装(Yarn模式)

一、解压 链接&#xff1a;https://pan.baidu.com/s/1O8u1SEuLOQv2Yietea_Uxg 提取码&#xff1a;mb4h tar -zxvf /opt/software/spark-3.0.3-bin-hadoop3.2.tgz -C /opt/module/spark-yarn mv spark-3.0.3-bin-hadoop3.2/ spark-yarn 二、配置环境变量 vim /etc/profile…

【typescript】特殊符号用法(?:)(??)(?.)(!)(!!)

一. 问号冒号&#xff08;?:&#xff09; 1.可以作为对象类型的可选属性&#xff0c;如&#xff1a; interface Person{name : string;age?: number; }const person1 : Person {name:"zien"} const person2 : Person {name:"sad", age:18} console.l…

MacBook有必要装清理软件吗?CleanMyMac的一些主要特点

MacBook是苹果公司的一款高端笔记本电脑&#xff0c;但是&#xff0c;随着使用时间的增长&#xff0c;MacBook也会出现一些问题&#xff0c;比如运行缓慢、卡顿、垃圾文件堆积、磁盘空间不足等。这些问题不仅影响了用户的使用体验&#xff0c;也可能对MacBook的寿命和安全性造成…

如何将国风与品牌信息相结合?

随着人们消费观念的转型升级。「国风」成为深受品牌欢迎的营销元素&#xff0c;它能够通过东方美学引起用户。然而有许多品牌在国风营销中稍不注意就会踩雷&#xff0c;今天媒介盒子就来和大家聊聊&#xff1a;国风营销怎么做才能吸引用户。 一、 与用户生活结合 要找到传统文…

ChatGPT高效提问—prompt常见用法(续篇四)

ChatGPT高效提问—prompt常见用法&#xff08;续篇四&#xff09; 1.1 知识生成 ​ 知识生成是指使用自然语言处理技术&#xff0c;通过ChatGPT等AI模型生成与特定主题相关的知识、文本或回答。在知识生成过程中&#xff0c;模型接收prompt输入的问题、指令或上下文信息&…

Vue3中路由配置Catch all routes (“*“) must .....问题

Vue3中路由配置Catch all routes (“*”) must …问题 文章目录 Vue3中路由配置Catch all routes ("*") must .....问题1. 业务场景描述1. 加载并添加异步路由场景2. vue2中加载并添加异步路由(OK)3. 转vue3后不好使(Error)1. 代码2. 错误 2. 处理方式1. 修改前2. 修…

8_姿态的其他描述及一般坐标系映射

1.机器人姿态的其他表示方法 前面说的用33矩阵矩阵描述姿态&#xff0c;9个元素&#xff0c;6个约束条件&#xff0c;实际上只有3个独立元素。即用3个独立元素即可描述机器人姿态。常用的有RPY角&#xff0c;欧拉角和四元数。 1.1 RPY角 RPY角是船舶在海上航行时常用的一种姿态…

基于java+springboot+vue实现的高校物品捐赠管理系统(文末源码+Lw)23-151

第1章 绪论 当前的网络技术&#xff0c;软件技术等都具备成熟的理论基础&#xff0c;市场上也出现各种技术开发的软件&#xff0c;这些软件都被用于各个领域&#xff0c;包括生活和工作的领域。随着电脑和笔记本的广泛运用&#xff0c;以及各种计算机硬件的完善和升级&#xf…

不到1s生成mesh! 高效文生3D框架AToM

论文题目&#xff1a; AToM: Amortized Text-to-Mesh using 2D Diffusion 论文链接&#xff1a; https://arxiv.org/abs/2402.00867 项目主页&#xff1a; AToM: Amortized Text-to-Mesh using 2D Diffusion 随着AIGC的爆火&#xff0c;生成式人工智能在3D领域也实现了非常显著…

信钰证券:2024年最新创业板开通条件?

创业板是深圳证券买卖所建立的一个专门为创新型、成长型企业服务的板块&#xff0c;受到了不少投资者的关注。对于2024年最新创业板注册条件&#xff0c;信钰证券下面就为我们详细介绍一下。 2024年最新创业板注册条件&#xff1a; 1、投资者的财物要求&#xff1a;投资者申请…

JavaScript基础(28)_获取元素的其他样式

其他样式操作的属性 clientWidth(只读)&#xff1a;获取元素的"可见宽度"&#xff0c;包括内容区和内边距(返回的是一个数字&#xff0c;不带px&#xff0c;可直接进行计算)。 clientHeight(只读)&#xff1a;获取元素的"可见高度"&#xff0c;包括内容区…

大数据应用对企业的价值

目录 一、大数据应用价值 1.1 大数据技术分析 1.2 原有技术场景的优化 1.2.1 数据分析优化 1.2.2 高并发数据处理 1.3 通过大数据构建新需求 1.3.1 智能推荐 1.3.2 广告系统 1.3.3 产品/流程优化 1.3.4 异常检测 1.3.5 智能管理 1.3.6 人工智能和机器学习 二、大数…

mac电脑安装cocoapods出错,以及安装最新版本ruby方法

macbook安装cocoapods时碰到一个报错&#xff1a;大概率是ruby的版本太低导致的 sudo gem install cocoapods ERROR: Error installing cocoapods: ERROR: Failed to build gem native extension. ... Could not create Makefile due to some reason, probably lack of neces…

Mountain Lake - Forest Pack

从头开始构建的50个岩石森林资源集合,充分利用了HDRP。还支持Universal 和Built-In。 支持Unity 2020.3+、高清渲染管线、通用渲染管线、标准渲染管线。导入包后,按照README中的说明进行操作。 Mountain Lake - Rock & Tree Pack是一个由50个准备好的资源组成的集合,从头…

如何运行心理学知识(心流)来指导工作和生活

如何运用心流来指导工作和生活 如何联系我 作者&#xff1a;鲁伟林 邮箱&#xff1a;thinking_fioa163.com或vlinyes163.com GitHub&#xff1a;https://github.com/thinkingfioa/ReadingSummary 版权声明&#xff1a;文章和记录为个人所有&#xff0c;如果转载或个人学习…

命令行参数、环境变量

1. 命令行参数 大家平时在写主函数时基本是无参的&#xff0c;但其实是有参数的&#xff0c;先介绍前两个参数。 int main(int argc, char* argv[])第二个参数是指针数组&#xff0c;第一个参数是该数组的个数&#xff0c;我们先来写 一段代码来看看指针数组里面是什么。 1 #…

Vue3父子组件传参

一&#xff0c;父子组件传参&#xff1a; 应用场景&#xff1a;父子组件传参 Vue3碎片&#xff1a;defineEmits&#xff0c;defineProps&#xff0c;ref&#xff0c;reactive&#xff0c;onMounted 1.父组件传子组件 a.父组件传参子组件 import { ref} from vue import OnChi…

【力扣】快乐数,哈希集合+快慢指针+数学

快乐数原题地址 方法一&#xff1a;哈希集合 定义函数getNext(n)&#xff0c;返回n的所有位的平方和。一直执行ngetNext(n)&#xff0c;最终只有2种可能&#xff1a; n停留在1。无限循环且不为1。 证明&#xff1a;情况1是存在的&#xff0c;如力扣的示例一&#xff1a; 接…