【C语言】超详解,让你C语言成功入门(五)——操作符

news2025/2/23 18:15:47

目录

  • 1.算术操作符
  • 2.移位操作符
    • 2.1左移操作符<<
    • 2.2右移操作符>>
  • 3.位操作符
  • 4.赋值操作符
  • 5.单目操作符
    • 5.1单目操作符介绍
    • 5.2sizeof 和 数组
  • 6.关系操作符
  • 7.逻辑操作符
  • 8.条件操作符(三目操作符)
  • 9.逗号表达式
  • 10.下标引用、函数调用和结构体
  • 11.表达式传值
      • 11.1 隐式类型转换
      • 11.2 算术转换
      • 12.3 操作符的属性
  • 12.优先级

1.算术操作符

操作符含义范例结果
+加法x+yx和y的和
减法x–yx和y的差
*乘法x * yx和y的积
/除法x / yx和y的商
%求余x%yx除以y的余数

注意:
(1)运算符%要求左右两个运算数据必须为整型数据,如5%2的值为3。
(2)相除时,结果为整数,小数部分舍去。但若除数或被除数中有一个为负值,则舍入的方向是不固定的。如5/3=1,但–5/3在有的计算机得到的结果是–1,而有的计算机上的结果是–2。C99规定采取 “向零取整” 的方法,即取整后向零取整。
(3)字符型数据可以和数值型数据进行运算,因为字符型数据在计算机中是用一个字节的整型数(ASCII码)表示的。如 ‘A’+1在进行运算时会把A的ASCII码65与1相加,最后得出结果就是66。

2.移位操作符

移的是二进制(补码)。

整数的二进制有三种表示法:

  • 原码
  • 补码
  • 反码

浮点数还有一种移码,移码通常用于表示浮点数的阶码。(计算机组成原理会讲,咱们这里先做了解)

整数在内存中存储的是补码。

编码正数负数
真值+(二进制)–(二进制)
原码高位补0,符号位补0高位补0,符号位补1
反码与原码相同原码的符号位不变,其他位按位取反(0→1,1→0)
补码与原码相同原码取反+1(反码+1)
移码符号位变1,其他位与补码相同符号位变0,其他位与补码相同

例:演示只用8位,最高一位为符号位(已加粗)

编码5–5
真值+0101–0101
原码0000010110000101
反码0000010111111010
补码0000010111111011
移码1000010101111011

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

2.1左移操作符<<

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

例1:5<<1
在这里插入图片描述
5的补码变为了00001010,原码为00001010,其二进制数为1010,转换为十进制:10。所以5左移一位后变成了10。

例2:–5<<1
在这里插入图片描述
–5的补码变为了11110100,反码为11110011,原码为10001100,其二进制数为–1100,转换为十进制:–12。所以–5左移一位后变成了–12。

2.2右移操作符>>

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

  1. 逻辑移位
    左边用0填充,右边丢弃
  2. 算术移位
    左边用原该值的符号位填充,右边丢弃
    在这里插入图片描述

警告⚠ :对于移位运算符,不要移动负数位,这个是标准未定义的。
例:

int num = 10;
num>>-1;//错误

3.位操作符

位操作符含义范例
&按位与x & y
按位或x ∣ y
^按位异或x ^ y

注:他们的操作数必须是整数。

#include <stdio.h>
int main()
{
    int num1 = 1;
    int num2 = 2;
    num1 & num2;
    num1 | num2;
    num1 ^ num2;
    return 0;
}

4.赋值操作符

(1)简单赋值运算
“ = ”的作用是将赋值符号右边的对象的值赋值给左边的对象。例:x = 9;
把值9赋给x,实际意义是将10存储到x的存储单元中。
此处“ = ”是赋值符,而非等于号。等于号是“ == ”,例如:if(x==10),意思是如果x等于10。

注:①10 = x;是无效语句。赋值运算符的左侧必须是一个运算对象,此对象的值可以改变。10是整数常量,不能改变其值,不能给常量赋值。
②若参与赋值运算的运算对象的数据类型不同,则右边对象的数据类型会被转换成左侧对象的类型。
③可以连续赋值:x = y = 10;

(2)复合赋值运算
在赋值运算符前加上其他运算符,例如在“ = ” 前加上“ + ”,运算符就变成了复合运算符“ += ”。
例:x += 10;
相当于 x = x+10;
其他算术运算符也可以与赋值运算符组合成复合赋值运算符。

5.单目操作符

5.1单目操作符介绍

单目操作符含义范例
逻辑反操作!a
+正号+x
负号–x
&取地址&a
sizeof操作数的类型长度(以字节为单位)sizeof(arr)
~对一个数的二进制按位取反~a
++前置、后置++++a 或 a++
– –前置、后置 – –– – a 或 a – –
*间接访问操作符(解引用操作符)*p
(数据类型)强制类型转换(int)a
#include <stdio.h>
int main()
{
    int a = -10;
    int *p = NULL;
    printf("%d\n", !2);
    printf("%d\n", !0);
    a = -a;
    p = &a;
    printf("%d\n", sizeof(a));
    printf("%d\n", sizeof(int));
    printf("%d\n", sizeof a);//这样写行不行?
    printf("%d\n", sizeof int);//这样写行不行?
    return 0;
}

自增运算符++
当 i 变量每次都要加1时,可写为 i++,或++i
相当于 i = i +1;

自减运算符 – –
当 i 变量每次都要减1时,可写为 i – – 或 – – i
相当于 i = i – 1;

自增、自减运算符的结合性是“ 从右到左 ”。x * y++ 相当于x * (y++),而并非是(x * y)++。

//++和--运算符
//前置++和--
#include <stdio.h>
int main()
{
    int a = 10;
    int x = ++a;
    //先对a进行自增,然后对使用a,也就是表达式的值是a自增之后的值。x为11。
    int y = --a;
    //先对a进行自减,然后对使用a,也就是表达式的值是a自减之后的值。y为10;
    return 0;
}
//后置++和--
#include <stdio.h>
int main()
{
    int a = 10;
    int x = a++;
    //先对a先使用,再增加,这样x的值是10;之后a变成11;
    int y = a--;
    //先对a先使用,再自减,这样y的值是11;之后a变成10;
    return 0;
}

5.2sizeof 和 数组

一般形式:sizeof(运算对象)
圆括号可有可无,但是当运算对象是数据类型是,必须加上圆括号。
例如:sizeof(int), sizeof x, sizeof(x), sizeof 34, sizeof(34)
sizeof的结合性是“ 从右到左 ”。

如果运算对象是表达式,那表达式将不会被执行,只会输出此表达式的数据类型所占的字节数。

#include<stdio.h>
int main()
{
    int a = 12,b = 1;
    printf("%zd\n",sizeof(a = a+b);
    printf("a = %d\n",a);
    return 0;
}

运算结果:
4
a = 12

sizeof运算的结果是一个无符号整数类型。C99新增了转换说明%zd用于输出 sizeof 运算结果的值。如果编译器不支持使用%zd,可以使用 %u 或 %lu 代替 %zd。

#include <stdio.h>

void test1(int arr[])
{
    printf("%d\n", sizeof(arr));//(2)
}

void test2(char ch[])
{
    printf("%d\n", sizeof(ch));//(4)
}

int main()
{
    int arr[10] = {0};
    char ch[10] = {0};
    printf("%d\n", sizeof(arr));//(1)
    printf("%d\n", sizeof(ch));//(3)
    test1(arr);
    test2(ch);
    return 0;
}

问:
(1)、(2)两个地方分别输出多少?
(3)、(4)两个地方分别输出多少?

答:
(1)、(2)两个地方分别输出多少?——40、4/8
(3)、(4)两个地方分别输出多少?——10、4/8
(1)、(3)= 数组大小 × 数据类型所占字节
(2)、(4)= 指针大小(4/8字节)

(2)、(4)为什么是指针大小?

test1(arr) 和 test2(ch) 其实传的都是地址,又可以写成test1(&arr)test2(&ch),那函数接收地址则是用的指针,指针大小为4byte或8byte(取决于编译器)。
具体的我们下一篇指针部分详细讲解。

6.关系操作符

关系操作符含义范例
<小于x<y
>大于x>y
<=小于等于x<=y
>=大于等于x>=y
==等于x==y
!=不等于x!=y

关系运算符的结合性是“ 从左到右 ”。a < b > c <= d 与( (a < b) > c) <= d 相同。

注意:浮点数之间进行比较时,尽量只使用 “ < ” 和 “ > ”。因为浮点数使用近似值表示的,这会导致逻辑上相等的两数却不相等。

7.逻辑操作符

逻辑运算符含义范例
&&逻辑与x && y
∣∣逻辑或x ∣∣ y
!逻辑非!x

在逻辑运算中,如果运算对象的值为非0,则认为是逻辑真,否则认为是逻辑假。真用 1 表示,假用 0 表示。

逻辑非
例:int a=5;
!a的结果为0,因为a不等于0。

ab!a!ba&&ba∣∣b

运算符 ! 的结合性是“ 从右到左 ”,而&&和 || 的结合性是“ 从左到右 ”。

在多个&&(或 ||)相连时,因结合性是从左到右,故当左边的运算对象为假(或真),停止运算。

8.条件操作符(三目操作符)

条件运算符的一般形式为:
表达式1 ?表达式2 :表达式3

条件运算符 ?:的功能是:在计算表达式1后,如果值为真(非0),则计算表达式2,并将表达式2的值作为整个表达式的结果;如果表达式1的值为假(0),则计算表达式3,并将表达式3的结果作为整个表达式的值。

x=10;
if(x > 8)
   y=20;
else
   y=10;

那我们可以用条件表达式来处理:

y = (x > 8) ? 20 : 10;

因x=10,比8大。故y的值为20,如果x所赋的值小于等于8,y的值赋为10。

9.逗号表达式

逗号运算符(,)用于将两个表达式连接时。如:
a+b , a+c
一般形式:表达式1 , 表达式2
求解过程:先求表达式1,再求表达式2。整个逗号表达式的值是表达式2的值。

一个逗号表达式又可以与另一个表达式组成一个新的逗号表达式。所以逗号表达式的一般形式又可拓展为:
表达式1, 表达式2, 表达式3, … , 表达式 n

注意:逗号也用作分隔符。下面代码中的逗号都是分隔符,而非逗号运算符。

int a,b;
printf("%d %d",a,b);

10.下标引用、函数调用和结构体

  1. []下标引用操作符
    操作数:一个数组名 + 一个索引值
int arr[10];//创建数组
arr[9] = 10;//实用下标引用操作符。
[ ]的两个操作数是arr和9
  1. ()函数调用操作符
    接受一个或者多个操作数:第一个操作数是函数名,剩余的操作数就是传递给函数的参数。
#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. 访问结构体成员变量
  • . :结构体 . 成员名
  • -> :结构体指针 -> 成员名
#include <stdio.h>
struct Stu
{
    char name[10];
    int age;
    char sex[5];
    double score;
}void set_age1(struct Stu stu)
{
    stu.age = 18;
}
void set_age2(struct Stu* pStu)
{
    pStu->age = 18;//结构成员访问
}
int main()
{
    struct Stu stu;
    struct Stu* pStu = &stu;//结构成员访问
 
    stu.age = 20;//结构成员访问
    set_age1(stu);
 
    pStu->age = 20;//结构成员访问
    set_age2(pStu);
    return 0;
}

11.表达式传值

表达式求值的顺序一部分是由操作符的优先级和结合性决定。

同样,有些表达式的操作数在求值的过程中可能需要转换为其他类型。

11.1 隐式类型转换

C的整型算术运算总是至少以缺省整型类型的精度来进行的。

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

整型提升的意义:

  • 表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。

    因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。

    通用CPU(general-purposeCPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int
    或 unsigned int,然后才能送入CPU去执行运算。

//实例1
char a,b,c;
...
a = b + c;

b和c的值被提升为普通整型,然后再执行加法运算。加法运算完成之后,结果将被截断,然后再存储于a中。

如何进行整体提升呢?

整形提升是按照变量的数据类型的符号位来提升的

  • 负数的整形提升
    char c1 = -1;
    变量c1的二进制位(补码)中只有8个比特位:
    1111111
    因为 char 为有符号的 char
    所以整形提升的时候,高位补充符号位,即为1
    提升之后的结果是:
    11111111111111111111111111111111
  • 正数的整形提升
    char c2 = 1;
    变量c2的二进制位(补码)中只有8个比特位:
    00000001
    因为 char 为有符号的 char
    所以整形提升的时候,高位补充符号位,即为0
    提升之后的结果是:
    00000000000000000000000000000001
  • 无符号整形提升,高位补0

11.2 算术转换

如果某个操作符的各个操作数属于不同的类型,那么除非其中一个操作数的转换为另一个操作数的类型,否则操作就无法进行。下面的层次体系称为寻常算术转换。

long double
double
float
unsigned long int
long int
unsigned int
int

如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。

警告:
但是算术转换要合理,要不然会有一些潜在的问题。

float f = 3.14;
int num = f;//隐式转换,会有精度丢失

12.3 操作符的属性

复杂表达式的求值有三个影响的因素。

  1. 操作符的优先级
  2. 操作符的结合性
  3. 是否控制求值顺序。

两个相邻的操作符先执行哪个?取决于他们的优先级。如果两者的优先级相同,取决于他们的结合性。

12.优先级

在这里插入图片描述
运算符优先级图源:https://www.wendangwang.com/doc/75d2728bbb843fed98536860

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

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

相关文章

2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-C卷

2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-C卷 2024 年甘肃省职业院校技能大赛中职组 电子与信息类“网络安全”赛项竞赛样题-C卷A模块基础设施设置/安全加固&#xff08;200分&#xff09;A 模块基础设施设置/安全加固&#xff08;200 分&am…

搜维尔科技:AI时代,迈向2030元宇宙数字人戏曲教育数字化思维、战略与未来!

一场关于中国传统戏曲与数字媒体交汇的探讨之旅将于今日在清华大学开讲&#xff0c;本次活动旨在推动AI时代大背景下&#xff0c;利用元宇宙、数字人等创新技术焕发中国传统戏曲全新活力。 讲座以“AI时代&#xff0c;迈向2030元宇宙数字人戏曲教育数字化思维、战略与未来”为主…

Flink-状态流与容错

状态流与容错 一、状态概念二、状态实现1.状态触发2.状态存储实现2.1 HashMapStateBackend2.2 EmbeddedRocksDBStateBackend2.3 状态存储对比 3.设置状态存储实现3.1 单个作业设置3.2 全局设置 三、容错机制1.状态快照2.状态快照生成3.Checkpoint Barrier4.Aligned Checkpointi…

“批量随机重命名文件夹,自定义长度,一键轻松搞定!“

您是否曾经因为文件夹命名重复或毫无特色而烦恼&#xff1f;现在&#xff0c;我们为您推荐一款全新的文件夹批量随机重命名工具&#xff0c;它可以轻松解决您的问题&#xff01; 首先第一步&#xff0c;我们要打开文件批量改名高手并登录账号。 第二步&#xff0c;在进入主页面…

L1-016:查验身份证

题目描述 一个合法的身份证号码由17位地区、日期编号和顺序编号加1位校验码组成。校验码的计算规则如下&#xff1a; 首先对前17位数字加权求和&#xff0c;权重分配为&#xff1a;{7&#xff0c;9&#xff0c;10&#xff0c;5&#xff0c;8&#xff0c;4&#xff0c;2&#xf…

webGL开发虚拟实验室技术方案

开发虚拟实验室涉及到模拟实际实验环境和过程&#xff0c;同时提供用户互动性和学习体验。以下是一个可能的技术方案&#xff0c;用于实现这样的虚拟实验室&#xff0c;希望对大家有所帮助。北京木奇移动技术有限公司&#xff0c;专业的软件外包开发公司&#xff0c;欢迎交流合…

面向注解编程—Spring 注解看这一篇就够了

面向注解编程—Spring 注解大全之IOC篇 Spring的一个核心功能是IOC&#xff0c;就是将Bean初始化加载到容器中&#xff0c;调用的时候直接注入即可&#xff0c;使用注解可以大大提高了开发效率&#xff01;。 Bean英文意为 豆子 理解起来就是豆荚里的豌豆&#xff0c;豆荚就是…

记一次使用Java8新特性中的parallelStream⭐️数据流引发的接口异常以及解决方法

目录 前言 正文 代码 分析 问题解决 总结 前言 小伙伴们大家好&#xff0c;分享下开发过程中最近遇到的坑&#xff0c;根据新需求&#xff0c;项目的一处模块需要改动&#xff0c;大致说下该模块的流程。。。好像之前有讲过&#xff0c;翻翻看&#xff0c;…

Linux4.8、环境变量续

个人主页&#xff1a;Lei宝啊 愿所有美好如期而遇 前言 如果对环境变量没有基本的理解&#xff0c;那么建议先看完这篇文章&#xff1a;环境变量https://blog.csdn.net/m0_74824254/article/details/134661113?spm1001.2014.3001.5501 环境变量与本地变量区别 使用export设…

response应用

文章目录 [TOC](文章目录) response说明一、response文件下载二、待补充。。。 response说明 response是指HttpServletResponse,该响应有很多的应用&#xff0c;比如像浏览器输出消息&#xff0c;下载文件&#xff0c;实现验证码等。 一、response文件下载 1.创建一个javaw…

跨境代采怎么实现(代采网站)

中国代购作为一种新型的业务形式&#xff0c;此类服务能够帮助消费者购买来自全球的商品&#xff0c;同时也为商家提供了在线销售机会。代购行业的兴起&#xff0c;有助于打破传统的地域和跨境限制&#xff0c;促进了国际贸易和经济发展。 一、中国代购的定义和特点 代购可以被…

基于SpringBoot实现的电影院售票系统

一、 系统架构 前端&#xff1a;html | jquery | bootstrap 后端&#xff1a;springboot | thymeleaf | spring-data-jpa 环境&#xff1a;jdk1.8 | mysql | maven 二、代码及数据库 三、功能介绍 01. 首页 02. 登录页 03. 管理端-电影列表 04. 管理端-添加电影 05. 管…

【EI会议征稿中】第五届人工智能与机电自动化国际学术会议(AIEA 2024)

第五届人工智能与机电自动化国际学术会议&#xff08;AIEA 2024&#xff09; 2024 5th International Conference on Artificial Intelligence and Electromechanical Automation 第五届人工智能与机电自动化国际学术会议&#xff08;AIEA 2024&#xff09;将于2024年3月8-10…

3 数据库

目录 一、数据库的基本信息 1.1 数据库的定义 1.2数据库的分类 1.2.1 关系型数据库 1.2.2 非关系型数据库 1.3 SQL介绍 1.3.1 概念 1.3.2 SQl语言分类 1.3.3 SQL注释 1.3.4 数据库操作命令DDL 1.3.5 数据表操作命令DDL 1.3.6 数据表操作命令DML 1.3.7 数据表中内容…

2023跳槽最新面试题整理:软件测试面试题(附带答案)备战面试...

混迹于软件测试行业十几年了&#xff0c;在面试经验方面也是比较有经验&#xff0c;那么也整理过很多面试题&#xff0c;今天暴露给大家看看&#xff0c;学习学习&#xff01; 测试面试一般从以下三大方向蹂躏面试者&#xff1a; 1、基本素养–比如沟通方向的考察&#xff0c…

同城上门洗鞋店小程序,打破传统洗鞋店新模式

同城洗鞋&#xff0c;一种把传统洗鞋和互联网结合的新兴服务&#xff0c;它让洗鞋更便捷、品质更高。你不用再为排队等待而烦恼&#xff0c;只需在家预约&#xff0c;我们的服务人员就会按时上门取鞋&#xff0c;进行初步清洗和检查。根据鞋子材质和污渍程度&#xff0c;选择合…

Java网络编程——基础入门

1、进程间的通信 进程指运行中的程序&#xff0c;进程的任务就是执行程序中的代码。EchoPlayer类是一个独立的Java程序&#xff0c;它可以在任意一台安装了JDK的主机上运行&#xff1a; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStr…

【EI会议征稿中|航空航天领域】第二届航空航天与控制工程国际学术会议(ICoACE 2023)

第二届航空航天与控制工程国际学术会议&#xff08;ICoACE 2023&#xff09; 2023 2nd International Conference on Aerospace and Control Engineering 2023年第二届航空航天与控制工程国际学术会议&#xff08;ICoACE 2023&#xff09;将于2023年12月15-17日在江苏南京召开…

性能测试计划怎么编写

一&#xff0e;简介 简介部分就不用过多描述了&#xff0c;无非项目的背景&#xff0c;进行此次性能测试的原因&#xff0c;以及性能测试覆盖的范围等等&#xff0c;几乎所有项目文档都在开端对项目进行简单的阐述。 二&#xff0e;性能测试需求 寻找的被测试对象和压力点 …

蓝桥杯算法心得——想吃冰淇淋和蛋糕(dp)

大家好&#xff0c;我是晴天学长&#xff0c;dp题&#xff0c;怎么设计状态很重要&#xff0c;需要的小伙伴可以关注支持一下哦&#xff01;后续会继续更新的。&#x1f4aa;&#x1f4aa;&#x1f4aa; 1) .想吃冰淇淋和蛋糕 想吃冰淇淋与蛋糕 输入格式 第一行输入一个整数n。…