C 语言的类型转换

文章目录

  • 自动类型转换
  • 强制类型转换

自动类型转换

Statements and expressions should normally use variables and constants of just one type. If, however, you mix types, C doesn’t stop dead in its tracks the way, say, Pascal does. Instead, it uses a set of rules to make type conversions automatically. This can be a convenience, but it can also be a danger, especially if you are mixing types inadvertently.

It is a good idea to have at least some knowledge of the type conversion rules.

The basic rules are

  1. When appearing in an expression, char and short , both signed and unsigned , are automatically converted to int or, if necessary, to unsigned int . (If short is the same size as int , unsigned short is larger than int ; in that case, unsigned short is converted to unsigned int .) Under K&R C, but not under current C, float is automatically converted to double . Because they are conversions to larger types, they are called promotions.
  2. In any operation involving two types, both values are converted to the higher ranking of the two types.
  3. The ranking of types, from highest to lowest, is long double , double , float , unsigned long long , long long , unsigned long , long , unsigned int , and int . One possible exception is when long and int are the same size, in which case unsigned int outranks long . The short and char types don’t appear in this list because they would have been already promoted to int or perhaps unsigned int.
  4. In an assignment statement, the final result of the calculations is converted to the type of the variable being assigned a value. This process can result in promotion, as described in rule 1, or demotion , in which a value is converted to a lower-ranking type.
  5. When passed as function arguments, char and short are converted to int , and float is converted to double . This automatic promotion is overridden by function prototyping.

Promotion is usually a smooth, uneventful process, but demotion can lead to real trouble. The reason is simple: The lower-ranking type may not be big enough to hold the complete number. For instance, an 8-bit char variable can hold the integer 101 but not the integer 22334.

What happens when the converted value won’t fit into the destination? The answer depends on the types involved. Here are the rules for when the assigned value doesn’t fit into the destination type:

  1. When the destination is some form of unsigned integer and the assigned value is an integer, the extra bits that make the value too big are ignored. For instance, if the destination is 8-bit unsigned char , the assigned value is the original value modulus 256.
  2. If the destination type is a signed integer and the assigned value is an integer, the result is implementation-dependent.
  3. If the destination type is an integer and the assigned value is floating point, the behavior is undefined. What if a floating-point value will fit into an integer type? When floating types are demoted to integer types, they are truncated, or rounded toward zero. That means 23.12 and 23.99 both are truncated to 23 and that -23.5 is truncated to -23.

代码示例:

#include
int main(void)
{
	char ch;
	int i;
	float fl;

	ch = i = fl = 'C';
	printf("ch = %c, i = %d, fl = %2.2f\n", ch, i, fl);

	return 0;
}

结果:

ch = C, i = 67, fl = 67.00

分析:

这里, 字符 ‘C’ 作为一字节的 ASCII 值, 储存在 ch 中.

整数变量 i 接受由字符 ‘C’ 转换而来的整数, 即 67, 然后按照 4 字节储存 67.

浮点型变量 fl 接受由字符 ‘C’ 转换而来的整数, 即 67, 再将 67 转换为浮点数, 67.00.

程序示例:

#include
int main(void)
{
	char ch;

	ch = 'C' + 1;
	printf("ch = %c\n", ch);

	return 0;
}
ch = D

分析:

字符 ‘C’ 转换成整数, 即 67, 然后加 1. 计算结果是四字节的整数 68, 然后被截断成 1 字节的整数 68, 储存在字符型变量 ch 中, 根据转换说明 %c 进行打印时, 68 被解释成 ‘D’ 的 ASCII 码值. 于是打印字符 D.

程序示例:

#include
int main(void)
{
	char ch = 'A';
	int i;
	float fl = 2.0f;

	printf("字母 A 的 ASCII 码是:%d\n", ch);
	i = fl + ch * 2;
	printf("i = %d\n", i);

	return 0;
}

结果:

字母 A 的 ASCII 码是:65
i = 132

分析:

语句 i = fl + ch * 2; 中, ch 为了和 2 相乘, 需要先转换为 4 位的 int 型的 65, 得到计算结果为 4 位的 int 型的 130.

4 位的 int 型的 130 为了和 float 类型的 fl 相加, 需要先转换为 float 类型, 即 130f.

变成了 130.0f + 2.0f , 得到结果为 132.0f.

要把 132.0f 赋值给 int 类型的 i, 需要把 132.0f 转变为 4 位的 int 类型的 132, 储存在 int 类型的 i 中.

程序示例:

#include
int main(void)
{
	char ch = 1107;
	printf("%c\n", ch);
	printf("%d\n", 1107 % 256);
	printf("%c\n", 1107 % 256);

	return 0;
}

结果:

S
83
S

分析:

这里显示了降级的过程.

把 ch 设置为超出其范围的一个值, 忽略额外的位, 按照上述的规则, 相当于将这个值对 265 求模.

程序示例:

#include
int main(void)
{
	char ch = 87.56;
	printf("%d\n", ch);
	printf("%c\n", ch);
	printf("%c\n", 87);

	return 0;
}

结果:

87
W
W

分析:

演示了另一个截断的例子. 这里将一个 float 值赋给了 char 类型变量, 丢弃了小数点后面的数字.

强制类型转换

应该尽量避免自动类型转换, 尤其是降级.

有时需要进行精确的类型转换, 或者明确指明类型转换的意图.

可使用强制类型转换 (cast)

即, 在某个变量的前面放置一个用括号括起来的类型名, 该类型名是希望转换成的目标类型.

圆括号和它括起来的类型名构成了强制类型转换运算符 (cast operator)

通用形式为:

(type) variable

代码示例:

int a = 4.4 + 4.5;
int b = (int)4.4 + (int)4.5;

第一行是自动类型转换. 首先 4.4 和 4.5 相加, 得到 8.9, 然后为了将 8.9 赋值给 int 类型的变量 a, 将 8.9 截断为 8.

第二行是强制类型转换. 相加之前 4.4 和 4.5 分别被转换为 4 和 5. 把 4+5 的结果赋给 b.

你可能感兴趣的:(C,语言,c语言)