C语言——表达式求值中类型转换和优先级等问题

简介: C语言——表达式求值中类型转换和优先级等问题

1.隐式类型转换

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

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

整型提升的意义:

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


如何进行整形提升呢?

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

负数的整形提升

正数的整形提升

无符号整形提升,高位补0

分析下面的代码:

具体过程如下:

程序输出结果:

分析下面的代码:

c只要参与表达式运算,就会发生整形提升,表达式 +c ,就会发生提升,所以 sizeof(+c) 是4个字节.

表达式 -c 也会发生整形提升,所以 sizeof(-c) 是4个字节,但是 sizeof(c) ,就是1个字节.

2.算数转换

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

3.操作符的属性

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


1. 操作符的优先级


2. 操作符的结合性


3. 是否控制求值顺序。


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


相邻操作符优先级高的先计算,低的后算。


相邻操作符的优先级相同的情况下,结合性起作用。


即使掌握了各种操作符的优先级和结合性,我们也可能回写出bug:

int main()
{
  int i = 10;
  i = i-- - --i * (i = -3) * i++ + ++i;
  printf("i = %d\n", i);
  return 0;
}

这串代码再不同的编译器下可能会产生不同的结果。

下面的代码也是错误代码,再不同的编译器中的结果也有所不同:

在vs编译器下ret的结果时12,而在gcc下ret的值时10

目录
相关文章
|
15天前
|
C语言
【C语言】符号优先级详解 -《谁与争锋 ! 》
理解C语言中的运算符优先级和结合性是编写正确代码的关键。本文详细介绍了C语言中的各种运算符、它们的优先级和结合性,并通过示例展示了如何正确使用这些运算符。掌握这些知识,将有助于编写出逻辑严谨、结构清晰的C语言程序。
51 8
|
2月前
|
编译器 C语言
共用体和结构体在 C 语言中的优先级是怎样的
在C语言中,共用体(union)和结构体(struct)的优先级相同,它们都是用户自定义的数据类型,用于组合不同类型的数据。但是,共用体中的所有成员共享同一段内存,而结构体中的成员各自占用独立的内存空间。
|
7月前
|
C语言
C语言中的关系运算符和关系表达式
C语言中的关系运算符和关系表达式
81 0
|
7月前
|
C语言
C语言中的条件运算符和条件表达式详解
C语言中的条件运算符和条件表达式详解
673 0
|
3月前
|
程序员 C语言
【C语言基础考研向】06运算符与表达式
本文介绍了C语言中的运算符分类、算术运算符及表达式、关系运算符与表达式以及运算符优先级等内容。首先概述了13种运算符类型,接着详细说明了算术运算符的优先级与使用规则,以及关系运算符和表达式的真假值表示,并给出了C语言运算符优先级表。最后附有课后习题帮助巩固理解。
115 10
|
3月前
|
存储 人工智能 C语言
数据结构基础详解(C语言): 栈的括号匹配(实战)与栈的表达式求值&&特殊矩阵的压缩存储
本文首先介绍了栈的应用之一——括号匹配,利用栈的特性实现左右括号的匹配检测。接着详细描述了南京理工大学的一道编程题,要求判断输入字符串中的括号是否正确匹配,并给出了完整的代码示例。此外,还探讨了栈在表达式求值中的应用,包括中缀、后缀和前缀表达式的转换与计算方法。最后,文章介绍了矩阵的压缩存储技术,涵盖对称矩阵、三角矩阵及稀疏矩阵的不同压缩存储策略,提高存储效率。
469 8
|
3月前
|
C语言
C语言程序设计核心详解 第二章:数据与数据类型 4种常量详解 常见表达式详解
本文详细介绍了C语言中的数据与数据类型,包括常量、变量、表达式和函数等内容。常量分为整型、实型、字符型和字符串常量,其中整型常量有十进制、八进制和十六进制三种形式;实型常量包括小数和指数形式;字符型常量涵盖常规字符、转义字符及八进制、十六进制形式;字符串常量由双引号括起。变量遵循先定义后使用的规则,并需遵守命名规范。函数分为标准函数和自定义函数,如`sqrt()`和`abs()`。表达式涉及算术、赋值、自增自减和逗号运算符等,需注意运算符的优先级和结合性。文章还介绍了强制类型转换及隐式转换的概念。
|
4月前
|
C语言
C语言------运算符与表达式
这篇文章是C语言运算符与表达式的实训教程,通过多个示例程序展示了如何使用算术运算符、关系运算符、逻辑运算符以及条件语句来解决实际问题,并介绍了如何通过函数库简化复杂数学运算。
C语言------运算符与表达式
|
7月前
|
安全 程序员 C语言
从C语言到C++_37(特殊类设计和C++类型转换)单例模式(下)
从C语言到C++_37(特殊类设计和C++类型转换)单例模式
56 5
|
7月前
|
IDE 测试技术 开发工具