2.5 C语言之类型转换

2.5 C语言之类型转换

一、类型转换

当一个运算符的几个操作数类型不同时,就需要通过一些规则把它们转换为某种共同的类型。

  • 一般来说,自动转换是指把"比较窄的"的操作数转换为"比较宽的"的操作数,并且不丢失信息的转换。例如:
c 复制代码
	float f = 1.2;
	int i = 2;
	float g = f + i;  // 在计算f+i的时候,将整型变量i的值自动转换为浮点型
	printf("%f", g);
  • 不允许使用无意义的表达式,例如,不允许把float类型的表达式作为下标
  • 针对可能导致信息丢失的表达式,编译器可能会给出警告信息,比如把较长的整型值赋给较短的整型变量,把浮点型值赋值给整型变量,等等,但这些表达式并不非法。
c 复制代码
	float f = 1.2;
	int i = f; // 将浮点型赋值给整型,丢失信息0.2
	printf("%d\n", i); // 1
	i = 128;
	char j = i; // 将int类型赋值给char类型,128已经超出char类型的范围 -128~127  注意:有些机器的char是无符号时,取值范围为0~255
	printf("%d\n", j); // -128
  • 将字符类型转换为整型时,我们需要注意一点:C语言中没有指定char类型的变量是无符号还是带符号变量。所以,当把一个char类型的变量转换为int类型的值时,其结果有没有可能是负整数呢?答案是不一定,取决于具体的机器实现。在某些机器中,如果char类型的最左一位为1,则转换为负整数(符号扩展);而在另一些机器中,char类型左边添加0,则转换为正整数。
  • C语言的定义保证了机器的标准打印字符集中的字符不会是负值,因此,在表达式中,这些字符总是正值。但是,存储在字符变量中的位模式在某些机器中可能是负的。所以,为了保证程序的可移植性,如果要在char类型的变量中存储非字符数据,最好指定signed或unsigned限定符。
c 复制代码
	unsigned char c = 2;
    int i = c;
    printf("%d\n", i);
  • 隐式类型转换规则
    • 二元运算符的两个操作数类型不同
      • 没有unsigned操作数
        • 如果其中一个操作数的类型为long double,则将另一个操作数转换为long double类型
        • 如果其中一个操作数的类型为double,则将另一个操作数转换为double类型(注意:float不会自动转换为double)
        • 如果其中一个操作数的类型为float,则将另一个操作数转换为float类型
        • 将char类型和short类型转换为int类型
        • 如果其中一个操作数的类型为long,则将另一个操作数转换为long类型
      • 有unsigned操作数时,转换规则要复杂一些,主要原因在于,带符号值与无符号值之间的比较运算是与机器相关的,因为它们取决于机器中不同整数类型的大小。例如:假定int类型占16位,long类型占32位,那么,-1L<1U,这是因为unsigned int类型的1U将被提升为signed long类型;但-1L > 1UL,这是因为-1L将被提升为unsigned long类型,因而成为一个比较大的正数。
    • 赋值时,赋值运算符右边的值需要转换为左边变量的类型。
    • 字符型变量都将被转为整型变量
    • 当把较长的整数转为较短的整数或char类型时,超出的高位部分将被丢弃。
    • float转换为int类型时,小数部分将被截取掉
    • double转换为float类型时,是四舍五入还是截取,取决于具体的实现
    • 由于函数调用的参数是表达式,所以把参数传递给函数时也可能进行类型转换。在没有函数原型的情况下,char与short类型将被转换为int类型,float类型将被转换为double类型。因此,即使调用函数的参数为char或float类型,我们也把函数参数声明为int或double类型。
  • 显式类型转换规则
    • 在任何表达式中,都可以使用一个称为强制类型转换的一元运算符强制进行显式类型转换。其形式如:
      (类型名) 表达式
      在上述语句中,表达式首先被赋值给类型名指定的类型的某个变量,然后再用该变量替换上述整条语句。最终结果就是上述表达式被转换为类型名指定的类型,例如库函数sqrt(double),如果给sqrt函数传入一个整数n,可以用 sqrt((double) n),在把n传递给函数之前先将其强制转换为double类型。(注意:强制类型转换只是生成一个指定类型的n的值,n本身并没有改变)
      • 在通常情况下,参数是通过函数原型声明的,这样,当函数被调用时,声明将对参数进行自动强制转换。例如,对于sqrt的函数原型:double sqrt(double); 下列函数调用:
        root = sqrt(2);
        不需要使用强制转换运算符就可以自动将整数2强制转换为double类型的值2.0
相关推荐
珹洺2 小时前
C语言数据结构——详细讲解 双链表
c语言·开发语言·网络·数据结构·c++·算法·leetcode
.Cnn3 小时前
用邻接矩阵实现图的深度优先遍历
c语言·数据结构·算法·深度优先·图论
2401_858286113 小时前
101.【C语言】数据结构之二叉树的堆实现(顺序结构) 下
c语言·开发语言·数据结构·算法·
寻找码源4 小时前
【头歌实训:利用kmp算法求子串在主串中不重叠出现的次数】
c语言·数据结构·算法·字符串·kmp
带多刺的玫瑰5 小时前
Leecode刷题C语言之统计不是特殊数字的数字数量
java·c语言·算法
陌小呆^O^6 小时前
Cmakelist.txt之win-c-udp-server
c语言·开发语言·udp
时光の尘6 小时前
C语言菜鸟入门·关键字·float以及double的用法
运维·服务器·c语言·开发语言·stm32·单片机·c
-一杯为品-6 小时前
【51单片机】程序实验5&6.独立按键-矩阵按键
c语言·笔记·学习·51单片机·硬件工程
爱摸鱼的孔乙己7 小时前
【数据结构】链表(leetcode)
c语言·数据结构·c++·链表·csdn
Dola_Pan7 小时前
C语言:数组转换指针的时机
c语言·开发语言·算法