服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言操作符进阶教程(表达式求值隐式类型转换方法)

C语言操作符进阶教程(表达式求值隐式类型转换方法)

2022-09-24 16:45乔乔家的龙龙 C/C++

这篇文章主要为大家介绍了C语言操作符进阶教程(表达式求值隐式类型转换方法),有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

结构体

结构体变量的声明需要在主函数之上或者主函数中声明,如果在主函数之下则会报错,而且c语言中的结构体不能直接进行强制转换,只有结构体指针才能进行强制转换。

涉及结构体的操作符这里讲两个:
. (结构体访问操作符)
-> ()

首先写一段代码:

?
1
2
3
4
5
6
int main()
{
struct Stu s = {"me",19,60};
prinft("%s %d %lf",s.who,s.age,s.weight)
return 0;
}

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

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

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

?
1
2
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去执行运算。

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

?
1
2
3
4
5
6
7
8
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。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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;

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

?
1
2
3
4
5
6
7
8
int main()
{
char c= 1;
printf("%u\n",sizeof(c));
printf("%u\n",sizeof(+c));
printf("%u\n",sizeof(-c));
return 0;
}

C语言操作符进阶教程(表达式求值隐式类型转换方法)

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

算术转换

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

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

char
short
int
long
long long
float
double

?
1
2
3
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),诸如此类,有表如下(片段):

C语言操作符进阶教程(表达式求值隐式类型转换方法)

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

C语言操作符进阶教程(表达式求值隐式类型转换方法)

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

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

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

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

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

以上就是C语言操作符进阶教程(表达式求值隐式类型转换方法)的详细内容,更多关于C语言操作符表达式求值隐式类型转换的资料请关注服务器之家其它相关文章!

原文链接:https://blog.csdn.net/qq_61500888/article/details/121317756

延伸 · 阅读

精彩推荐
  • C/C++EasyC++模板重载

    EasyC++模板重载

    这篇文章主要介绍了C++模板重载,重载的模板的函数特征,也就是入参的数量和类型必须有所不同,下面我们讲举例说明此内容,具有一定的参考价值,需...

    梁唐6302022-07-14
  • C/C++C语言中长度为0的数组详解

    C语言中长度为0的数组详解

    这篇文章主要给大家介绍了关于C语言中长度为0的数组,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友...

    zzy5703843367632022-01-21
  • C/C++C++数据结构链表基本操作示例过程

    C++数据结构链表基本操作示例过程

    这篇文章主要为大家介绍了C++数据结构链表基本操作的示例过程有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步早日升职加薪...

    xr4153832022-02-25
  • C/C++VC中CDC、HDC、pDC区别与联系及相互转换

    VC中CDC、HDC、pDC区别与联系及相互转换

    这篇文章主要介绍了VC中CDC、HDC、pDC区别与联系及相互转换的方法,非常的详细,有需要的小伙伴可以参考下,希望对大家学习VC能够有所帮助。...

    C语言教程网12282021-03-16
  • C/C++C语言直接插入排序算法介绍

    C语言直接插入排序算法介绍

    大家好,本篇文章主要讲的是C语言直接插入排序算法介绍,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下,方便下次浏览...

    绅士·永6402022-07-21
  • C/C++c语言常量定义规则知识点总结

    c语言常量定义规则知识点总结

    在本篇文章里小编给大家整理的是关于c语言常量定义规则知识点总结,需要的朋友们可以学习下。...

    angryTom6622021-08-20
  • C/C++C语言编写简单拼图游戏

    C语言编写简单拼图游戏

    这篇文章主要为大家详细介绍了C语言编写简单拼图游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    凸凸凸凸凸凸凸凸凸凸12192021-08-25
  • C/C++C++使用cuBLAS加速矩阵乘法运算的实现代码

    C++使用cuBLAS加速矩阵乘法运算的实现代码

    这篇文章主要介绍了C++使用cuBLAS加速矩阵乘法运算,将cuBLAS库的乘法运算进行了封装,方便了算法调用,具体实现代码跟随小编一起看看吧...

    白水baishui4892021-12-30