【C语言】10.操作符详解(下)

🎬个人主页:缘三水的博客
❄专栏传送门:C语言专栏(新手向)
人生格言:行动是迷茫的最好解药


🎬个人介绍:

文章目录

  • 前言
  • (一)结构成员访问操作符
    • [1.1 结构体](#1.1 结构体)
      • [1.11 结构体的声明](#1.11 结构体的声明)
      • [1.12 结构体变量的定义](#1.12 结构体变量的定义)
      • [1.13 结构体变量的初始化](#1.13 结构体变量的初始化)
    • [1.2 结构成员访问操作符](#1.2 结构成员访问操作符)
      • [1.21 结构成员的直接访问](#1.21 结构成员的直接访问)
      • [1.22 结构成员的间接访问](#1.22 结构成员的间接访问)
  • (二)操作符的属性:优先级,结合性
    • [2.1 优先级](#2.1 优先级)
    • [2.2 结合性](#2.2 结合性)
  • (三)表达式求值
    • [3.1 整型提升](#3.1 整型提升)
    • [3.2 算术转换](#3.2 算术转换)
    • [3.3 问题表达式](#3.3 问题表达式)
  • 总结

前言

上一篇中我们介绍了部分操作符,接下来我们将介绍剩下的操作符

前文回顾:【C语言】9.操作符详解(上)


那么正文开始

(一)结构成员访问操作符

结构成员访问操作符有

.

->

本文只介绍点操作符.

->操作符我们在介绍指针时讲解

1.1 结构体

我们先来了解结构体

当我们要描述一个学生时,我们会讲到学生的姓名,年龄,性别,学号等等

这些属性我们用一个数组是无法全部描述的,因为数组只能存放多个相同类型 的数据

此时我们就可以用到结构体

结构体是一种自定义数据类型 ,内部可以存放多个不同类型 的成员变量

成员变量可以是:单独的变量,数组,指针,结构体

1.11 结构体的声明

基本格式

c 复制代码
struct 标签名
{
	//这里写入一个或多个成员变量,可以是不同数据类型
};//分号前可以创建结构体变量,也可以不创建

例如,我们要描述学生

c 复制代码
struct Student
{
	char name[20];
	int age;
	char sex[5];
	char id[20];
};//分号不可以丢弃
	

这样我们就完成了一个结构体的声明

1.12 结构体变量的定义

结构体变量定义有两种方式

  1. 在结构体声明时的分号前定义
    这种方式只需要写出结构体变量名即可
c 复制代码
	struct Student
	{
		char name[20];
		int age;
		char sex[5];
		char id[20];

	}s1,s2,s3;

这里就创建了s1,s2,s3这几个结构体变量

  1. 在结构体声明后,再定义结构体变量
    创建方式:struct 标签名 结构体变量名;
c 复制代码
	struct Student
	{
		char name[20];
		int age;
		char sex[5];
		char id[20];

	};
	struct Student s1, s2, s3;

这样也可以创建结构体变量

1.13 结构体变量的初始化

初始化也是两种,

  1. 在声明时创建结构体变量并初始化
  2. 声明后创建结构体变量再初始化

初始化格式:初始化是使用大括号{},初始化顺序是结构体成员变量的顺序

c 复制代码
	struct Student
	{
		char name[20];
		int age;
		char sex[5];
		char id[20];
	}s1={"zhangsan",18,"boy","20251202"};//创建结构体变量并初始化
c 复制代码
	struct Student
	{
		char name[20];
		int age;
		char sex[5];
		char id[20];

	};
	struct Student s1={"zhangsan",18,"boy","20251202"};//创建结构体变量并初始化

初始化也可以不按照顺序,此时需要使用点操作符.

例子

c 复制代码
struct Student s1 = { .age = 20,.name = "zhangsan",.sex = "boy",.id = "20251202" };

格式:点操作符. + 成员变量名

当结构体里的成员变量也是结构体时怎么初始化呢?

举个例子,当我们想创建一个电话本时

这个电话本里应该有多个人,每一个人又有多个信息

那么这每一个人就是一个结构体

电话本又是一个结构体

则电话本的初始化应该是

c 复制代码
struct people//人的信息
{
	char name[20];
	char telephone[12];
};
struct Ebook//电话簿
{
	struct people data[100];//存放100个人的电话簿
	int count;//现在存放的人数
};

int main()
{
	struct people p1 = { "zhangsan","12345678901" };//创建一个people的结构体变量
	struct Ebook eb = { {{"lisi","98765432101"},{"wangwu","01234567890"}},2 };//创建一个电话簿
	return 0;
}

1.2 结构成员访问操作符

1.21 结构成员的直接访问

当我们想打印结构体变量里的一个信息应该怎么做呢?

可以使用直接访问

直接访问用到了点操作符.

点操作符有 个操作数,分别是结构体变量名成员变量名

实例

c 复制代码
struct student s1 = { .age = 20,.name = "zhangsan",.sex = "boy",.id = "20251202" };
printf(" name:%s\n id:%s\n age:%d\n sex:%s", s1.name,s1.id, s1.age,s1.sex);

在printf函数中我们就用到了直接访问

s1.name

s1是结构体变量名,name是成员变量名

1.22 结构成员的间接访问

会用到->操作符

这里涉及到指针知识我们在之后介绍


(二)操作符的属性:优先级,结合性

了解到这么多操作符后,在实际应用中可能会出现多个运算符的存在,这就需要我们了解操作符的属性

2.1 优先级

优先级指的是,表达式中存在多个运算符,运算符的先后执行顺序

例如

c 复制代码
a + b * c;

这个表达式中*的优先级高于加法,因此先执行乘法运算 *,再执行加法运算

下面我列举出常用的优先级顺序

• 圆括号()

• ⾃增运算符(++),⾃减运算符(- -)

• 单⽬运算符(+和-)

• 乘法(*),除法(/)

• 加法(+),减法(-)

• 关系运算符(<、>等)

• 赋值运算符(=)

除此之外还有很多运算符的优先级顺序

想拓展了解的可以自行查看
操作符优先级顺序表

2.2 结合性

当优先级相同时,就要判断结合性来决定操作符执行先后了

一般优先级相同,操作符从左到右执行

c 复制代码
a * b / c;

也存在从右至左执行的情况,赋值运算符=就是这样

以上,由于圆括号的优先级最高,我们可以灵活运用圆括号(),来调整操作符的执行顺序


(三)表达式求值

3.1 整型提升

由于C语言运算是默认以整型运算 来执行的

int类型是32比特位

因此char(8比特位)类型和short int(16比特位)类型需要经过整型提升转化位int类型才可以运算

数据类型长度

例如

c 复制代码
char a = -1;
char b = 1;
char c = a + b;

整型提升指的也是二进制位 提升

这里的a,b,c都是字符型,长度都为8比特位,1、-1都是整型32(比特位)需要截断才能存放进a,b中

之后进行整型提升 ,相加后的结果再截断为所需的长度,这里是char类型就是八个二进制位

如何进行整型提升?

1.对有符号整数,在高位按照符号位补上

2.对无符号整数,在高位补上0

c 复制代码
过程
-1补码
11111111 11111111 11111111 11111111
截断后存储在a中
11111111
整型提升
11111111 11111111 11111111 11111111

1补码
00000000 00000000 00000000 00000001
截断后存储在b中
00000001
整型提升
00000000 00000000 00000000 00000001

相加1 00000000 00000000 00000000 00000000
截断
00000000
计算结果为0

3.2 算术转换

对操作符的操作数类型不同时

要么进行算术转换 成相同类型计算

要么就无法进行计算

下面列出算术转换的先后顺序

1 long double

2 double

3 float

4 unsigned long int

5 long int

6 unsigned int

7 int

可以看出一些规律

转换先后大多以数据类型长度长的优先

优先转换成浮点型

无符号同类型优先转换

3.3 问题表达式

表达式

c 复制代码
a * b + c * d + e * f

这样的表达式可能存在两种计算路径

c 复制代码
(1)
a*b
c*d
a*b+c*d
e*f
a*b+c*d+e*f
c 复制代码
(2)
a*b
c*d
e*f
a*b+c*d
a*b+c*d+e*f

倘或前面的变量也在后面出现,前面变量改变,后面也跟着改变,则有可能出现两种计算结果

因此,我们在敲代码时应该注意到表达式不宜过于复杂

不仅难以读懂,也可能造成计算结果的不符


总结

以上就是本文的全部内容,希望能对你有帮助

有错误的地方希望可以得到大佬的指正
最后不要吝啬你的点赞,收藏和评论!!!

相关推荐
liliangcsdn43 分钟前
python如何写数据到docx示例
开发语言·python
渡我白衣1 小时前
深入理解算法库的灵魂——彻底掌握 <algorithm> 的范式、迭代器约束、隐藏陷阱与性能真相
数据结构·c++·人工智能·网络协议·mysql·rpc·dubbo
Gomiko1 小时前
JavaScript基础(九):内部对象
开发语言·javascript·udp
报错小能手1 小时前
C++流类库 文件流操作
开发语言·c++
矜辰所致1 小时前
CH58x 主机扫描事件相关应用(扫描到广播包)
c语言·蓝牙主机·ble 广播包·广播包过滤·广播名称过滤
smile_Iris1 小时前
Day 26 常见的降维算法
开发语言·算法·kotlin
暗然而日章1 小时前
C++基础:Stanford CS106L学习笔记 3 流
c++·笔记·学习
刻刻帝的海角1 小时前
响应式数据可视化 Dashboard
开发语言·前端·javascript
王铁柱子哟-1 小时前
如何在 VS Code 中调试带参数和环境变量的 Python 程序
开发语言·python