C语言_操作符

news2024/12/24 20:53:25

目录

算术操作符

移位操作符

位操作符

赋值操作符

单目操作符 

关系操作符

逻辑操作符 

条件操作符

逗号表达式

下标引用,函数调用,结构成员 

表达式求值

隐式类型转换

算术转换

操作符的属性 

练习题

代码仓库


算术操作符

加(+),减(-),乘(*),除(/),取模(%)

  • 除法:
  1. 整数除法(除号两端都是整数就执行整数除法)
  2. 浮点数除法(除号两端只要有一个是小数就执行浮点数除法)
  3. 除数不能为0
  • 取模:
  1. 得到整除后的余数
  2. 两个操作数必须都是整数

移位操作符

左移操作符(<<),右移操作符(>>)

  1. 移位移动的是补码的二进制序列
  2. 移位操作符的操作数只能是整数
  3. 整数的二进制有三种表示形式,原码,反码,补码
    根据正负直接写出的二进制序列就是原码
    正整数的原反补一样,负整数原反补需要计算
    二进制最高位是符号位,符号位1表示负数0表示正数
    
    一个整型是4个字节=32个bit位
    int a = 15;
    00000000 00000000 00000000 00001111  //原码
    00000000 00000000 00000000 00001111  //反码
    00000000 00000000 00000000 00001111  //补码
    
    最高位是符号位,1表示负数0表示正数
    int b = -15;
    10000000 00000000 00000000 00001111  //原码
    反码:符号位不变其他按位取反
    11111111 11111111 11111111 11110000  //反码
    补码:反码+1
    11111111 11111111 11111111 11110001  //补码
    
    整数在内存中存储的是补码
    计算的时候也是使用补码计算
  4. 右移分为算术右移,逻辑右移
    算术右移:右边丢弃,左边补原来的符号位
    逻辑右移:右边丢弃,左边直接补0
    C语言没有明确规定用哪个,一般编译器采用算术右移
  5. 左移:左边丢弃,右边补0
  6. 移动负数位是标准未定义行为

位操作符

按位与(&),按位或(|),按位异或(^)

  1. 操作二进制位
    int a = 3;
    int b = -5;
    a的补码:00000000 00000000 00000000 00000011
    b的补码:11111111 11111111 11111111 11111011
    
    按二进制位与(&):对应二进制位有0为0,两个同时1才为1
    a & b: 00000000 00000000 000000000 00000011 
    
    按二进制位或(|):对应二进制位有1为1,两个同时0才为0
    a | b:11111111 11111111 11111111 11111011
    
    按二进制位异或(^):对应二进制位相同为0,相异为1
    a ^ b:11111111 11111111 11111111 11111000
    
    计算结果是补码,输出需要转为原码
    原码 = 补码-1然后符号位不变取反

    面试题:不能创建临时变量(第三个变量),实现两个整数的交换。

    //方法1
    int a = 3;
    int b = 5;
    a = a + b;
    b = a - b;
    a = a - b;
    //缺陷:假如a或b特别大,那么a+b就可能超出整型范围发生截断
    
    //方法2
    a = a ^ b;
    b = a ^ b;
    a = a ^ b;
    
    //异或特点:
    //a ^ a = 0
    //a ^ 0 = a
    //a ^ b = b ^ a 异或支持交换律

赋值操作符

  1. 赋值(=)
    int x = 1;
    int y = 2;
    int z = 3;
    //也可以连续赋值
    x = y = z = 4;
  2.  复合赋值符,+=,-=,*=,/=,%=,>>=,<<=,&=,|=,^=

单目操作符

  1. 逻辑反操作(!)
  2. 负值(-)
  3. 正值(+)
  4. 取地址(&),解引用操作符(*)应用于指针
    int a = 10;
    int* pa = &a; //取出a的地址,pa是指针变量
    *pa = 20; //通过pa中存放的地址,找到指向的空间(内容)
  5.  sizeof 不是函数,是操作符,计算的是类型创建变量的大小,单位是字节
    int a = 10;
    printf("%d\n", sizeof(a)); //4
    printf("%d\n", sizeof a); //4  可以不带括号
    int arr[10];
    printf("%d\n", sizeof(arr)); //40
  6. ~ :对一个数的二进制位按位取反
  7. 后置++(后置-- 同理)
    int a = 1;
    int b = a++; //b = a, a = a + 1 先使用,后++

    前置++(前置-- 同理)

    int a = 1;
    int b = ++a; //a = a + 1,b = a 先++,后使用
  8. 强制类型转换:(类型) 
    int a = (int)3.14;

关系操作符

  1. >, >=, <, <=, !=, ==

逻辑操作符

  1. 逻辑与(&&),逻辑或(||)
  2. && 左边为假右边就不计算了
  3. || 左边为真右边就不计算了
  4. &&,||,!,如果计算结果为真,使用1表示

条件操作符

  1. e1 ? e2 : e3
    int a = 0;
    int b = 0;
    
    if(a>5)
    {
        b = 3;
    }
    else
    {
        b = -3;
    }
    
    //转成条件操作符
    b = (a>5) ? 3 : -3;

逗号表达式

  1. 从左向右计算,整个表达式的结果是最后一个表达式的结果
    int a = 1;
    int b = 2;
    int c = (a>b, a=b+10, a, b=a+1); //13 
    
    //例子2
    a = get();
    count(a);
    while(a>0)
    {
        a = get();
        count(a);
    }
    //改成逗号表达式
    while(a=get(), count(a), a>0) {}

下标引用,函数调用,结构成员 

  1. 下标引用操作符 [ ]
    int arr[10];
    arr[3] = 4; //arr和3是操作数
  2.  函数调用操作符()
    int len = strlen("abc"); //操作数是函数名和参数
  3. 访问结构成员,结构体.成员名,结构体指针->成员名 

表达式求值

  1. 表达式在计算的过程中有哪些类型转换?有些表达式的操作数在求值的过程中可能需要转换为其他类型,类型转换有整型提升,算术转换
  2. 表达式的求值顺序是怎么样的?表达式求值的顺序一部分是由操作符的优先级和结合性决定

隐式类型转换

  1. C的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获得这个精度,表达式中的字符(char)和短整型(short)操作数在使用之前被转换为普通整型,这种转换称为整型提升
  2. 整型提升的意义:表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度 一般就是int的字节长度,同时也是CPU的通用寄存器的长度。 因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长 度。 通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令 中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。
  3. 如何进行整体提升呢?
    char c1 = 5;
    //00000000 00000000 00000000 00000101 这是5的整型
    //00000101 存入char发生截断
    
    char c2 = 127;
    //00000000 00000000 00000000 01111111
    //01111111
    
    //整形提升是按照变量的数据类型的符号位来提升的,前面补符号位
    char c3 = c1 + c2
    //00000101 c1
    //00000000 00000000 00000000 00000101 c1整型提升 
    //01111111 c2
    //00000000 00000000 00000000 01111111 c2整型提升
    //整型提升后相加
    //00000000 00000000 00000000 10000100
    //10000100 c3发生截断
    
    printf("%d\n", c3); //%d:10进制的形式打印有符号的整数,遇到char需要整型提升
    //1111111 11111111 11111111 10000100 c3整型提升,前面符号位补齐,这里是补码,转成原码然后打印

算术转换

  1. 如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。
    //下面的层次体系称为寻常算术转换。
    //从上往下依次排列,下面类型遇到上面类型则需要转为上面类型
     long double
     double
     float
     unsigned long int
     long int
     unsigned int
     int

操作符的属性 

  1. 复杂表达式的求值有三个影响的因素,操作符的优先级,操作符的结合性,是否控制求值顺序。
  2. 相邻操作符优先级高的先算,低的后算
  3. 相邻操作符优先级相同的情况下,看结合性

C语言中的运算符优先级可以分为多个级别,从高到低依次为:

  1. 括号类操作符(如 ()[]->.)。
  2. 单目运算符(如 !\~++---)。
  3. 算术运算符(如 +-*/%)。
  4. 关系运算符(如 <>==!=&lt;=&gt;=)。
  5. 逻辑运算符(如 &&||!)。
  6. 条件运算符(如 ? :)。
  7. 赋值运算符(如 =+=-=*=/=%=%=)。
  8. 逗号运算符(,)。

左结合性(Left-to-right)

大多数二元操作符都是左结合的,这意味着它们从左到右结合。常见的左结合操作符包括:

算术操作符+,  -,  *,  /,  %

关系操作符<,  <=,  >,  >=

相等操作符==,  !=

位操作符&,  |,  ^,  <<,  >>

逻辑操作符&&,  ||

逗号操作符,

a - b + c // 先计算 a - b,然后再计算结果 + c
 

右结合性(Right-to-left)

一些操作符是右结合的,这意味着它们从右到左结合。常见的右结合操作符包括:

赋值操作符=,  +=,  -=,  *=,  /=,  %=

三元操作符? :

一元操作符!,  ~,  ++,  --,  +(正号),  -(负号),  *(指针解引用),  &(取地址),  sizeof

类型转换操作符(type)

a = b = c // 先计算 b = c,然后再计算 a = (b = c)

总结:我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的 


练习题

答:A

答:a=9, b=23, c=8   (b=++c, c++, ++a, a++)整体是一个逗号表达式

写一个函数,返回参数二进制中1的个数

//思路:先取出第一位比较,然后右移一位
int get_one(int _num)
{
	int count = 0;
	for (int i = 0; i < 32; i++) if ((_num>>i) & 1) count++;
	return count;
}
	
int main()
{
	int num;
	scanf("%d", &num);
	printf("%d\n", get_one(num));
	return 0;
}
//方法2
//n = n & (n-1) 这个表达式会让n的二进制最右边的1消失
int get_one(int _num)
{
	int count = 0;
	for (; _num != 0; _num = _num & (_num - 1), count++);
	return count;
}
	
int main()
{
	int num;
	scanf("%d", &num);
	printf("%d\n", get_one(num));
	return 0;
}

获取一个整数二进制序列中所有偶数位和奇数位并分别打印

//思路:假设第一位是奇数位,第一位右移0位和1相与打印,第三位右移2位...,第5位右移4位...,第31位右移30位...
//偶数位:第2位右移1位...,第4位右移3位...,第32位右移31位...
int main()
{
	int n;
	scanf("%d", &n);

	for (int i = 30; i >= 0; i -= 2) printf("%d ", (n >> i) & 1);
	printf("\n");
	for (int i = 31; i > 0; i -= 2) printf("%d ", (n >> i) & 1);
	return 0;
}

输出两个int整数m和n的二进制序列中有多少个位不同

//思路:先异或,再算有几个1
int main()
{
	int m, n, count = 0;
	scanf("%d %d", &m, &n);
	int ret = m ^ n;
	while (ret = ret & (ret - 1)) count++;
	count++;
	printf("%d\n", count);
	return 0;
}

 

答:D,这个代码有问题,因为不能确定唯一的计算路径,不同的编译环境有不同的结果

 
下面代码的结果是?

答:>

解析:第一个点,全局变量和静态变量如果不初始化默认是0,

第二个点,sizeof的返回值类型是size_t也就是unsigned int,而 i 的类型是int,i 和 sizeof 比较 i 的类型会被算术转换为 unsigned int,此时 i 是 -1,所以 i 变成一个很大的正整数。

 

答:D

 

有序序列合并_牛客题霸_牛客网

输入两个升序排列的序列,将两个序列合并为一个有序序列并输出。

//思路:用i, j分别遍历两个数组,将i, j对应的元素进行比较,小的输出然后往后遍历
int main() {
    //输入第一行
    int n, m;
    scanf("%d %d", &n, &m);
    //输入第二行,变长数组
    int n_arr[1000];
    for (int i = 0; i < n; i++) scanf("%d ", &n_arr[i]);
    //输入第三行
    int m_arr[1000];
    for (int i = 0; i < m; i++) scanf("%d ", &m_arr[i]);
    //合并
    int i = 0, j = 0;
    while (i < n && j < m)
    {
        //谁小谁输出
        if (n_arr[i] < m_arr[j]) printf("%d ", n_arr[i++]);
        else printf("%d ", m_arr[j++]);
    }
    //走到这里是有一个数组输出完了,直接输出另一个数组剩下的数
    if (i == n) while (j < m) printf("%d ", m_arr[j++]);
    else while (i < n) printf("%d ", n_arr[i++]);
    return 0;
}

有序序列判断_牛客题霸_牛客网

输入一个整数序列,判断是否是有序序列,有序,指序列中的整数从小到大排序或者从大到小排序(相同元素也视为有序)。


代码仓库

Operator/Operator/main.c · 林宇恒/code_c - 码云 - 开源中国 (gitee.com)

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

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

相关文章

WAIC上官宣!大模型语料提取工具MinerU正式发布,开源免费“敲”好用

7月4日&#xff0c;2024 WAIC科学前沿全体会议在上海世博中心红厅隆重举行。上海人工智能实验室与商汤科技联合香港中文大学和复旦大学正式发布新一代大语言模型书⽣浦语2.5&#xff08;InternLM2.5&#xff09;&#xff0c;同时全链条工具体系迎来重磅升级&#xff0c;对于大模…

17.【C语言】初识常见关键字 下

1.typedef 类型&#xff08;重新&#xff09;定义&#xff08;或命名&#xff09;&#xff0c;可简化输入 如&#xff1a; #define _CRT_SECURE_NO_WARNINGS 1 #include <stdio.h> typedef signed long long k; int main() {k a 0; } signed long long被简写为k这个…

基于SpringBoot的乐校园二手书交易管理系统

你好呀&#xff0c;我是计算机学姐码农小野&#xff01;如果有相关需求&#xff0c;可以私信联系我。 开发语言 Java 数据库 MySQL 技术 SpringBoot框架 工具 Visual Studio、MySQL数据库开发工具 系统展示 首页 用户注册界面 二手图书界面 个人中心界面 摘要 乐校园…

vue3+ts+vite项目报错:找不到名称“GC”。ts-plugin(2304)

GC变量通过script标签引入的第三方引入&#xff0c;但是ts-plugin并不知道&#xff0c;需要明确声明这个变量的类型 /// <reference types"vite/client" />declare module "*.vue" {import type { DefineComponent } from "vue";// eslint…

【8】相关补充

【8】相关补充 文章目录 前言一、不同模型在测试集上的精度二、实验记录三、SNP位点筛选及其它python脚本四、总结五、后续安排总结 前言 存放一些有关这个项目研究的补充。 三叶青图像识别研究简概 一、不同模型在测试集上的精度 存放了不同识别模型在测试集上精度评估展示…

2024年前端面试中面试官常拷打的“项目细节”!

前言 都知道前端面试中&#xff0c;面试官最爱拷打的项目细节&#xff0c;根据你的项目经历来进行相关提问&#xff0c;时不时再给你几个高难度问题&#xff0c;让人头疼。 程序员大都有一个特点&#xff1a;会做&#xff0c;不会写&#xff0c;更不会说 前端面试&#xff0c…

【Revit二次开发】创建rvt文件,但不打开Revit

介绍 需要安装Revit&#xff0c;但不用打开Revit加载插件&#xff0c;而是运行一个控制台应用&#xff0c;就可以创建一个rvt文件&#xff08;更多读写功能都可自行添加&#xff09;。 本文内容主要参考&#xff1a;博客1&#xff0c;但对内容进行了简化&#xff0c;只保留了…

第N7周:seq2seq翻译实战-pytorch复现-小白版

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 理论基础 seq2seq&#xff08;Sequence-to-Sequence&#xff09;模型是一种用于机器翻译、文本摘要等序列转换任务的框架。它由两个主要的递归神经网络&#…

BSI 第七届万物互联智慧高峰论坛:主题:拥抱AI时代,标准赋能组织实现可持续发展

BSI 第七届万物互联智慧高峰论坛&#xff1a;主题&#xff1a;拥抱AI时代&#xff0c;标准赋能组织实现可持续发展 主要收到 BSI 温女士的邀请参加的本次论坛。还是学到的很多 。 在科技日新月异的时代背景下&#xff0c;BSI 第七届万物互联智慧高峰论坛于[时间&#xff1a;6…

【HICE】搭建不同的主机名访问web服务

1.首先进入1.conf.d编辑内容&#xff0c;再重启服务&#xff0c;关闭防火墙 2.部署网页haha.html和xixi.html 3.在vim /etc/hosts增加域名 3.在window中进行本地解析的编辑 4.浏览器的验证

阿里云安装rabbitMQ

1、首先看linux 版本 uname -a如果时centos 7 可以参考其他文档。我这里是centos 8 这个很重要 。网上全是按centos7 按照。导致我前面一直安装不上 各种问题。 2、查看rabbitmq 对应 erl 的版本下载 https://www.rabbitmq.com/docs/which-erlang 选择rabbitmq 3.11.19 选择…

【线性代数的本质】矩阵与线性变换

线性变化要满足两点性质&#xff1a; 直线&#xff08;连续的点&#xff09;在变换后还是直线。原点不变。 假设有坐标轴&#xff08;基底&#xff09; i ^ \widehat{i} i 和 j ^ \widehat{j} j ​&#xff1a; i ^ [ 1 0 ] , j ^ [ 0 1 ] \widehat{i}\begin{bmatrix} 1 \…

Facebook广告被拒:常见原因以及避免屏蔽的方法

大多数情况下&#xff0c;广告被屏蔽是因为违反了规则&#xff0c;这不仅仅是因为审核因素。有些规则并不明显&#xff0c;也没有在任何地方指定。例如&#xff0c;在广告中使用广告政策中未列出的停用词&#xff1b;审核算法确定照片描绘的模特过于暴露。下面小编将为你介绍Fa…

四款主流电脑监控软件(电脑监控软件主要优势)

在现代企业环境中&#xff0c;确保员工的工作效率和企业信息的安全成为了管理者的重要任务。电脑监控软件作为一种有效的管理工具&#xff0c;能够帮助企业实现这些目标。固信电脑监控软件在这方面表现尤为出色&#xff0c;本文将详细介绍固信电脑监控软件的优势及其主要功能&a…

【腾讯内推】腾讯2025校招/青云计划/社招——长期有效

及时跟进进度&#xff0c;保证不让简历石沉大海&#xff01; 涵盖NLP/CV/CG/ML/多模态/数据科学/多媒体等各方向! 定向匹配优质团队/竞争力薪酬/覆盖全球工作地点! 招聘对象: 本硕博:2024年1月-2025年12月毕业的同学 目前最热岗位: 技术研究-自然语言处理 技术研究-计算机视觉 …

pdf压缩,pdf压缩在线网页版,在线压缩pdf网站

在数字化时代&#xff0c;pdf文件已经成为我们工作、学习和生活中不可或缺的一部分。然而&#xff0c;pdf文件往往体积庞大&#xff0c;传输效率低下&#xff0c;还占用大量存储空间。如何在不影响文件质量的前提下&#xff0c;减小pdf文件的大小呢&#xff1f;今天&#xff0c…

【RT-thread studio 下使用STM32F103-学习sem-信号量-初步使用-线程之间控制-基础样例】

【RT-thread studio 下使用STM32F103-学习sem-信号量-初步使用-线程之间控制-基础样例】 1、前言2、环境3、事项了解&#xff08;1&#xff09;了解sem概念-了解官网消息&#xff08;2&#xff09;根据自己理解&#xff0c;设计几个使用方式&#xff08;3&#xff09;不建议运行…

RedHat / CentOS安装FTP服务

本章教程,记录在RedHat / CentOS中安装FTP的具体步骤。FTP默认端口:21 1、安装 epel 源 yum install -y epel-release2、安装 pure-ftpd yum -y install pure-ftpd3、修改默认配置 # 默认配置位于 /etc/pure-ftpd/pure-ftpd.conf,在配置文件中找到下面几个参数进行修改:#…

Vmware环境下ESXi主机 配置上行链路、虚拟交换机、端口组、VMkernel网卡

一、适用场景 1、使用专业服务器跑多种不同的业务&#xff0c;每种业务可能所需运行的server环境不同&#xff0c;有的需要Linux server CentOS7/8、kali、unbuntu……有的需要windows server2008、2003、2016、2019、2022…… 2、本例采用的是VMware ESXi6.7 update 3版本&am…

一个项目学习Vue3---Class和Style绑定

看下面一段代码学习此部分内容 <template><button click"stateChang">状态切换</button><div :class"{font-color:classObject.openColor,font-weight:classObject.openWeight}">颜色和粗细变化</div><div :class"…