网站seo设计,百度广告联盟官网入口,网站建设的电话销售,北京市建设工程信息网交易网站目录前言1. c的类型转换1.1 隐式类型转换1.2 强制类型转换1.3 类型转换的函数1.3.1 字符串转实型:atoi(),strtol()等1.3.2 实型转字符串:sprintf()1.3.3 网络字节序转换函数:ntohs(),htons()2. C的类型转换前言
什么是隐式类型转换#xff1f;什么时候会发生#xff1f;那些…目录前言1. c的类型转换1.1 隐式类型转换1.2 强制类型转换1.3 类型转换的函数1.3.1 字符串转实型:atoi(),strtol()等1.3.2 实型转字符串:sprintf()1.3.3 网络字节序转换函数:ntohs(),htons()2. C的类型转换前言什么是隐式类型转换什么时候会发生那些类型可以隐式转换强制类型转换什么情况必须用c与类型转换的4种关键字分别是什么有什么区别和联系各在什么场合下使用等。本文针对以上问题做简要小结。同时会涉及到以下内容关于printf输出格式与类型不一致请查看《%d输出float类型%f输出int类型》关于符号扩展有符号与无符号的转换问题请查看《符号位扩展空间不足—char和int举例》1. c的类型转换1.1 隐式类型转换隐式类型转换(自动类型转换)的发生一.借助“,因两边类型一致二.函数调用,传参或返回时(实际上也是借助”)三.能够隐式转换的类型:1.基本数据类型之间。如int和double(double-int:可能出现丢失精度的问题)int和char(int-char:可能出现空间不足,取低位,丢失高位数据1char-int:会符号位扩展1);2.通用指针。因所有类型的指针都可转化为通用指针通用指针也可转化为任意类型的指针注意输出格式与类型不一致,不会发生隐式类型转换如printf(“%f,%d\n”, 1, 1.0);2上代码#includestdio.hintmain(){// 隐式类型转换(借助,因两边类型一致): // double-int 丢失精度 // int-double float PI3.14159;int s1, r5;double s2;s1r * r * PI;// 隐式转换,double-int 丢失精度 s2r * r * PI;printf(s1%d, s2%f\n, s1, s2);int a5;double a1a/2;// 隐式类型转化,int—double double a22;// 隐式类型转化,int—double double a3(double)2;// 强制类型转换,int-double;一般采取此种写法 double a4(double)a/2;double a5a/2.0;printf(a1%f,a2%f,a3%f,a4%f,a5%f\n, a1, a2, a3, a4, a5);doublev5.0;int v15/2;int v25.0/2;// 隐式类型转换,double-int 丢失精度 int v32.5;// 隐式类型转换,double-int int v4(int)2.5;// 强制类型转换,double-int 丢失精度 printf(v1%d, v2%d, v3%d, v4%d\n, v1, v2, v3, v4);printf(--------------------------------------------------------------------------\n);// 隐式类型转换(借助,因两边类型一致): // 任何类型的指针-void* // void*-任何类型的指针 int c1;int *p_intc;void *pp_int;// 通用指针,可以隐式转换 void *p2(void*)p_int;// 一般采取强制类型转化的写法 //p_doublep_int;// 不可以隐式转换,编译过不了 printf(%d\n, *(int*)p);printf(----------------------------------------------------------------------------\n);return0;}1.2 强制类型转换强制类型转换的格式为:(type_name) expression在写法上,两边一般都是强制类型转化的写法(即便是可以隐式转换的类型,不写强转也没错,但不建议):1.直观上看两边类型一致易读易懂2.避免出错因为隐式类型转换只发生在如上所述的某些类型之间其余的类型必须用强制类型转换不然编译出错1.3 类型转换的函数1.3.1 字符串转实型:atoi(),strtol()等一般都是数字的字符串,如:“178666”-178666atoi为代表的:char* 字符串转换intint atoi(const char* nptr);char* 字符串转换longlong atol(const char* nptr);char* 字符串转换long longlong long atoll(const char *nptr);char* 字符串转换floatdouble atof(const char *nptr);strtol为代表的char* 字符串转换 unsigned long intunsigned long int strtoul(const char *nptr, char **endptr, int base);char* 字符串转换 unsigned long long intunsigned long long int strtoull(const char *nptr, char **endptr, int base);char* 字符串转换 long intlong int strtol(const char *nptr, char **endptr, int base);char* 字符串转换 long long intlong long int strtoll(const char *nptr, char **endptr, int base);char* 字符串转换 doubledouble strtod(const char *nptr, char **endptr);char* 字符串转换 floatfloat strtof(const char *nptr, char **endptr);char* 字符串转换 long doublelong double strtold(const char *nptr, char **endptr);1.3.2 实型转字符串:sprintf()1.3.3 网络字节序转换函数:ntohs(),htons()ntohs()#include netinet/in.h简述将一个无符号短整型数从网络字节顺序转换为主机字节顺序。16位。输入uint16_t netshort一个以网络字节顺序表达的16位数。返回值uint16_t ntohs返回一个16位以主机字节顺序表达的数。uint16_t ntohs(uint16_t netshort);htons()#include netinet/in.huint16_t htons(uint16_t hostshort);ntohl()简述将一个无符号长整形数从网络字节顺序转换为主机字节顺序。32位输入uint32_t netlong一个以主机字节顺序表达的32位数。返回值uint32_t ntohl返回一个32位以网络字节顺序表达的数。#include netinet/in.huint32_t ntohl(uint32_t netlong);htonl()#include netinet/in.huint32_t htonl(uint32_t hostlong);2. C的类型转换C向下兼容C故C的隐式类型转换强制类型转换和类型转换的一些函数在C里同样适应。C特有的4种与类型转换相关的关键字。用法小结:1.const_cast常量指针或常量引用去const属性2.static_cast(可以进行比特位上的转换)基本数据类型之间的转换3.dynamic_cast(基类必须有虚函数)安全的基类指针和派生类指针之间转换。4.reinterpret_cast(不可以进行比特位上的转换)指针类型的转换上代码const_cast:#include iostreamusing namespace std;// const_cast 去掉const属性 // const_castint*(num)常用因为函数调用时不能把一个const指针或应用直接赋给一个非const指针或引用必须要转换。 // const_cast的目的并不是为了让你去修改一个本身被定义为const的值因为这样做的后果是无法预期的。 // const_cast的目的是修改一些指针/引用的权限如果我们原本无法通过这些指针/引用修改某块内存的值现在你可以了。 intmain(){// const_cast的目的是修改一些指针/引用的权限 int a100;const int *pia;int *pi2const_castint *(pi);*pi2200;couta,*pi,*pi2endl;// res:200,200,200 printf(-----------------------------------------------------\n);// const int b1;// int b2const_castint(b);//编译通不过,不允许 // 去修改一个本身被定义为const的值因为这样做的后果是无法预期的。 const int c100;const int *pc;int *p2const_castint *(p);*p2200;coutc,*p,*p2endl;// res:100,200,200return0;}static_cast:// static_cast 静态类型转换。用于 //1. 基本数据类型转换。enum, struct, int, char, float等。 //2. static_cast不能进行无关类型如非基类和子类指针之间的转换,通用指针void*可以。 //3. 基类和子类之间转换其中子类指针转换成父类指针是安全的 // 但父类指针转换成子类指针是不安全的。(基类和子类之间的动态类型转换建议用dynamic_cast)intmain(){int n6;int *pnn;double dstatic_castdouble(n);// 基本类型转换 //double *d2static_castdouble*(n);// 无关类型指针转换编译错误 void *pstatic_castvoid*(pn);// 任意类型转换成void类型}dynamic_cast:// dynamic_cast // 有条件转换动态类型转换运行时类型安全检查(转换失败返回NULL) // 1. 安全的基类指针和派生类指针之间转换。 // 2. 必须要有虚函数。 class BaseClass { public: int m_iNum; virtual void foo(){}; // 基类必须有虚函数。保持多态特性才能使用dynamic_cast }; class DerivedClass: public BaseClass { public: char*m_szName[100]; void bar(){}; }; int main() { DerivedClass * pb new DerivedClass(); BaseClass *pd1 static_castBaseClass *(pb); // 子类-父类静态类型转换正确但不推荐 BaseClass *pd2 dynamic_castBaseClass *(pb); // 子类-父类动态类型转换正确 BaseClass* pb2 new BaseClass(); DerivedClass *pd21 static_castDerivedClass *(pb2); // 父类-子类静态类型转换危险访问子类m_szName成员越界 DerivedClass *pd22 dynamic_castDerivedClass *(pb2); // 父类-子类动态类型转换安全的。结果是NULL cout pd21 endl; // res:0x1e1aa0 cout pd22 endl; // res:0 // int a 1; // int *pa a; // double *b dynamic_castdouble*(pa); //int*-double*,编译错误 }reinterpret_cast:// reinterpret_cast // 1. 转换的类型必须是一个指针、引用、算术类型、函数指针或者成员指针。 // 2. 最普通的用途就是在函数指针类型之间进行转换。 // 3. 仅仅重新解释类型它可以把一个指针转换成一个整数也可以把一个整数转换成一个指针。 // 但不会进行比特位上的转换,如:不能int-double typedef void(*FuncPtr)(); int doSomething(){ return 0; }; int main() { FuncPtr funcPtrArray[10]; //funcPtrArray[0] doSomething; // 编译错误类型不匹配reinterpret_cast可以让编译器以你的方法去看待它们funcPtrArray funcPtrArray[0] reinterpret_castFuncPtr(doSomething); // 不同函数指针类型之间进行转换 printf(---------------------------------------------------------\n); int n 6; int *pn n; double *d2 reinterpret_castdouble*(n); // int*-double* void *p reinterpret_castvoid*(pn); // int*-void* printf(%d\n, *(int*)p); printf(----------------------------------------------------------\n); //double d reinterpret_castdouble(n); // int-double,编译错误 //char c 127; //int d reinterpret_castint(c); // char-int,编译错误 printf(%d\n, sizeof(int*)); // res:8 // 64bit故用long long long long int p2 reinterpret_castlong long(pn); int *p3 reinterpret_castint*(10); printf(llx:0x%llx\n, p2); printf(llx:0x%llx\n, p3); }《符号位扩展空间不足—char和int举例》 ↩︎ ↩︎《%d输出float类型%f输出int类型》 ↩︎