1、在数值计算过程中一些常用的数值转换规则:
(1)如果两个操作数有一个操作数的类型为long double,则另一个操作数无论何种类型,均被转换为long double类型。
(2)如果两个操作数有一个操作数的类型为double,而另一个操作数不是long double类型,则另一个操作数被转换为double类型。
(3)如果两个操作数的类型都不是double(包括long double)类型,而一个操作数的类型是float,则另一个操作数被转换为float类型。
(4)如果两个操作数都是整数,编译器将所有小于int类型的操作数提升为int类型。
2、显式转换的形式:cast-name<type>(expression)。
type是转换的目标类型而expression是要转换的值。如果type是引用类型,则结果是左值。cast-name是static_cast,dynamic_cast,const_cast和reinterpret_cast中的一种。
3、静态转换:static_cast。
任何具有明确定义的类型转换,只要不包含底层const,都可以使用static_cast。
4、动态转换也是C++语言提供的一种强制类型转换方式。与静态转换不同的是在转换前它能够进行类型检查。动态转换通常用于一个类对象指针转换为另一个类对象指针。如果源指针类型与目标指针类型不兼容,则转换的结果为NULL。程序中可以通过检测结果是否为NULL来判断强制类型是否成功。
在C++中使用dynamic_cast关键字进行动态转换。动态转换只能对void *(无类型指针)类型或者类对象指针进行转换,并且类中必须包含有虚方法,而不能对普通的数据类型进行转换。
5、常量转换,用于将const对象转换为非const对象。
如下,可以转换为同类型的非常量指针:
#include<iostream> using namespace std; int main() { const int max_a = 100; // long *plen = (long*)&max_a; // cout << *plen << endl; //在C中可以进行 //在C++中: int * plen = const_cast<int *>(&max_a); // long *plen = const_cast(long *)(&max_a); //对于不同类型的long型则编译不通过 cout << *plen << endl; return 0; }
但是如下程序,虽然转换成功,但是改过值后依然输出的是常量的值。
#include<iostream> using namespace std; int main() { const int max_a = 100; // long *plen = (long*)&max_a; // cout << *plen << endl; //在C中可以进行 //在C++中: int * plen = const_cast<int *>(&max_a); // long *plen = const_cast(long *)(&max_a); cout << *plen << endl; return 0; }
因为max_a是常量,原则上是不能改变常量值的,因此编译器在编译时遇到常量,将其直接翻译为一个常数,而不进行寻址操作。
6、重解释转换。
重解释转换能将任何指针类型转换为其他的指针类型,这种转换方式是一种不安全的转换方式。在程序中应该尽量少用。
#include<iostream> using namespace std; int main() { char *psztext = "mrkj"; unsigned int *paddr = reinterpret_cast<unsigned int *>(psztext); char * pszcaption = reinterpret_cast<char*>(paddr); return 0; }
在使用重解释转换时,通常转换后的指针是不能够按照它的数据类型使用的。在程序中使用reinterpret_cast是危险的、不明智的,因此建议开发人员少使用,谨慎使用。
7、数值与字符串转换
函数都在<stdlib.h>头文件里。
(1)字符串转换为整数 : int atoi(const char * string)
string:表示待转换后的字符串。
返回值:如果函数执行成功,返回值为字符串转换后的整数,如果参数string不能转换为整数,返回值为0.如果参数string转换后的数值溢出,返回值未知。
#include<iostream> #include<stdlib.h> using namespace std; int main() { char *pszheight = "100"; char *width ="200"; int nheight = atoi(pszheight); int nwidth = atoi(width); int area = nheight * nwidth ; cout << area << endl; return 0; }
(2)字符串转换为实数 double atof(const char * string);
string:待转换后的字符串
返回值:如果函数执行成功,返回值为字符串转换后的实数,如果参数布恩那个转换为实数,返回值为0.0,溢出同样为未知。
(3)整数转换为字符串 char *itoa(int value,char *str,int radix)
value:表示待转换的整数
str:表示一个字符指针,用于存储函数转换后的字符串
radix:表示基数,范围2...35,通常为10,即采用10进制转换。
返回值:函数返回一个指向str参数的字符指针。
#include<iostream> #include<stdlib.h> using namespace std; int main() { int ndays = 365; char psztext[128] = {0}; itoa(ndays,psztext,10); cout << psztext << endl; return 0; }
不知道为什么我的codeblocks有G++还是不支持,在VC 6.0中可以正确运行。
(4)实数转换为字符串 char * fcvt(double value,int count ,int *dec,int *sign);
value:表示待转换的实数
count:表示小数点后的位数,即精度。
dec:是一个整形指针,表示数字的符号,0为正数,1为负数。
返回值:如果函数执行成功,返回值是一个字符指针,否则为NULL。
#include<iostream> #include<stdlib.h> using namespace std; int main() { double dbpi = 3141.5926; int ndec; int nsign; char * psztext=fcvt(dbpi,2,&ndec,&nsign); cout << "字符串为:" << psztext << endl; cout << "小数点后的位数为2" << endl; cout << "小数点的位置" << ndec << endl; cout << "数字的符号:" << nsign << endl; return 0; }