C++ 数据类型转换

在C++中,将数据由当前类型变化为其他类型的操作。数据类型转换分为两类,分别是自动数据类型转换和强制数据类型转换。自动转换时程序根据运算要求进行的转换,不需要人工干预。强制数据类型转换是根据程序需要,由编写程序人员人为改变数据类型的方式。本文主要介绍C++ 数据类型转换(自动转换、强制转换)。

1、隐式类型转换(自动转换)

隐式类型转换是编译器自动进行的类型转换。它通常发生在不同类型的数据进行运算时,编译器会自动将较小的数据类型转换为较大的数据类型以避免数据丢失。在多种数据类型混合计算的时候,不需要程序员控制类型,系统会自动进行类型转换

转换,隐式转换的规则是:存储长度较短的转换成存储长度较长的,且不丢失数据。

bool - > char - > short int - > int - > unsigned int - > long - > unsigned - > long long - > float - > double - > long double

例如,

#include <iostream>
using namespace std;
int main() 
{ 
    int x = 10;    
    char y = 'a';  
    // 'a' is 97 
    x = x + y; 
    float z = x + 1.0; 
    printf("x = %d, z = %f", x, z); 
    return 0; 
} 

赋值转换:如果赋值运算符两侧数据类型不一致,则在赋值时会发生赋值类型转换。包括函数返回值、函数传参等。

例如,

#include <iostream>
using namespace std;
int main()
{
    int a1 = 3.5;
    //此时a的值是3
    float f1 = 4;
    //此时f的值是4.0
    int a, b;
    double x = 1.54;
    char ch;
    a = x;
    x = 12;
    b = 'a';
    ch = 356;
    printf("a=%d\nx=%f\nb=%d\nch=\'%c\'\n",a,x,b,ch);
    return 0;
}

2、强制类型转换(显式转换)

显式类型转换是程序员主动进行的类型转换,也叫强制类型转换。它通过使用强制转换运算符来实现。强制类型转换是通过类型转换运算来实现的。其一般形式为:(类型说明符)(表达式)其功能是把表达式的运算结果强制转换成类型说明符所表示的类型。自动转换是在源类型和目标类型兼容以及目标类型广于源类型时发生一个类型到另一类的转换。

1)C 风格强制转换

使用括号 () 来进行类型转换。如 (float)a a转换为浮点型,(int)(x+y) 把x+y的结果转换为整型。

例如,

#include <iostream>
using namespace std;
int main() 
{ 
    double x = 1.2; 
    int sum = (int)x + 1; 
    printf("sum = %d", sum); 
    return 0; 
} 

2)C++ 强制转换(static_cast

static_cast 是 C++ 提供的类型转换操作符,适用于常见的类型转换。C++有四大强制类型转换符:reinterpret_cast, const_cast, static_cast, dynamic_cast

reinterpret_cast:最普通的强制类型转换符,与用圆括号实现类型转换一样。reinterpret_cast 用于进行低级别的指针或引用转换。可以在任何两个指针类型之间进行转换,甚至可以在不相关的类型之间转换。然而,这通常是危险的,因为它不会进行任何类型检查。

const_castconst_cast 用于添加或移除对象的 const 限定符。它不能改变对象的实际类型,只能修改 constvolatile 限定符。

static_cast:编译器可以隐式转换的任何类型都可以由static_cast完成。仅当类型之间可隐式转换时(除类层次间的下行转换以外)。static_cast才是合法的。主要是可以提高隐式转换的安全性。另外,C++基本类型(int,char等)的指针之间不能含有隐式转换,必须要用显示转换,所以如果static_cast里有基本类型的指针转换则是错误的。static_cast 是推荐使用的方式,因为它提供了更好的类型安全,编译器会检查类型转换是否合法。

dynamic_cast:运算符将一个指向基类的指针转换成指向派生类的指针;如果失败,返回空指针。dynamic_cast 主要用于多态类型转换,通常用于转换基类指针或引用到派生类指针或引用。它是运行时类型转换,用于处理类层次结构中的对象转换。

使用形式为:

cast-name<type>(expression)

例如,

#include<iostream>
using namespace std;
class B{
public:
    B():b(1){}
    virtual void foo(){};
    int b;
};
class D:public B{
public:
    D():d(2){}
    int d;
};
void func(B *pb){
    D *pd1 = static_cast<D *>(pb);//语句1
    cout<<pd1->b<<endl;
    cout<<pd1->d<<endl;
    D *pd2 = dynamic_cast<D *>(pb);//语句2
    cout<<pd2->b<<endl;
    cout<<pd2->d<<endl;
}
int main(){
    int* ip;
    char* p1 = reinterpret_cast<char*>(ip);
    const char* pc_str;
    //新的表达式pc则删除const属性
    char* p2 = const_cast<char*>(pc_str);
    B* pb = new B;
    func(pb);
    return 0;
}

3、各种类型转换

 C++ 中,数据类型转换可以通过多种方式进行,包括隐式转换(编译器自动进行)、显式转换(程序员明确要求)和 C 风格的强制转换。

1)整数与字符数组、字符串的转换

#include<iostream>
using namespace std;
#include <string>

int main() {
    // 1--> int to char[]
    int tmp1 = 100;
    char ch1[15];
    sprintf(ch1, "%d", tmp1);
    std::cout << "int to char[]: " << ch1 << std::endl;

    // 2--> int to string
    int tmp2 = 111;
    char ch2[15];
    sprintf(ch2, "%d", tmp2);
    std::string str2(ch2);
    std::cout << "int to string: " << str2 << std::endl;

    // 3--> char[] to string  
    char arr4[] = "this is a sample";
    std::string str4(arr4);
    std::cout << "char[] to string: " << str4 << std::endl;

    return 0;
}

2)整数与枚举类型的转换

#include<iostream>
using namespace std;

enum enum3 {
    A,
    B
};

int main() {
    // 3--> int to enum
    int tmp3 = 222;
    enum3 val3 = static_cast<enum3>(tmp3);
    std::cout << "int to enum: " << val3 << std::endl;

    return 0;
}

3)字符与整数的转换

#include<iostream>
using namespace std;

int main() {
    // 5--> char to int
    char ch5 = '8';
    int val5 = ch5 - '0';  // Convert char '8' to int 8
    std::cout << "char to int: " << val5 << std::endl;

    // 6--> char[] to int
    char arr6[] = "12345";
    int tmp6;
    sscanf(arr6, "%d", &tmp6);
    std::cout << "char[] to int: " << tmp6 << std::endl;

    // 7--> char* to int
    char* pch7 = "444";
    int tmp7 = atoi(pch7);
    std::cout << "char* to int: " << tmp7 << std::endl;

    return 0;
}

4)浮点与字符数组的转换

#include<iostream>
using namespace std;
#include <cstdlib>

int main() {
    // 8--> char* to float
    char* pch8 = "55.5";
    float tmp8 = atof(pch8);
    std::cout << "char* to float: " << tmp8 << std::endl;

    // 9--> char* to double
    char* pch9 = "66.666";
    double tmp9 = atof(pch9);
    std::cout << "char* to double: " << tmp9 << std::endl;

    // 10--> float to char[]
    float tmp10 = 11.11;
    char ch10[20];
    sprintf(ch10, "%f", tmp10);
    std::cout << "float to char[]: " << ch10 << std::endl;

    return 0;
}

5)字符串与字符数组之间的转换

#include<iostream>
using namespace std;
#include <string>

int main() {
    // 13--> char* to string
    char* pch13 = "hello, world";
    std::string str13(pch13);
    std::cout << "char* to string: " << str13 << std::endl;

    // 14--> string to char[]
    std::string str14 = "dog, cat";
    char arr14[256];
    strncpy(arr14, str14.c_str(), sizeof(arr14));
    arr14[sizeof(arr14) - 1] = 0;
    std::cout << "string to char[]: " << arr14 << std::endl;

    return 0;
}

6)浮点与整数之间的转换

#include<iostream>
using namespace std;

int main() {
    // 16--> float to int
    float ftmp16 = 99.99;
    int tmp16 = static_cast<int>(ftmp16);  
    std::cout << "float to int: " << tmp16 << std::endl;

    // 17--> vector<float> to float*
    std::vector<float> vec;
    for (int i = 0; i < 10; i++)
        vec.push_back(i * 1.5);
    float* p = &vec[0];
    for (int i = 0; i < 10; i++)
        std::cout << "vector<float> to float*: " << p[i] << std::endl;

    // 18--> int[] to vector<int>
    int x[5] = {1, 2, 3, 4, 5};
    std::vector<int> v(x, x + sizeof(x) / sizeof(x[0]));
    for (int i = 0; i < v.size(); i++)
        std::cout << "int[] to vector<int>: " << v[i] << std::endl;

    return 0;
}

相关文档:C 类型转换及常用类型转换函数

推荐阅读
cjavapy编程之路首页