首页 > 其他分享 >表达式求值的相关语法知识(C语言)

表达式求值的相关语法知识(C语言)

时间:2024-06-09 10:58:50浏览次数:28  
标签:C语言 char 实例 提升 求值 CPU 表达式 整型

目录

整型提升

整型提升的意义

整型提升规则

整型提升实例

算术转换

赋值转换

操作符的属性

C语言的语法并不能保证表达式的执行路径唯一!!!

问题表达式


整型提升

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

整型提升的意义

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

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

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

整型提升规则

        对于有符号的小于 int 的整型数据,在进行整型提升时根据符号位来提升

        //负数的整形提升

        char c1 = -1;
        变量c1的二进制位(补码)中只有8个比特位:
        11111111
        因为 c1 为有符号的 char
        所以整形提升的时候,高位补充符号位,即为1
        提升之后的结果是:
        111111111111111111111111111111111

        

        //正数的整形提升

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

        无符号的小于 int 的整型数据没有符号位,在进行整型提升时高位补0

        unsigned  char c1 = -1;
        变量c1的二进制位(补码)中只有8个比特位:
        11111111
        因为 c1 为无符号的 char
        所以整形提升的时候,高位补0
        提升之后的结果是:
        00000000000000000000000011111111

        

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

整型提升实例

实例一:

        实例1中的a,b要进行整型提升,但是c不需要整型提升

        a,b整型提升之后,变成了负数,所以表达式 a==0xb6 , b==0xb600 的结果是假,但是c不发生整型提升,则表达式 c==0xb6000000 的结果是真.所以打印结果为 c

实例二:

        实例2中的c只要参与表达式运算,就会发生整型提升,表达式 +c ,就会发生提升,所以 sizeof(+c) 是4个字节.表达式 -c 也会发生整型提升,所以 sizeof(-c) 是4个字节,但是 sizeof(c) ,就是1个字节.

实例三:

算术转换

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

        如果某个操作数的类型在上面这个列表中排名较低,那么首先要转换为另外一个操作数的类型后执行运算。(可能会导致精度丢失,因此算术转换要合理且慎重)

实例一:

赋值转换

        赋值时,=右边的值会转换成左边变量的数据类型(构建临时变量,右边的值本身不变化)再赋值(可能会导致精度丢失).

实例一:

操作符的属性

        复杂表达式的求值还有三个影响的因素。
        1. 操作符的优先级
        2. 操作符的结合性
        3. 是否控制求值顺序
        两个相邻的操作符先执行哪个取决于他们的优先级。如果两者的优先级相同,则取决于他们的结合性。

        下表优先级从高到低:

优先级实例一:

结合性实例一:

控制求值顺序实例一(&&和||):

C语言的语法并不能保证表达式的执行路径唯一!!!

       由于C语言的语法规则只争对相邻的操作符,因此并不能保证表达式的执行路径唯一!!!

        实例如下:

问题表达式

实例一:

实例二:

实例三:

实例四:

作者在不同编译器中测试结果:非法表达式程序的结果
—128Tandy 6000 Xenix 3.2
—95Think C 5.02(Macintosh)
—86IBM PowerPC AIX 3.2.5
—85Sun Sparc cc(K&C编译器)
—63 gcc,HP_UX 9.0,Power C 2.0.0
Sun Sparc acc(K&C编译器)
21Turbo C/C++ 4.5
22FreeBSD 2.1 R
30Dec Alpha OSF1 2.0
36Dec VAX/VMS
42 Microsoft C 5.1

        总结:我们写出的表达式如果不能通过操作符的属性确定唯一的计算路径,那这个表达式就是存在问题的。在实践中我们应避免这种问题。

标签:C语言,char,实例,提升,求值,CPU,表达式,整型
From: https://blog.csdn.net/m0_62646213/article/details/137648732

相关文章

  • 实验6 C语言结构体、枚举应用编程
    task1.c1//P286例8.172//对教材上的程序作了微调整,把输出学生信息单独编写成一个函数模块3//打印不及格学生信息和所有学生信息程分别调用45#include<stdio.h>6#include<string.h>7#defineN3//运行程序输入测试时,可以把这个数组......
  • C语言学习总结2——基本数据类型及其声明
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言1、整型家族2、浮点类型3、指针4、声明5、typedef6、常量前言在C语言中,仅有4种基本数据类型一整型、浮点型、指针和聚合类型(如数组和结构等)。所有其他的类型都是从这4种基本类型的某种组......
  • Linux -- 正则表达式基础
    提示:制作不易,可以点个关注和收藏哦。前言        虽然我们这一节的标题是正则表达式,但实际这一节实验只是介绍grep,sed,awk这三个命令,而正则表达式作为这三个命令的一种使用方式(命令输出中可以包含正则表达式)。正则表达式本身的内容很多,要把它说明清楚需要单独一门......
  • C语言学习笔记(八)————数组
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言1一维数组1.2一维数组的引用1.3一维数组的初始化2二维数组2.1二维数组的定义2.2二维数组的存放顺序3多维数组总结前言一个学习C语言的小白,有问题评论或私信~本文主要记录C语言......
  • C语言学习记录(七)————控制语句
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言控制语句是什么?一、分支语句(选择结构)1if-else语句2switch语句二、循环语句1.goto2while3do-while4for三、辅助控制语句1break2continue3return总结前言一位学习C语言的小白,有......
  • C语言学习记录(六)————输入输出
    提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档文章目录前言一、输入输出1.数据输出2.格式输出函数3.字符输入函数4格式输入函数5输入函数垃圾清理方法1:用getchar清除方法2:用格式串中空格或“%*c”来吃掉6字符串输入输出函数6.1字符串输入函数get......
  • C语言二叉平衡搜索树
    AVL(二叉平衡搜索树)的概念和思路任意一个节点左子树高度-右子树高度<=1要想让BST保持平衡,必须在每一次插入、删除之后,检查是否其左右子树满足平衡的定义如果不满足,就做“旋转”操作,使其恢复平衡加入以上平衡策略算法后的BST,称为AVL,AVL是一种绝对平衡的二叉树#include......
  • C语言中的指针(1)
    目录指针是什么?指针变量&和*操作符指针变量的类型指针变量的大小指针变量类型的意义void*指针const修饰指针const修饰变量const修饰指针变量指针运算•指针+-整数•指针-指针​编辑​编辑​编辑•指针的关系运算野指针概念成因指针未初始化​编......
  • C语言实验六
    #include<stdio.h>#include<string.h>#defineN3//运行程序输入测试时,可以把这个数组改小一些输入测试typedefstructstudent{intid;//学号charname[20];//姓名charsubject[20];//考试科目doublepe......
  • C语言笔记第12篇:自定义类型(struct结构体)
    1、结构体类型的声明为什么要有自定义的结构类型呢?这是因为稍微复杂的类型,直接使用内置类型是不行的!比如:描述一个人或 一本书的价格、版号等信息。1.1结构的创建结构体是一些值的集合,这些值称为成员变量,结构的每个成员可以是不同类型的变量。1.1.1 结构的声明structt......