04-类型转换

  • Post author:
  • Post category:其他


注:博客中内容主要来自《狄泰软件学院》,博客仅当私人笔记使用。

测试环境:ubuntu 14.04

GCC版本:4.8.4

一、类型之间的转换

1)C语言中的数据类型可以进行转换


* 强制类型转换


* 隐式类型转换

int main()
{
    long l = 800;
    int i = (int)l; //强制类型转换 

    short s = 800;
    int j = s;    //隐式类型转换
                  //no error, no warning 

    return 0;
}

二、强制类型转换

1)强制类型转换的语法

* (

Type

)var_name;

* (

Type

)value;

2)强制类型转换的结果


* 目标类型


能够容纳


目标值:


结果不变


* 目标类型


不能容纳


目标值:


结果将产生截断


注意:


不是所有的强制类型转换都能成功,当不能进行强制类型转换时,编译器将产生错误信息。

实例分析
强制类型转换分析
4-1.c
#include <stdio.h>

struct TS
{
    int i;
    int j;
};

struct TS ts;

int main(void)
{
    short s = 0x1122;
    char c = (char)s;    //0x22,数据高位截断
    int i = (int)s;    //0x00001122
    int j = (int)3.1415;    //3
    unsigned int p = (unsigned int)&ts;

    printf("s = %#x\n", s);    //0x1122    
    printf("c = %#x\n", c);    //0x22
    printf("i = %#x\n", i);    //0x00001122
    printf("j = %#x\n", j);    //0x3
    printf("p = %#x\n", p);
    printf("&ts = %p\n". &ts);

    return 0;
}

操作:

1)gcc 4-1.c -o 4-1.out编译,打印如下:

s = 0x1122
c = 0x22
i = 0x1122
j = 0x3
p = 0x804a024
&ts = 0x80a024

分析:

编译正常,都可以正常打印。

2)增加内容,测试强制转换失败:

#include <stdio.h>

struct TS
{
    int i;
    int j;
};

struct TS ts;

int main(void)
{
    short s = 0x1122;
    char c = (char) s;    //0x22,数据高位截断
	int i = (int) s;		//0x00001122
	int j = (int)3.1415;	//3
	unsigned int p = (unsigned int) &ts;

	long l = (long) ts;		//error	结构体不能转换成其他类型

	ts = (struct TS)l;	    //error

	printf("s = %#x\n" , s);		//0x1122
	printf("c = %#x\n" , c);		//0x22
	printf("i = %#x\n" , i);		//0x00001122
	printf("j = %#x\n" , j);		//0x3
	printf("p = %#x\n" , p);		
	printf("&ts = %p\n" , &ts);	      

    return 0;
}

gcc 4-1.c -o 4-1.out编译错误:

4-1.c:23:2: error: aggregate value used where an integer was expected
  long l = (long) ts;
  ^
错误:结构体的值期望被转换为long

4-1.c:24:15: error: conversion to non-scalar type requested
  ts = (struct TS)l;
               ^
错误:基础类型转换为结构体类型

解释:

编译时如果有无法转换成功的类型,编译器会报错。

三、隐式类型转换

1)隐式类型转换

*

编译器主动进行的类型转换

char c = 0;    //变量C占用1个字节
short s = c;    //c到s隐式类型转换
int i = s;    //s到i隐式类型转换
long l = i;    //i到l隐式类型转换


注意:


低类型到高类型的隐式类型转换是安全的,不会产生截断;


高类型到低类型的隐式类型转换是不安全的,会产生截断,可能丢失数据。

四、表达式中的隐式类型转换

1)隐式类型转换的发生点


* 算术运算式中,低类型转换为高类型


* 赋值表达式中,表达式的值转换为左边变量的类型


* 函数调用时,实参转换为形参的类型


* 函数返回值,return表达式转换为返回值类型

实例分析
隐式类型转换分析
4-2.c
#include <stdio.h>

int main()
{
    char c = 'a';
    int i = c;    //safe,低类型转换为高类型
    unsigned int j = 0x11223344;
    short s = j;    //unsafe,0x3344

    printf("c = %c\n",c);    //a
    printf("i = %d\n", i);    //97
    printf("j = %x\n", j);    //0x11223344
    printf("s = %x\n", s);    //0x3344
    printf("sizeof(c + s) = %d\n", sizeof(c + s));    //4

    return 0;
}

操作:

1)gcc 4-2.c -o 4-2.out编译,打印如下:

c = a
i = 97
j = 11223344
s = 3344
sizeof(c + s) = 4

分析:

* unsigned int转换为short,发生截断,导致高位数据丢失(小端系统)

* 计算c+s大小时,先将字符c隐式转为int型

小结

1)强制类型转换由程序员负责

* 转换可能产生截断

* 转换不区分类型的高低

* 转换不成功时,编译器给出错误信息

2)隐式类型转换由编译器自动完成

* 低类型向高类型的转换是安全的

* 高类型向低类型的转换是不安全的



版权声明:本文为piaoguo60原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。