当预期在不同类型的值的上下文中使用表达式时,可能会发生转换:
int n = 1L; // expression 1L has type long, int is expectedn = 2.1; // expression 2.1 has type double, int is expectedchar *p = malloc(10); // expression malloc(10) has type void*, char* is expected
转换发生在以下情况:
按照分配进行转换
在赋值运算符中,右侧操作数的值被转换为左侧操作数的非限定类型。
在标量初始化中,初始化表达式的值被转换为被初始化的对象的非限定类型
在函数调用表达式中,对于具有原型的函数,将每个参数表达式的值转换为相应参数的非限定声明类型
在return语句中,操作数的值return被转换为具有函数返回类型的对象
请注意,除转换外,实际分配也会从浮点类型中移除额外的范围和精度,并禁止重叠; 这些特性不适用于转换,就像通过分配一样。
默认参数优化
在调用时的函数调用表达式中。
1)没有原型的功能
2)可变参数函数,其中参数表达式是与省略号参数匹配的尾随参数之一
整数类型的每个参数都经过整数提升(参见下文),并且每个类型的参数都float被隐式转换为类型double。
int add_nums(int count, ...);int sum = add_nums(2, 'c', true); // add_nums is called with three ints: (2, 99, 1)
请注意,float complex和float imaginary没有提升到double complex和double imaginary在这种情况下。
通常的算术转换
以下算术运算符的参数经过隐式转换,以获得公共实数类型,这是执行计算的类型:
二进制算术*,/,%,+, -
关系运算符,<=,> =,==,!=
二进制按位运算&,^,|,
条件操作符?:
1)如果一个操作数是long double,long double complex或long double imaginary,另一个操作数被隐式转换如下:
整数或实际浮动类型 long double
复杂类型 long double complex
虚构类型 long double imaginary
2)否则,如果一个操作数是double,double complex或double imaginary,另一个操作数被隐式转换如下:
整数或实际浮动类型 double
复杂类型 double complex
虚构类型 double imaginary
3)否则,如果一个操作数是float,float complex或float imaginary,另一个操作数被隐式转换如下:
整数类型为float(唯一可能的实际类型是float,保持原样)
复杂类型依然存在 float complex
虚构类型仍然存在 float imaginary
4)否则,两个操作数都是整数。在这种情况下,首先,两个操作数都进行整数升级(见下文)。然后
如果促销后的类型相同,则该类型是常见类型
否则,如果促销后的两个操作数具有相同的签名(均为有符号或无符号),则具有较低转换等级的操作数(请参见下文)会隐式转换为具有较高转换等级的操作数的类型
否则,签名会有所不同:如果具有无符号类型的操作数的转换等级大于或等于有符号操作数类型的等级,则带符号类型的操作数将隐式转换为无符号类型
否则,签名是不同的,并且带符号的操作数的等级大于无符号的操作数的等级。