C++ primer 查漏补缺七:类型转换

在C++语言中,某些类型之间有关联。如果两种类型有关联,那么当程序需要其中一
种类型的运算对象时,可以用另一种关联类型的对象或值来替代。换句话说,如果两种类
型可以相互转换(conversion),那么它们就是关联的。

例子:

 int ival = 3.125+6;

因为3.125是double类型,所以先将6转化为double类型,执行浮点型运算得到 9.125
再将9.125转化为int型赋值给 ival

隐式类型转换

C++不会直接将两个不同类型的值相加,而是先根据类型转换规则设法将运算对象的类型统一后再求值。
上述的类型转换是自动执行的,无须程序员的介入,有时甚至不需要程序员了解。因此,它们被称作隐式转换(implicit conversion)。

算术类型之间的隐式转换被设计得尽可能避免损失精度。很多时候,如果表达式中既有整数类型的运算对象也有浮点数类型的运算对象,整型会转换成浮点型。

何时发生隐式类型转换 ?
在下面这些情况下,编译器会自动地转换运算对象的类型:

  • 在大多数表达式中,比int类型小的整型值首先提升为较大的整数类型。
  • 在条件中,非布尔值转换成布尔类型。
  • 初始化过程中,初始值转换成变量的类型
  • 在赋值语句中,右侧运算对象转换成左侧运算对象的类型。
  • 如果算术运算或关系运算的运算对象有多种类型,需要转换成同一种类型。
  • 如第6章将要介绍的,函数调用时也会发生类型转换。
    在这里插入图片描述

数组和指针

通常情况下 数组名字 约等于 指向数组首元素的指针

string nums[] ={ "one" ,"two" , "three"};
string *p = &nums[0];
string *p2 = &nums;

在这里 *p*p2 是等价的

auto 和 decltype的区别
假设

int ia[]={0,1,2,3};
auto ia2(ia);//1 
auto ia2(&ia[0]);//2

ia2的类型是 int*,编译器执行代码1 实际上执行的是代码2
而decltype(ia) 返回的是有4个元素的数组

对数组执行sizeof运算得到整个数组所占空间的大小,等价于对数组中所有的元素各执行一次sizeof运算并将所得结果求和。注意,sizeof运算不会把数组转换成指针来处理。

指针的转换

  • 常量整数值0或者字面值nullptr能转换成任意指针类型
  • 指向任意非常量的指针能转换成void*:
  • 指向任意对象的指针能转换成const void*

显示转换

cast-name(expression);

type是转换的目标,expression是要转换的值。如果type是引用类型,则结果是左值
cast-name 的取值范围有

static_cast

任何具有明确定义的类型转换,只要不包含底层const,都可以使用。常见用法:

  1. 把一个较大的算术类型赋值给较小的类型
int i=635,j=544;
double slope = static_cast<double>(j)/i;

当需要把一个较大的算术类型赋值给较小的类型时,static_cast非常有用。此时,强制类型转换告诉程序的读者和编译器:我们知道并且不在乎潜在的精度损失。一般来说,如果编译器发现一个较大的算术类型试图赋值给较小的类型,就会给出警告信息:但是当我们执行了显式的类型转换后,警告信息就会被关闭了。

  1. 指针
double d;
void* p =&d;//正确:任何非常量对象的地址都可以存入 void*
double *dp = static_cast<double*>(p);

当我们把指针存放在void*中,并且使用 static_cast 将其强制转换回原来的类型时,应该确保指针的值保持不变。也就是说,强制转换的结果将与原始的地址值相等,因此我们必须确保转换后所得的类型就是指针所指的类型。类型一旦不符,将产生未定义的后果。

补充说明:
顶层const:表示指针本身是一个常量
底层const:表示指针所指向的对象是一个常量

int i=0;
int *const pl =&i;// 顶层const  不能改变pl的值
const int ci =42; // 顶层const  不能改变ci的值
const int *p2 = &ci ; //允许改变p2的值,底层const

*const 常量指针
const * 指向常量

const_cast

将常量对象转换成非常量对象,去掉const的性质

const char *pc;
char *p = const_cast<char*>(cp); //正确
static_cast<char*>(cp);//错误 static_cast 不能转换掉const的性质
static_cast<string>(cp);//正确 字符串字面值剋转化为string类型

reinterpret_cast

重新解释转换(reinterpret_cast)

#include <iostream>
using namespace std;

int main()
{
	// 16进制表示
	int num = 0x00636261;
	// 用int类型指针指向num 
	int* p_int = &num;
	// 将int类型的指针转换为char类型的指针 	
	char* p_char = reinterpret_cast<char *>(p_int);
	
	// 输出结果 
	cout<<"p_int的值:" << p_int <<endl;
	cout<<"p_char的值: "<< static_cast<void *>(p_char)<<endl;// 为了输出p_char的值而进行类型转换(不然会输出其指向的字符串) 
	cout<<"p_int指向的内容: " << hex  <<*p_int<<endl;
	cout<<"p_char指向的内容: "<< p_char <<endl;
	
	return 0;
}

在这里插入图片描述

p_int 和p_char 指向同一片内存,即num 所在的地方。
但是解引用之后, p_int 会按照int类型读取这片内存, p_char 则是按照 char的方式。所以输出不一样

彻底理解c++的隐式类型转换

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 《C Primer》(第5版)是一本C语言的入门教材,对于初学者来说是一本很好的学习资料。它以中文回答了大量的C语言习题,为读者提供了一个循序渐进的学习过程。 这本书有一些优点,首先是适合各种学习条件的读者。无论是想要在大学学习C语言的学生,还是自学编程的初学者,都可以从这本书中受益。其次,书中的内容易于理解。作者采用简明易懂的语言,讲解了C语言的基础知识和编程技巧,帮助读者快速掌握C语言。第三,书中的习题丰富多样,涵盖了从简单到复杂的各个方面。这些习题不仅有助于加深对C语言知识的理解,还可以帮助读者锻炼编程能力。 由于本人无法提供PDF文档,请读者自行询并下载该书的PDF版本。这本书不仅仅是一个习题集,它还包含了大量的示例代码和案例分析,这些都对读者的学习和实践提供了很好的帮助。 总之,《C Primer》(第5版)是一本很棒的C语言学习资料,读者可以通过习题的练习提高自己的编程能力,掌握C语言的基础知识。希望读者能够借助这本书的帮助,快速地学会C语言编程。 ### 回答2: " C Primer习题集:第5版pdf " 是一本同名教材的习题集,针对C语言编程进行了深入的练习。该习题集的PDF版本可以在网络上进行下载。 这本习题集是为了帮助C语言初学者提高他们的编程技能。它从基础知识开始,逐渐深入到更高级的概念和技术。习题集的章节组织结构与原版教材一致,旨在提供一个系统和综合的学习体验。 这本习题集涵盖了许多重要的编程主题,如变量、运算符、控制流程、数组、字符串、指针、结构体和文件。每个章节都包含大量的习题,涵盖了不同难度级别的问题。这些习题可帮助学生巩固已学知识,并提供了实践机会以应用所学的概念。 与原版教材相比,该习题集以问题为驱动,需要学生进行自我思考和解答。通过反复实践和解决问题,学生可以更好地理解C语言的概念和技术。 总的来说, C Primer习题集:第5版pdf 提供了一个实践性强、系统性好的学习工具,适合想要提高他们C语言编程技能的人使用。通过完成这些习题,学生可以更深入地理解C语言的各个方面,并在实际项目中应用所学的知识。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值