“21天好习惯”第一期-13

12 篇文章 0 订阅
本文详细介绍了C++中的类型转换,包括初始化和赋值转换、表达式中的转换、参数传递时的转换以及强制类型转换。特别强调了C++11中的auto关键字如何简化变量声明,以及在不同类型转换中的注意事项。示例代码展示了类型转换的效果及其可能产生的问题。
摘要由CSDN通过智能技术生成

C++心得笔记


目录

C++心得笔记

C++ Primer Plus 第三章 处理数据

 3.4.4        类型转换

3.4.5        C++11中的auto声明         


C++ Primer Plus 第三章 处理数据

 3.4.4        类型转换

        C++丰富的类型允许根据需求选择不同的类型,这也使计算机的操作更复杂。为处理这种潜在的混乱,C++自动执行很多类型转换:

  •         将一种算术类型的值赋给另一种类型的变量时,C++将对值进行转换;  
  •         表达式时包含不同的类型时,C++将对值进行转换;
  •         将参数传递给函数时,C++将对值进行转换。 

1、初始化和赋值进行的转换

        C++允许将一种类型的值赋给另一种类型的变量。这样做时,值将被转换为接受变量的类型。例如:

         long so_long;

        short thirty;

        so_long = thirty; 

         进行赋值时,程序将thirty的值(通常是16位)扩展为long值(通常为32位)。扩展后将得到一个新值,这个值被存储在so_long中, 而thirty的内容不变。

        将一个值赋给值取值范围更大的类型通常不会导致什么问题。例如,将short值赋给long变量并不会改变这个值,只是占用的字节更多而已。然而,将一个很大的long值(如2111222333)赋给float变量将降低精度。因为float只有6位有效数字,因此这个值将被四舍五入为2.11122E9。因此, 有些转换是安全的,有些则会带来麻烦。

下面的程序演示了一些初始化进行的转换:

#include<iostream>
#include<stdlib.h>
int main()
{
	using namespace std;
	cout.setf(ios_base::fixed, ios_base::floatfield);
	float tree = 3;		// int converted to float
	int guess(3.9832);	// double converted to int 
	int debt = 7.2E12; 	// result not defined in C++
	cout << "tree = " << tree << endl;
	cout << "guess = " << guess << endl;
	cout << "debt = " << debt << endl;
	system("pause");
	return 0;	
} 

当你将整数变量初始化为浮点值时,有些编译器将提出警告,指出这可能会丢掉数据。

2、以{}方式初始化时进行的转换(C++11)

        C++将使用大括号的初始化称为列表初始化(list-initialization),因为这种初始化常用于给复杂的数据类型提供值列表。与上面那个程序所示的初始化方式相比,它对类型转换的要求更严格。具体地说,列表初始化不允许缩窄(narrowing),即变量的类型可能无法表示赋给它的值。

        在不同的整型之间转换或将整型转换为浮点型可能被允许,条件是编译器知道目标变量能够正确地存储赋给它的值。例如:

const int code = 66;
int x = 66;
char c1 {31325};    //narring, not allowed
char c2 = {66};     // allowed because char can hold 66
char c3 {code};     // ditto
char c4 = {x};      // not allowed, x is not constant
x = 31325;          
char c5 = x;        // allowed by this form of initialization

        在上述代码中, 初始化c4时, 您知道x的值为66, 但在编译器看来, x是一个变量, 其值可能很大。编译器不会跟踪下述阶段可能发生的情况:从 x被初始化到它被用来初始化c4。 

3、表达式中的转换 

        当同一个表达式中包含两种不同的算术类型时,C++将执行两种自动转换:首先,一些类型在出现时便会自动转换;其次,有些类型在与其他类型同时出现在表达式中时将被转换。

        自动转换:在计算表达式时,C++将bool、char、unsigned char、signed char和short值转换为int。具体地说,true被转换为1,false被转换为0。这些转换被称为整型提升(integral promotion)。例如:

        short chickens = 20;               

        short ducks = 35;

        short fowl = chickens + ducks; 

        执行这些语句时,C++程序取得chickens和ducks的值,并将它们转换为int。然后,程序将结果转换为short类型,因为结果将被赋值给一个short变量。(通常int类型选择为计算机最自然的类型) 

4、传递参数时的转换 

        传递参数时的类型转换通常由C++函数原型控制。然而也可以取消原型对参数传递的控制。为保持与传统C语言的大量代码的兼容性,在将参数传递给取消原型对参数传递控制的函数时,C++将float参数提升为double。

5、强制类型转换 

        C++还允许通过强制类型转换机制显示地进行类型转换。强制类型转换的格式有两种。例如:

                (long) thorn        // returns a type long conversion of thorn

                   long (thorn)        // returns a type long conversion of thorn 

        强制类型转换不会修改thorn变量本身,而是创建一个新的、指定类型的值,可以在表达式中使用这个值。第一种格式是来自与C语言,第二种格式是纯粹的C++。

        C++还引入了4个强制类型转换运算符,对它们的使用要求更为严格,在这四个运算符中,static_cast<>可用于将值从一种数值类型转换为另一种数值类型。

#include<iostream>
#include<stdlib.h>
int main()
{
	using namespace std;
	int auks, bats, coots;
	auks = 19.99 + 11.99;
	bats = (int) 19.99 + (int) 11.99;	// old C syntax
	coots = int (19.99) + int (11.99);	// new C++ syntax
	cout << "auks = " << auks << ", bats = " << bats;
	cout << ", coots = " << coots << endl;
	
	char ch = 'Z';
	cout << "The code for " << ch << " is ";	//print as char
	cout << int (ch) << endl;	// print as int 
	cout << "Yes, the code is ";
	cout << static_cast<int>(ch) << endl; 	// using static_cast
	system("pause");
	return 0;	
} 

3.4.5        C++11中的auto声明         

        C++11新增了一个工具,让编译器能够根据初始值的类型推断变量的类型。为此,它重新定义了auto的含义。如果使用关键字auto,而不指定变量的类型,编译器将把变量的类型设置程=成与初始值相同:

auto n = 100;        // n is int
auto x = 1.5;        // x is double
auto y = 1.3e12L;    // y is long double

然而,自动推断类型并非为这种简单情况而设计的:事实上,如果将其用于这种简单情形,甚至会出现错误。例如:

auto x = 0.0;     // ok, x is double 
double y = 0;     // ok, 0 automatically converted to 0.0
auto z = 0;       // ops, z is int because 0 is int

       处理复杂类型,如标准模块库(STL)中的类型时,自动类型推断的优势才能显现出来。例如,对于下述C++98代码:

std::vector<double> sores;
std::vector<double>::iterator pv = scores.begin();

        C++11 允许您将其重写为下面这样:

std::vector<double> scores;
auto pv = scores.begin();

         

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值