新概念炒冷饭——操作符进阶详解

简介: 正片开始👀##补充:结构体👏结构体变量的声明需要在主函数之上或者主函数中声明,如果在主函数之下则会报错,而且c语言中的结构体不能直接进行强制转换,只有结构体指针才能进行强制转换。涉及结构体的操作符这里讲两个:. (结构体访问操作符)-> ()首先写一段代码:
int main()
{
struct Stu s = {"me",19,60};
prinft("%s %d %lf",s.who,s.age,s.weight)
return 0;
}

这就是个结构体访问,这里的结构是:结构体变量 . 结构体成员,箭头怎么用呢?当我有一个结构体指针:

struct Stu * ps = &s;
printf("%s %d %lf\n"),(*ps).name,(*ps).age,(*ps).score);
return 0;

这里我是对 ps 解引用一下,找到他所指向的对象,其实和上面第一组代码的结果是一样的;但是,横看竖看都觉得有点啰嗦,我们把格局打开:

printf("%s %d %lf\n",ps->name,ps->age,ps->score);
return 0;

这样是不是看着要清爽许多?->操作符的基本语法是:结构体指针 -> 结构体成员


表达式求值👏

我们在接触那么多的操作符后,就可以应用来进行计算,表达式求值的顺序一部分是由操作符的优先级和综合性决定。同样,有些表达式的操作数在求值过程可能需要转换成其他类型。


隐式类型转换👏

C语言的整型算术运算总是至少以缺省整型类型的精度来进行的。为了获取这个精度,表达式中的字符和短整型操作数在使用之前被转换为普通整型,这种转换被称为整型提升


意义:


表达式的整型运算要在CPU的相应运算器件内执行,CPU内整型运算器(ALU)的操作数的字节长度一般就是int的字节长度,同时也是CPU的通用寄存器的长度。因此,即使两个char类型的相加,在CPU执行时实际上也要先转换为CPU内整型操作数的标准长度。通用CPU(general-purpose CPU)是难以直接实现两个8比特字节直接相加运算(虽然机器指令中可能有这种字节相加指令)。所以,表达式中各种长度可能小于int长度的整型值,都必须先转换为int或unsigned int,然后才能送入CPU去执行运算。


我们用一段代码代入一下:

int main()
{
char a = 5;
char b = 126;
char = a+b;
printf("%d\n",c);
return 0;
}

这里的一个表达式:a+b, 其中a和b的类型都是 char 类型,按照定义来看,也就是这段代码的运行远比我们想象的复杂 ,我们知道 sizeof(char),sizeof(short)的大小肯定是小于 int 类型的,所以我们计算时就要把char,short提升成 int(unsigned int)类型,再执行运算。


方法👏

整型提升是按照变量的数据类型的符号位来提升的,char x = -1 中,x的二进制位(补码)只有8个比特位,char为有符号的char所以整型提升时,高位补充符号位,即为1;无符号整型提升,高位补0。


就拿刚刚的代码进行剖析:

int main()
{
char a = 5; 
//5 = 0000……0101(32位)
//char类型一个字节8个比特位,就只能从5的二进制数中获取8位
//即a=00000101
//这一步叫截断
char b = 126;
//126 = 0000……01111110(32位)
//b = 01111110
char = a+b;
//当a,b相加时整型提升
//111111111……0000011
//111111111……0000010
//100000000……1111101(符号位不变,其他位按位取反)=-125
printf("%d\n",c);//
return 0;

下面这个代码就可以证明整型提升的存在:

int main()
{
char c= 1;
printf("%u\n",sizeof(c));
printf("%u\n",sizeof(+c));
printf("%u\n",sizeof(-c));
return 0;
}

image.png

从运行结果来看,为什么会是 4 呢?其实就是因为他参与了运算,进行了整型提升,变成了int类型。


算术转换👏

我们在刚刚谈的是 char 和 short 的计算,那如果是int 和 long ,int 和long long,int 和 float 以及 double计算呢?他们发生的就是算术转换。总的来说就是4字节以下的属于整型提升,大于4的属于算术转换。


是指如果其中操作符的各个操作数为不同类型,除非其中一个转换成另一个类型,否则无法进行操作。下面层次的系统称为寻常算术转换

char

short

int

long

long long

float

double

short a = 10;
int b = 5;
prinft("%d\n",sizeof(a+b+1));

printf 结果是 2 ,是因为short只有两个字节大小,在表达式中 short a 当家做主,不管放什么进来都是short,但是,sizeof 内部多表达式其实不会真实计算,我们写文件通常是 test.c,要生成 .exe 的可执行文件三步走:编译,链接,运行。在表达式进去在编译的时候就变成 2 了,根本到不了运行。


如果某个数类型在上表中排名较低,那会首先转换到另一个操作数的类型后执行运算。

PS.算术转换要合理,不然会出现潜在问题。

比如把 float 类型变成 int 类型就会造成精度丢失。


操作符属性👏

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

1.操作符优先级

2.操作符结合性

3.是否控制求值顺序


首先优先级是在求值时,相邻两个操作符先执行哪个的问题,当优先级相同时,取决于他们的结合性。

什么是结合性?举个栗子: a = b = c;

b的左右两侧都为 = 号,而 = 具有右结合性,故应该由右向左计算,即:a = (b = c),诸如此类,有表如下(片段):

image.png

还有一些关于优先级的常见错误值得注意一下:

image.png

有了上面这些属性是不是任意给一个表达式就可以确定一个唯一的计算路径呢?答案是:NO!比如一些问题表达式:

a*b+c*d+e*f;
a + --a;
• 1
• 2

第一个可能第一感觉就是三个部分依次先乘后加给扒拉出来,这就想的太简单了,如果我把 abcdef 换成表达式,那就可能会相互影响,存在潜在问题。

第二个就不是计算顺序的问题了,是取值时机的问题,左右操作数相互关联时,计算路径可能不唯一。


诸君谨记,以上代码谁写谁特么就是猪队友,谨记!

相关文章
|
算法
数据结构与算法-(7)---栈的应用拓展-前缀表达式转换+求值
数据结构与算法-(7)---栈的应用拓展-前缀表达式转换+求值
72 1
|
8月前
|
存储 Java
Java基础语法探究:从数据类型到控制结构
Java基础语法探究:从数据类型到控制结构
53 0
|
4月前
|
C语言
C语言判断逻辑的高阶用法
在C语言中,高级的判断逻辑技巧能显著提升代码的可读性、灵活性和效率。本文介绍了六种常见方法:1) 函数指针,如回调机制;2) 逻辑运算符组合,实现复杂条件判断;3) 宏定义简化逻辑;4) 结构体与联合体组织复杂数据;5) 递归与分治法处理树形结构;6) 状态机管理状态转换。通过这些方法,可以更高效地管理和实现复杂的逻辑判断,使代码更加清晰易懂。
246 88
|
4月前
|
C语言
C语言程序设计核心详解 第二章:数据与数据类型 4种常量详解 常见表达式详解
本文详细介绍了C语言中的数据与数据类型,包括常量、变量、表达式和函数等内容。常量分为整型、实型、字符型和字符串常量,其中整型常量有十进制、八进制和十六进制三种形式;实型常量包括小数和指数形式;字符型常量涵盖常规字符、转义字符及八进制、十六进制形式;字符串常量由双引号括起。变量遵循先定义后使用的规则,并需遵守命名规范。函数分为标准函数和自定义函数,如`sqrt()`和`abs()`。表达式涉及算术、赋值、自增自减和逗号运算符等,需注意运算符的优先级和结合性。文章还介绍了强制类型转换及隐式转换的概念。
|
6月前
|
存储 Java 索引
Java数组操作:基础与进阶指南
Java数组操作:基础与进阶指南
|
7月前
|
开发框架 .NET 程序员
掌握C#语言的精髓:基础知识与实用技能详解(数据类型与变量+ 条件与循环+函数与模块+LINQ+异常+OOP)
掌握C#语言的精髓:基础知识与实用技能详解(数据类型与变量+ 条件与循环+函数与模块+LINQ+异常+OOP)
39 0
|
8月前
|
C++
关系表达式:编程中的比较利器
在编程中,关系表达式扮演着至关重要的角色。它们允许我们比较两个或多个值,并基于这些比较的结果来执行相应的操作。关系表达式通过返回布尔值(真或假)来告诉我们两个值之间的关系,从而帮助我们在程序中做出决策。
77 0
|
8月前
|
Java
基本概念【算术、 关系、逻辑、位、字符串、条件、优先级等运算符】(三)-全面详解(学习总结---从入门到深化)
基本概念【算术、 关系、逻辑、位、字符串、条件、优先级等运算符】(三)-全面详解(学习总结---从入门到深化)
77 0
|
8月前
|
存储 Java 程序员
Java数组全套深入探究——基础知识阶段2、数组的定义语法
Java数组全套深入探究——基础知识阶段2、数组的定义语法
70 0
|
前端开发
前端经典面试题 | New操作符的原理
前端经典面试题 | New操作符的原理