C++隐式转换
C++ 隐式和显式 初始化,类型转换

--1. 隐式和显式初始化1.1 C++隐式初始化int ival(1024);string hello("Hello world.")1.2 C++显式初始化int ival = 1024;string hello = "Hello world."2.隐式和显式类型转换.2.1C++隐式转换发生在四种情况下* 在混合类型的算术表达式中int ival = 3;double dval = 3.1415ival + dval; //ival 被提升为double 类型:3.0* 用一种类型的表达式赋值int *pi = NULL; // NULL(0)被转换成了int* 类型的空指针值* 用一个表达式传递给一个函数调用extern double sqrt(double);sqrt(2); //2被提升为double类型: 2.0* 从一个函数返回一个表达式double difference(int ival1, int ival2){return ival1 - ival2; //返回值被提升为double 类型.}2.2C++内建类型(char,int,short,double etc.)对像之间默认含有隐式转换2.3C++用户定义类对象之间可以含有隐式转换.void dosomething(A aObject);class A {public:A(int x = 0);}dosomething(20); // Ok 隐式转换2.4C++显式转换包含四种转换static_cast : 编译期的转化,不能转换掉exdivssion的const、volitale、或者__unaligned属性*所有内建类型对象之间的隐式转换都可用static_cast.*把空指针转换成目标类型的空指针用static_cast。
*把任何类型的表达式转换成void类型用static_cast。
c语言的自动类型转换(转)

c语⾔的⾃动类型转换(转)⼀、⾃动转换遵循以下规则:1. 若参与运算量的类型不同,则先转换成同⼀类型,然后进⾏运算。
2. 转换按数据长度增加的⽅向进⾏,以保证精度不降低。
如int型和long型运算时,先把int量转成long型后再进⾏运算。
若两种类型的字节数不同,转换成字节数⾼的类型若两种类型的字节数相同,且⼀种有符号,⼀种⽆符号,则转换成⽆符号类型1. 所有的浮点运算都是以双精度进⾏的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。
2. char型和short型参与运算时,必须先转换成int型。
3. 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。
如果右边量的数据类型长度左边长时,将丢失⼀部分数据,这样会降低精度,丢失的部分按四舍五⼊向前舍⼊。
⼆、隐式类型转换分三种,即算术转换、赋值转换和输出转换。
1.算术转换进⾏算术运算(加、减、乘、除、取余以及符号运算)时,不同类型数招必须转换成同⼀类型的数据才能运算,算术转换原则为:在进⾏运算时,以表达式中最长类型为主,将其他类型位据均转换成该类型,如:若运算数中有double型或float型,则其他类型数据均转换成double类型进⾏运算。
若运算数中最长的类型为long型.则其他类型数均转换成long型数。
若运算数中最长类型为int型,则char型也转换成int型进⾏运算。
算术转换是在运算过程中⾃动完成的。
2.赋值转换进⾏赋值操作时,赋值运算符右边的数据类型必须转换成赋值号左边的类型,若右边的数据类型的长度⼤于左边,则要进⾏截断或舍⼊操作。
下⾯⽤⼀实例说明:char ch;int i,result;float f;double d;result=ch/i+(f*d-i);⾸先计算 ch/i,ch → int型,ch/i → int型。
接着计算 f*d-i,由于最长型为double型,故f→double型,i→double型,f*d-i→double型。
c语言枚举类型之间转换

c语言枚举类型之间转换C语言枚举类型之间的转换引言:在C语言中,枚举类型是一种用于定义一组具有相同属性的常量的数据类型。
枚举类型可以为程序添加可读性,并且能够提高代码的可维护性和可扩展性。
本文将探讨在C语言中枚举类型之间的转换,包括枚举常量之间的转换、枚举类型与整型之间的转换以及枚举类型与字符串之间的转换。
一、枚举常量之间的转换在C语言中,枚举常量是枚举类型的取值,它们之间可以相互转换。
枚举常量之间的转换可以使用赋值运算符进行,如下所示:```cenum Color { RED, GREEN, BLUE };enum Color myColor;myColor = RED;```上述代码中,我们定义了一个名为`Color`的枚举类型,其中包含三个枚举常量`RED`、`GREEN`和`BLUE`。
然后,我们声明了一个名为`myColor`的枚举类型变量,并将其赋值为`RED`。
这样,我们就实现了枚举常量之间的转换。
二、枚举类型与整型之间的转换在C语言中,枚举类型实际上是一种特殊的整型。
因此,枚举类型与整型之间可以相互转换。
枚举类型可以隐式地转换为整型,而整型可以通过强制类型转换转换为枚举类型。
1. 枚举类型隐式转换为整型当将枚举类型赋值给整型变量时,会发生隐式转换。
例如:```cenum Weekday { MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY };enum Weekday today = MONDAY;int day = today;```上述代码中,我们定义了一个名为`Weekday`的枚举类型,其中包含七个枚举常量,分别代表一周的七天。
然后,我们声明了一个名为`today`的枚举类型变量,并将其赋值为`MONDAY`。
接着,我们声明了一个名为`day`的整型变量,并将其赋值为`today`。
由于枚举类型隐式转换为整型,所以这种赋值是合法的。
C++对象指针转换

在C++中存在两种转换:隐式转换和显式转换(强制转换)。
一、隐式类型转换C++定义了一组内置类型对象之间的标准转换,在必要时它们被编译器隐式地应用到对象上。
隐式类型转换发生在下列这些典型的情况下;1、在混合类型的算术表达式中。
在这种情况下,最宽的数据类型成为目标转换类型。
这也被称为算术转换arithmetic conversion 例如:int ival = 3;double dval = 3.14159;// ival 被提升为double 类型: 3.0 (是一种保值转换)ival + dval;2、用一种类型的表达式赋值给另一种类型的对象。
在这种情况下,目标转换类型是被赋值对象的类型。
例如,在下面第一个赋值中文字常量0 的类型是int 它被转换成int*型的指针表示空地址在第二个赋值中double 型的值被截取成int 型的值。
// 0 被转换成int*类型的空指针值int *pi = 0;// dval 被截取为int值3 (这不是保值转换),一般情况下编译器会给出warning.ival = dval;3、把一个表达式传递给一个函数调用,表达式的类型与形式参数的类型不相同。
在这种情况下,目标转换类型是形式参数的类型。
例如:extern double sqrt( double );// 2 被提升为double 类型: 2.0cout4、从一个函数返回一个表达式,表达式的类型与返回类型不相同。
在这种情况下,目标转换类型是函数的返回类型。
例如:double difference( int ival1, int ival2 ){// 返回值被提升为double 类型return ival1 - ival2;}二、显示转换(强制转换)(一)、旧式强制类型转换:由static_cast,cons_cast 或reinterpret_cast 强制转换符号语法,有时被称为新式强制转换符号,它是由标准C++引入的。
c语言的自动类型转换

b.若两种类型的字节数相同,且一种有符号,一种无符号,则转换成无符号类型
3) 所有的浮点运算都是以双精度进行的,即使仅含float单精度量运算的表达式,也要先转换成double型,再作运算。
4) char型和short型参与运算时,必须先转换成int型。
5) 在赋值运算中,赋值号两边量的数据类型不同时,赋值号右边量的类型将转换为左边量的类型。如果右边量的数据类型长度左边长时,将丢失一部分数据,这样会降低精度,丢失的部分按四舍五入向前舍入。
3. 在任何涉及两种数据类型的操作中,它们之间等级较低的类型会被转换成等级较高的类型。
4. 在赋值语句中,= 右边的值在赋予 = 左边的变量之前,首先要将右边的值的数据类型转换成左边变量的类型。也就是说,左边变量是什么数据类型,右边的值就要转换成什么数据类型的值。这个过程可能导致右边的值的类型升级,也可能导致其类型降级(demotion)。所谓“降级”,是指等级较高的类型被转换成等级较低的类型。
(2)若运算数中最长的类型为long型.则其他类型数均转换成long型数。
(3)若运算数中最长类型为int型,则char型也转换成int型进行运算。算术转换是在运算过程中自动完成的。
2.赋值转换
进行赋值操作时,赋值运算符右边的数据类型必须转换成赋值号左边的类型,若右边的数据类型的长度大于左边,则要进行截断或舍入操作。
2. 按照从高到低的顺序给各种数据类型分等级,依次为:long double, double, float, unsigned long long, long long, unsigned long, long, unsigned int 和 int。这里有一个小小的例外,如果 long 和 int 大小相同,则 unsigned int 的等级应位于 long 之上。char 和 short 并没有出现于这个等级列表,是因为它们应该已经被升级成了 int 或者 unsigned int。
算数转换c语言

算数转换c语言
在C语言中,算术转换主要是指数据类型的转换,尤其是当你正在进行算术运算时。
当两个不同的数据类型进行算术运算时,C语言会尝试将它们转换为同一种数据类型,以便进行运算。
这个过程被称为"算术转换"。
C语言中的算术转换遵循一定的规则,包括整数提升和浮点数提升。
具体来说,当一个操作数的类型小于另一个操作数的类型时,较小的操作数会被转换为较大的操作数的类型。
下面是一个简单的示例,展示了如何在C语言中进行算术转换:
c
#include <stdio.h>
int main() {
int a = 5;
float b = 3.14;
float result;
// 执行算术转换的示例
result = a + b; // int 和 float 相加,将 int 转换为 float
printf("Result: %f\n", result); // 输出: 8.140000
return 0;
}
在这个例子中,我们有一个整数 a 和一个浮点数 b。
当我们执行 a + b 运算时,整数a 被自动转换为浮点数,以保持与浮点数 b 的类型一致。
结果是一个浮点数,并被存储在变量 result 中。
需要注意的是,在进行算术运算时,如果操作数的类型不一致,C语言会自动进行类型转换。
这通常被称为"隐式转换"或"自动转换"。
在某些情况下,你可能需要显式地进行类型转换,以确保结果是你所期望的。
C用法随笔

1、强制类型转换当操作数的类型不同,而且不属于基本数据类型时,经常需要强制类型转换,将操作数转化为所需要的类型。
强制类型转换具有两种形式,称为显式强制转换和隐式强制类型转换。
1、显式强制类型转换显式强制类型转换需要使用强制类型转换运算符,格式如下:type(<expression>)或(type)<expression>其中,type为类型描述符,如int,float等。
<expression>为表达式。
经强制类型转换运算符运算后,返回一个具有type类型的数值,这种强制类型转换操作并不改变操作数本身,运算后操作数本身未改变,例如:int nVar=0xab65;char cChar=char (nVar);上述强制类型转换的结果是将整型值0xab65的高端两个字节删掉,将低端两个字节的内容作为char型数值赋值给变量cChar,而经过类型转换后nVar的值并未改变。
2、隐式强制类型转换隐式类型转换发生在赋值表达式和有返回值的函数调用表达式中。
在赋值表达式中,如果赋值符左右两侧的操作数类型不同,则将赋值符右边操作数强制转换为赋值符左侧的类型数值后,赋值给赋值符左侧的变量。
在函数调用时,如果return后面表达式的类型与函数返回值类型不同,则在返回值时将return后面表达式的数值强制转换为函数返回值类型后,再将值返回,如:int nVar;double dVar=3.88;nVar=dVar;//执行本句后,nVar的值为3,而dVar的值仍是3.882、宏定义的一些使用技巧总结大全(一)我在写代码的时候喜欢使用宏,不仅使代码看起来整洁,而且用好了还能极大的减轻编码的工作量,但是如果使用不当的话,出了问题查找起来就就非常的难了,下面的总结大部分是从网上看到的,也有一些是我自己在工作中总结出来的。
宏使用中的常见的基础问题1. 防止一个头文件被重复包含#ifndef BODYDEF_H#define BODYDEF_H//头文件内容#endif2. 重新定义一些类型,防止由于各种平台和编译器的不同,而产生的类型字节数差异,方便移植。
CC++数据类型的转换

C/C++数据类型的转换之终极无惑数据类型在编程中经常遇到,虽然可能存在风险,但我们却乐此不疲的进行数据类型的转换。
1.隐式数据类型转换数据类型转换,到底做了些什么事情呢?实际上,数据类型转换的工作相当于一条函数调用,若有一个函数撰文负责从double转换到int(假设函数是dtoi),则下面的转换语句:double d=4.48;int i=d;//报告警告等价于i=dtoi(d)。
函数dtoi的原型应该是:int dtoi(double)或者是int dtoi(const double&)。
有些类型的数据转换时绝对安全的,所以可以自动进行,编译器不会给出任何警告,如由int 型转换成double型。
另一些转换会丢失数据,编译器只会给出警告,并不算一个语法错误,如上面的例子。
各种基本数据类型(不包括void)之间的转换都属于以上两种情况。
以上两种不显示指明数据类型的转换就是隐式数据类型转换。
隐式数据类型转换无处不在,主要出现在一下集中情况。
(1)算术运算式中,低类型能够转换为高类型。
(2)赋值表达式中,右边表达式的值自动隐式转换为左边变量的类型,并赋值给他。
(3)函数调用中参数传递时,系统隐式地将实参转换为形参的类型后,赋给形参。
(4)函数有返回值时,系统将隐式地将返回表达式类型转换为返回值类型,赋值给调用函数。
编程原则,请尽量不要使用隐式类型转换,即使是隐式的数据类型转换是安全的,因为隐式类型数据转换降低了程序的可读性。
2.显示数据类型转换显示数据类型转换是显示指明需要转换的类型,首先考察如下程序。
#include<iostream>usingnamespace std;int main(int argc,char* argv[]){short arr[]={65,66,67,0};wchar_t *s;s=arr;wcout<<s<<endl;getchar();}由于short int和wchar_t是不同的数据类型,直接把arr代表的地址赋给s会导致一个编译错误:error C2440:“=”:无法从“short[4]”转换为“wchar_t”。
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
首先回顾一下C++类型转换:C++类型转换分为:隐式类型转换和显式类型转换1又称为“标准转换”,包括以下几种情况:1) 算术转换(Arithmetic conversion) : 在混合类型的算术表达式中, 最宽的数据类型成为目标转换类型。
int ival = 3;double dval = 3.14159;ival + dval;//ival被提升为double类型2)一种类型表达式赋值给另一种类型的对象:目标类型是被赋值对象的类型int *pi = 0; // 0被转化为int *类型ival = dval; // double->int例外:void指针赋值给其他指定类型指针时,不存在标准转换,编译出错3)将一个表达式作为实参传递给函数调用,此时形参和实参类型不一致:目标转换类型为形参的类型extern double sqrt(double);cout << "The square root of 2 is " << sqrt(2) << endl;//2被提升为double类型:2.04)从一个函数返回一个表达式,表达式类型与返回类型不一致:目标转换类型为函数的返回类型double difference(int ival1, int ival2){return ival1 - ival2;//返回值被提升为double类型}第2部分. 显式类型转换被称为“强制类型转换”(cast)C 风格:(type-id)C++风格:static_cast、dynamic_cast、reinterpret_cast、和const_cast..public:virtual int salary();};class Manager : public Employee{public:int salary();};class Programmer : public Employee{public:int salary();};我们公司在开发的时候建立有如下类:class MyCompany{public:void payroll(Employee *pe);//};void MyCompany::payroll(Employee *pe){//do something}但是开发到后期,我们希望能增加一个bonus()的成员函数到W$公司提供的类层次中。
假设我们知道源代码的情况下,很简单,增加虚函数://Emplyee.hclass Employee{public:virtual int salary();virtual int bonus();};class Manager : public Employee{public:int salary();class Programmer : public Employee{public:int salary();int bonus();};//Emplyee.cppint Programmer::bonus(){//}payroll()通过多态来调用bonus()class MyCompany{public:void payroll(Employee *pe);//};void MyCompany::payroll(Employee *pe){//do something//pe->bonus();}但是现在情况是,我们并不能修改源代码,怎么办?dynamic_cast华丽登场了!在Employee.h中增加bonus()声明,在另一个地方定义此函数,修改调用函数payroll().重新编译,ok //Emplyee.hclass Employee{public:virtual int salary();};class Manager : public Employee{public:int salary();};class Programmer : public Employee{public:int salary();int bonus();//直接在这里扩展};//somewhere.cppint Programmer::bonus(){//define}class MyCompany{public:void payroll(Employee *pe);//};void MyCompany::payroll(Employee *pe){Programmer *pm = dynamic_cast<Programmer *>(pe);//如果pe实际指向一个Programmer对象,dynamic_cast成功,并且开始指向Programmer对象起始处if(pm){//call Programmer::bonus()}//如果pe不是实际指向Programmer对象,dynamic_cast失败,并且pm = 0else{//use Employee member functions}}dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。
在类层次间进行上行转换时,dynamic_cast和static_cast的效果是一样的;在进行下行转换时,dynamic_ca 检查的功能,比static_cast更安全。
class Base{public:int m_iNum;virtual void foo();};class Derived:public Base{public:char*m_szName[100];};void func(Base *pb){Derived *pd1 = static_cast<Derived *>(pb);Derived *pd2 = dynamic_cast<Derived *>(pb);}在上面的代码段中,如果pb实际指向一个Derived类型的对象,pd1和pd2是一样的,并且对这两个指针执行Derived类型的任何全的;如果pb实际指向的是一个Base类型的对象,那么pd1将是一个指向该对象的指针,对它进行Derived类型的操安全的(如访问m_szName),而pd2将是一个空指针(即0,因为dynamic_cast失败)。
另外要注意:Base要有虚函数,否则会编译出错;static_cast则没有这个限制。
这是由于运行时类型检查需要型信息,而这个信息存储在类的虚函数表(关于虚函数表的概念,详细可见<Inside c++ object model>)中,虚函数的类才有虚函数表,没有定义虚函数的类是没有虚函数表的。
另外,dynamic_cast还支持交叉转换(cross cast)。
如下代码所示。
class Base{public:int m_iNum;virtual void f(){}};class Derived1 : public Base};class Derived2 : public Base{};void foo(){derived1 *pd1 = new Drived1;pd1->m_iNum = 100;Derived2 *pd2 = static_cast<Derived2 *>(pd1); //compile errorDerived2 *pd2 = dynamic_cast<Derived2 *>(pd1); //pd2 is NULLdelete pd1;}在函数foo中,使用static_cast进行转换是不被允许的,将在编译时出错;而使用dynamic_cast的转换则结果是空指针。
reinpreter_cast用法:reinpreter_cast<type-id> (expression)说明:type-id必须是一个指针、引用、算术类型、函数指针或者成员指针。
它可以把一个指针转换成一个整数一个整数转换成一个指针(先把一个指针转换成一个整数,在把该整数转换成原类型的指针,还可以得到原先的该运算符的用法比较多。
const_cast用法:const_cast<type_id> (expression)说明:该运算符用来修改类型的const或volatile属性。
除了const 或volatile修饰之外, type_id和exp以下是对C++中不能重载为友元函数的四个运算符进行了详细的分析介绍,需要的朋友可以过来参考下C++规定有四个运算符=, ->, [], ()不可以是全局域中的重载(即不能重载为友员函数),这是为什么呢?现在先说说赋值运算符“=”的重载C++规定赋值运算符“=”只能重载为类的非静态成员函数,而不可以重载为类的友元函数。
不能重载为类的静态成员应该比较容易理解,因为静态成员函数是属于整个类的,不是属于某个对象的,它只能去操作类静态数据成员。
而赋值运算符“=”是基于对象操作的。
那么为什么赋值运算符不可以重载为类的友元函数?像同样都是双目运算符的+为什么它就可以呢?在讨论这问题之前,先看一测试的程序:1.2.#include <iostream>ing namespace std;4.5.class A6.{7.private:8. int x;9.public:10. A(){x=99;}11. A(int xx)12. {13. cout<<"Call A(int xx)"<<endl;14. x = xx;15. }16.};17.int main()18.{19. A a;20. a = 7;21.}复制代码程序执行结果为:Call A(int xx)说明执行a = 7这程序语句时,程序去调用类A中的带参构造函数。
在类A中加入一赋值运算重载成员函数,如下:1.2.#include <iostream>ing namespace std;4.5.class A6.{7.private:8. int x;9.public:10. A(){x=99;}11. A(int xx)12. {13. cout<<"Call A(int xx)"<<endl;14. x = xx;15. }16. A operator=(int xx) //重载赋值运算符运算17. {18. cout<<"Call A operator=(int xx)"<<endl;19. x = xx;20. return *this;21. }22.};23.24.int main()25.{26. A a;27. a = 7;28.}复制代码程序运行结果:Call A operator=(int xx)说明在类A中已经有相应赋值运算符重载函数的时候,执行赋值语句a = 7;程序会去调用类A中相应的赋值运算符重载函数,而不会像上面原来那样去调用有参构造函数。