C强制类型转换

C强制类型转换

为了提高效率,C 语言对于不同的两个类型将直接转换成较高类型计算。

举个例子:对于已经分别被定义且被赋值,类型为 double 和 int 的 a 和 b:

假设如果进行 a + b 运算,那么b将直接被隐式转换为 double 类型,然后再进行运算,不能理解为逐层转换(即不能理解为b先转换为unsigned int类型,再转换为 long => unsigned long => long long => unsigned long long => float => double类型,最后再进行运算)。

p.s: 说到运算,对于 char 和 short 类型,进行运算时将会被隐式转换为 int,看代码:

#include

int main() {

char c = 22, ch = 33;

short m = 23, n = 32;

printf("%d\n", sizeof(c + ch)); //char和char类型的运算

printf("%d\n", sizeof(m + n)); //short和short类型的运算

printf("%d", sizeof(m + ch)); //short和char类型的运算

return 0;

}

输出:

4

4

4

这里没讲,顺带补充一下转换规则:

1、float、double、long double 类型赋值给整数类型:直接截断小数

如:

#include

int main() {

float a = 3.8;

int b = a; //进行了一次隐式类型转换

printf("a=%.2f; b=%d", a, b);

return 0;

}

根据转换规则和隐式类型转换规则,输出的结果为:

a=3.80; b=3

2、整数类型赋值给浮点数(float、double、long double)类型:补足有效小数位

对上述代码进行修改:

#include

int main() {

int a = 8;

float b = a; //进行了一次隐式类型转换

printf("a=%d; b=%f", a, b);

return 0;

}

输出:

a=8; b=8.000000 //%f默认输出6位小数

3、存储长度较短的类型赋值给存储长度较长的类型:补足有效位,其它位补 0

假设有如下定义:

char c = 56;

short num = 67;

int m;

long long int n;

如果执行以下操作:

m = ((int)c);

n = ((long long)num);

那么它们在内存以 2 进制格式分别存储为:

00111000 //Binary of 'c'

00000000 01000011 //Binary of 'num'

00000000 00000000 00000000 00111000 //Binary of 'm'

00000000 00000000 00000000 00000000 00000000 00000000 00000000 01000011 //Binary of 'n'

4、存储长度较长的类型赋值给存储长度较短的类型:舍弃高位(但保留符号),截断低字节给存储长度较短的类型

假设定义:

long long int l = 223372036854775807;

进行赋值:

int i = (int)l;

它们在内存以2进制格式分别存储为:

00000011 00011001 10010011 10101111 00011101 01111011 11111111 11111111 //Binary of 'l'

00011101 01111011 11111111 11111111 //Binary of 'v'

p.s: 此时的 v=494665727。

顺带说明一下,如果变量 “l” 的后 32 个字节都为 1,那么 v 将等于 -1。

5、unsigned类型赋值给非unsigned类型:直接传递数值

注意:如果 unsigned 类型储存的量太大,强制类型转换后可能会出现非 unsigned 类型的值的绝对值不等于 unsigned 类型的值的绝对值的情况。

说到 “unsigned 类型储存的量太大”,顺带说一下,虽然 printf 输出 int 和 unsigned int 时可以混用 %d(或%i)和 %u(或%ui),但还是建议输出 int 类型的时候用 %d(或%i),输出 unsigned int 类型时用 %u(或%ui)(其它类型同理<如%ul等>)

看一个例子:

#include

int main() {

unsigned int x = 4294967295; //这个数字为(2^32)-1, 而int类型最大存储数字的值为(2^31)-1

int y = ((int)x);

printf("signed of x=%d", x); //这里有一次隐式类型转换(unsigned int => int)

putchar('\n');

printf("unsigned of x=%u\n", x);

printf("signed of y=%d", y);

return 0;

}

可是因为隐式类型转换,结果输出为:

-1

4294967295

-1

出现“-1”的这个输出就是因为“unsigned类型储存的量太大(大于了同类型但非unsigned的类型)”

p.s: 不一定都为 -1,具体要看 unsigned 类型的值的 2 进制

6、非 unsigned 类型赋值给 unsigned 类型:直接传递数值

给个小技巧:如果你想“临时”给一个不知道正负的非 unsigned 类型的变量加上绝对值,可以使用abs函数,但利用(unsigned)(非unsigned类型变量名)可以节省一点内存开销

但是也有弊端:可能会出现 unsigned-unsigned 永远大于 0 的情况(不确定)

最后补充一下,强制类型转换只是临时类型转换,并不影响变量本身储存的值,看如下代码:

#include

int main() {

float a = 6.9;

printf("%.3f", a);

putchar('\n');

((int)a);

printf("%.3f", a);

return 0;

}

输出结果:

6.900

6.900ssl ssl

157***1786@qq.com

3年前 (2022-08-28)

相关推荐