登录/注册

语言中的类型转换

我们在前面学习了 C 语言的数据类型,那么变量在参与运算的时候类型是始终如一不变的吗?

带着这个疑问,我们可以先看一个例子:

#include <stdio.h>

#define typename(x) _Generic[1];
    a=b+c;
    printf("a=b+c, a=%dn",a);
    printf("type (b+c): %sn",typename(b+c));
    d=b+c;
    printf("d=b+c, d=%fn",d);
    return 0;
}

经过编译运行后得到如下的结果:

Tips:有关如何编译运行的内容请参考前面的章节。 Tips:同时值得注意的是,这个程序中的 _Generic 来自于 C11 标准中,所以在你之前可能看到的 C 语言的书籍中是没有的。请大家不要使用过于古老的编译器,请使用推荐的较新的编译器。也就是支持 C11 以上标准的编译器。具体情况可以参照你们所选择的编译器的手册。或者直接选择 GCC 7 及更新版本的编译器。

a type: int, b type: int, c type: float, d type: float
a=b+c, a=5
type (b+c): float
d=b+c, d=5.141590

这里面的 a, b 变量为整形,而 c 和 d 都是浮点型。那么当一个整形和一个浮点型相加的时候会发生什么呢?这就是我们今天要介绍的内容。

1. 隐式类型转换

C 语言是强类型语言,也就是说不同类型的数据之间是不能进行运算的。必须保持一致的类型才能进行运算。也就是说在这个不同数据类型的计算过程中,C 语言自动进行了一次类型转换,使得两个变量的数据类型一致,才能进行相关的计算。这种自动的转换,也称之为隐式类型转换。

从前面提及的例子还可以看出,我们定义的数据类型,在不同的类型的数据运算结束后,并没有发生改变,也就是数据类型保持着我们最开始定义时候的类型。这时会发生丢弃精度的事情,也就是上面例子中小数点后面的数值就会消失。

那么这种隐式的转换有什么规律可循吗?

下面的表格就展示了类型转换的规律,当在计算过程中,数值类型不一致的时候,就会发生自动的类型转换,转换的类型是将表格中处于下方的较低优先级的数据类型,向表格上方的较高优先级的数据类型进行转换。

级别 数据类型
1 long double
2 double
3 float
4 unsigned long long
5 long long
6 unsigned long
7 long
8 unsigned int
9 int
10 char short int

根据这个表格我们就可以看出之前的转换中,int 与 float 类型进行计算,编译器会自动将 int 类型转换为 float 类型进行计算。从而使得运算在相同的数据类型间进行。

2. 显式类型转换

如果说隐式类型转换是编译器自动进行的类型转换,那么显式类型转换,则是我们人为的进行数据类型的转换,这里可以理解为是一种强制的类型的转换,这种转换将不再遵守上面的转换规则,而是按照我们人为的标明的类型进行转换。

就是在我们需要指定类型的变量前加上数据类型,并用圆括号包裹。例如: (int)a, (float)b, (long)c 等。

下面我们通过一个示例程序来看一下显式类型转换:

#include <stdio.h>

#define typename(x) _Generic[2];
    a=(float)b+(float)c;
    printf("a=b+c, a=%dn",a);
    printf("type (b+c): %sn",typename[3];
    d=(int)b+(int)c;
    printf("d=b+c, d=%fn",d);
    return 0;
}#include <stdio.h>

#define typename(x) _Generic[4];
    a=(float)b+(float)c;
    printf("a=b+c, a=%dn",a);
    printf("type (b+c): %sn",typename[5];
    d=(int)b+(int)c;
    printf("d=b+c, d=%fn",d);
    return 0;
}

下面是执行结果。

a type: int, b type: int, c type: float, d type: float
a=b+c, a=5
type (b+c): int
d=b+c, d=5.000000

通过显式类型转换,我们可以控制在计算过程中的数据类型。之前自动转换为 float 类型的数据,在我们显式指定为 int 类型后,计算过程中就会按照 int 类型来进行计算。

3. 小结

对于隐式类型转换。其实变化的原因主要是因为计算的数值为了匹配计算精度而进行的,一般情况下都是较低精度的变量类型会转变为较高精度的变量类型。

而显式类型转换则是我们主动控制了类型的精度,可以抛去我们不需要的高的精度。同时,由于指定了类型,在转换过程中不会产生歧义。

Tips: 请注意,这里在类型转换的过程中不会自动进行四舍五入等操作,因此如果使用不当会造成数据的精度丢失。

4. 参考文献

  1. Type Conversion in C
  2. Type Casting – C Programming
  3. TypeCasting in C: Implicit, Explicit with Example
  4. How do I check if a variable is of a certain type (compare two types) in C?
  5. Syntax and Sample Usage of _Generic in C11
参考资料
  1. x), /* Get the name of a type */ _Bool: "_Bool", unsigned char: "unsigned char", char: "char", signed char: "signed char", short int: "short int", unsigned short int: "unsigned short int", int: "int", unsigned int: "unsigned int", long int: "long int", unsigned long int: "unsigned long int", long long int: "long long int", unsigned long long int: "unsigned long long int", float: "float", double: "double", long double: "long double", char *: "pointer to char", void *: "pointer to void", int *: "pointer to int", default: "other") int main() { int a=1,b=2; float c=3.14159,d=0; printf("a type: %s, b type: %s, c type: %s, d type: %sn",typename(a),typename(b),typename(c),typename(d 

  2. x), /* Get the name of a type */ _Bool: "_Bool", unsigned char: "unsigned char", char: "char", signed char: "signed char", short int: "short int", unsigned short int: "unsigned short int", int: "int", unsigned int: "unsigned int", long int: "long int", unsigned long int: "unsigned long int", long long int: "long long int", unsigned long long int: "unsigned long long int", float: "float", double: "double", long double: "long double", char *: "pointer to char", void *: "pointer to void", int *: "pointer to int", default: "other") int main() { int a=1,b=2; float c=3.14159,d=0; printf("a type: %s, b type: %s, c type: %s, d type: %sn",typename(a),typename(b),typename(c),typename(d 

  3. int)b+(int)c 

  4. x), /* Get the name of a type */ _Bool: "_Bool", unsigned char: "unsigned char", char: "char", signed char: "signed char", short int: "short int", unsigned short int: "unsigned short int", int: "int", unsigned int: "unsigned int", long int: "long int", unsigned long int: "unsigned long int", long long int: "long long int", unsigned long long int: "unsigned long long int", float: "float", double: "double", long double: "long double", char *: "pointer to char", void *: "pointer to void", int *: "pointer to int", default: "other") int main() { int a=1,b=2; float c=3.14159,d=0; printf("a type: %s, b type: %s, c type: %s, d type: %sn",typename(a),typename(b),typename(c),typename(d 

  5. int)b+(int)c 

原文地址:https://blog.csdn.net/q7825103/article/details/105379906
文章来源与用户投稿或网络采集,如果您是本文的作者,发现版权或转载方式问题请右侧邮箱联系管理员。

抢沙发

共同学习,写下你的评论
姓名
电子邮件
个人主页