c++ string转double_CC++语言1|数据类型及其转换

数据类型是所有程序语言的基础。C++程序的所有功能都是建立在内置于C++语言的基本数据类型基础之上的。数据类型可以告诉数据代表的意义以及程序可以对数据执行的哪些操作,它确定了数据和数据操作在程序中的意义。

在C/C++中,数据类型分为两种,简单类型和结构类型。简单类型包括有整数类型、字符类型、浮点类型、指针类型、枚举类型和void类型等。结构类型包括有数组、字符串、记录和文件等。C/C++的基本数据类型属于简单类型。用户可以创建的所有数据类型都是根据基本类型定义的。(本小节只讨论简单类型,结构类型内容见后续。)

C++语言定义了几种基本类型,分别是字符型、整型、浮点型等。C++还提供了可用于自定义数据类型的机制,标准库正是利用这些机制定义了许多更复杂的类型,例如,可变长字符串string和vector等。此外,程序员还能自己修改已有的基本类型以灵活定制复合数据类型。

程序中不能定义void类型的变量,它仅仅是用于说明函数没有返回值或说明指针是无类型的。C++中所有的表达式是都可转换或映射为void类型的。

数据存储于内存,可以被随机访问。内存存储单元由8个位(0或1,对应一个晶体管开关)组成一个字节(byte),字节是基本的内存单元,都有一个唯一的内存地址对应。

8588e1da4446b535684ab3a531b69b80.png

每一种编程语言都会将数据区分类型,由类型来定义值域、需要的内存空间,相应的编码和解码方案,可以执行的操作(使用的操作符)。C和C++也不例外。

444d71a260ef42a3b5afc31e516365be.png

数据类型与字节长度:

b088da60324150c2b1ca9a8f32add948.png

数据区分存储类别存储到不同的分区。每一个程序运行后,操作系统称其为一个进程(正在进行的程序),每一个进程都有属于自己的一个内存空间,进一步区分为不同的分区,例如代码存储到代码区,全局变量和静态变量存储到全局/静态区,常量存储到常量区(或数据段),并分配一个固定大小(如1M)的栈区用于存储局部变量(可重复利用),以及在程序运行过程中可以临时申请的堆区(操作系统和各进程占用的空间以外剩下的内存空间及硬盘上的虚拟内存)。

80e96d919f0488ebd26c9dcbc0daf21b.png

就程序的结构而言,一个程序通常是多文件的,即使程序员只写了一个单文件,或多或少会通过预处理的#include来包含一些文件,最后通过链接器将诸多的文件链接到一起。在文件内部,通过语句块、函数来实现模块化。所以数据的可见范围一般从声明处开始,作用域可以是文件内的块、文件,或跨文件。如果需要访问跨文件的全局变量,需要用关键字extern来声明,如:

extern int size;

表示由此处开始需要使用另一文件中定义的全局变量size。这里因为虽然多文件最终都会链接在一起,但编译发生在链接之前,如果不用extern告诉编译器,编译器会找不到size这个标识符,而发生编译错误。如果想让某一全局变量不被跨文件访问到,可以使用static来限定,如:

static int size; //函数外定义的全局变量,static表示不被跨文件访问,从而不能使用extern去声明

static除了可以限定空间以外,在不同的上下文中,可以延长局部变量的存续时间,称为静态局部变量,虽然由static限定的局部变量在空间上是局部的,但在时间上可以延续到程序结束。其在内存中保存的位置也不再是局部变量存储的栈区,而是到了静态存储区。

static int i; //块内声明,static表示延长其存续期到程序结束

1 编码方案与类型转换

同样的一个二进制序列,可以用不同的编码方案去解码(可能有意义,也可能没有意义),数据的类型就包含了编码、解码的方案。所以,数据类型的转换,就是尝试用不同的编码方案去解码。

在算术运算和关系运算中如果参与运算的操作数类型不一样,则系统会对其进行类型转换,这是隐含转换,转换的原则就是将低类型的数据转换为高类型数据。各类型从低到高依次为char,short,int,unsigned int,long,unsigned long,float,double。类型越高范围越大,精度也越高。隐含转换是安全的,因为没有精度损失。逻辑运算符的操作数必须是bool型,如果不是就需要将其转换为bool型,非0数据转换为true,0转换为false。位运算操作数必须是整数,如果不是也会自动进行类型转换,也是低类型数据转换为高类型数据。赋值运算要求赋值运算符左边的值和右边的值类型相同,不同的话也要进行自动转换,但这个时候不会遵从上面的原则而是一律将右值转换为左值的类型。比如,int iVal; float fVal; double dVal;则dVal=iVal*fVal;计算时先将iVal转换为跟fVal一样的float型,乘法的结果再转换为double型。

C语言的强制类型转换:

(要转换的新的数据类型) 被转换的表达式;

要转换的新的数据类型 (被转换的表达式);

一般规则是:

小容器→大容器:高位补零;大容器→小容器:高位截断;

强制类型转换的目的之一:抑制警告信息;在许多情况下,强制类型转换告诉编译器,“是的,我真的想这样做。”这指示编译器,即使有数据损失或其他危险的可能性,也继续执行数据转换。强制类型转换也可以用来澄清模糊的情况。

C语言的类型转换简单粗暴,在C++中区分不同的情况使用不同的关键字进行类型转换。

具体内容请见:C++|详细解释隐式类型转换与C风格、C++风格的显式类型转换

赋值时的自动类型转换是指当表达式的结果类型和变量类型不一致时,系统会将右边的表达式的结果转换成左边的变量的类型,再赋给左边的变量。

2 整型

整型是用来表示没有小数位的数,在C/C++中,用来表示整数、字符和布尔值的算术类型合称为整型。可以用很直接的方式来表示整型字面量,-100、+110、120、8888等。

修饰符是整型的一个重要表示,整型可以加上符号和长短的修饰符来表示不同的存储长度和数值范围。

表示长短的修饰符有short、int、long等。一般来说,short代表半个机器字长;int代表一个机器字长;long代表一个或2个机器字长。

另外,整型还可以是带符号的(signed),也可以是无符号的(unsigned)。带符号的整型可以表示正数也可以表示负数(包括0),而无符号的整型只能表示大于等于0的数。

由于有了前缀,整型就可以细分为char(字符型)、unsigned char(无符号字符型)、signed char(有符号字符型)、int(整型)、unsigned int(无符号整型)、signed int(有符号整型)、short int(短整型)、unsigned short int(无符号短整型)、signed short int(有符号短整型)、long int(长整型)、signed long int(有符号长整型)、unsigned long int(无符号长整型)、bool(布尔型)等13种。

整型的编码方案是补码,正整数的补码就是原码。

负数的补码:按位求反再加1;也就是模数-自身数值,如10010的补码:11111+1-10010;简单理解就是10010取反再加1,也就是1110。

在某些应用中,不可能出现负数,则整型数中有一半的数值范围是被浪费的。因此在C/C++中可以将所有的数都看成正整数,称为无符号数。

要注意的是,C并未很好地实现整数。例如,整数是无穷大的数,但是2字节的int类型只能表示65536个整数。因此,不要混淆抽象概念和具体的实现。

3 字符与转义字符

字符的编码方案有多种,如ASCII、GB2312、Unicode,都是用一个整数去表示不同的字符。ASCII是使用单字节的编码方案,其表示的字符数量有限,ASCII以外的编码方案都是多字节编码,可以表示更多的字符。

字符的内部实现是整数,所以其也可以使用与整型相同的运算符进行运算。

不可见字符(控制字符)与界定符(单引号、双引号、反斜框)、问号等,用一个反斜杠打头进行字符转义。如表示换行,0用在一个字符数组的未尾表示一个字符串的结束。

反斜杠是让后面的字面转为其他的含义,不是利用其本身的含义。

有时我们需要表示一个文件路径,如“c:est.txt",“"只是一个字符,不是用作转义,所以要将其本身转义,文件路径要写为“c:est.txt”。

4 布尔类型

C语言中非0表示真。C中没有布尔类型,但你可以定义:

typedef enum{false,true} bool;

或者使用预定义:

#ifndef bool#define bool int#endif#ifndef true#define true 1#endif#ifndef false#define false 0#endif

C++提供了布尔型:

布尔型变量的类型说明符为booI,用来表示逻辑值。

布尔常量只有两个值:“true”和“false”,表示“真”和“假”,均为关键词,在机器中位长为8位。

5 浮点型

对于小数或实数,在编程语言中并不使用小数,而是将固定长度分为尾数部分、指数部分、及1位的符号位三部分:尾数部分的固定长度就是一个浮点型数据的精度。浮点型的编码方案一般采用real-4或real-8(整型一般采用补码的编码方案)。

单精度 float:占用4字节,3字节尾数,1字节指数, 精确度7位,范围10^-38~10^38

双精度 double:占用8字节, 5字节尾数, 3字节指数, 精确度15~16位,范围10^-307~10^308

long double:占用16字节;

尾数*10指数=尾数e指数,如:

123e2=123002.25e-3=0.00225

注意:尾数不能为空,e3要写成1e3,指数必须为整数,不能写成2.5e2.3。

在C/C++中,浮点数在默认情况下被定义为double类型。如果希望指定float类型的数值,需要在该数值后要加上字母f。

二进制浮点数只能精确地表示多个1/2的幂的和。因此,3/4和7/8可以精确地表示为二进制小数,而1/3和2/5却不能。

一般来说,对于一个浮点数,不会只定义了不使用。通常我们都会对浮点数进行比较复杂的运算,那么在运算的过程中,就有可能发生四舍五入的情况。所以,对于一个进行了一些可能导致四舍五入的运算的浮点数而言,不能保证它的准确性(当然这里的误差是非常非常小的)。所以,在对浮点数比较的时候,就需要考虑到这些误差,方法之一就是,让浮点数与一段数值范围比较,而不是与一个确定的数值比较。

float x = 1e-10;const float EPSINON = 0.00001;if ((x >= - EPSINON) && (x <= EPSINON))cout<

x是一个变量,被定义为float,所以在比较时,零值并不是0,而是以下代码:

if(x>0.000001&&x

6 数据类型占用空间的计算

sizeof 运算符用来了解某一类型或某一表达式占用的内存量。sizeof 运算符的用法: sizeof(类型名) 或 sizeof(表达式);如:

sizeof(float) :float类型的变量占用的内存量;

sizeof('a’+15) :表达式 'a’+15 的计算结果所占的内存量;

如有数组:char arr(11);

arr虽然在用做函数参数时会退化为一指针,但在用作sizeof参数时,会计算整个数组占用的内存空间,所以在用数组做参数的函数中,通常使用以下表达式来计算数组长度:

int arrLen = sizeof(arr)/sizeof(arr[0]);

7 类型别名

typedef为C语言的关键字,作用是为一种数据类型定义一个新名字。这里的数据类型包括内部数据类型(int,char等)和自定义的数据类型(struct等)或者是数据类型的复合声明。

typedef比#define更灵活。typedef由编译器解释,只能用于类型,不能用于值。能提高程序的移植性。

typedef用于将复合类型声明进行简写。

char * string; typedef char * STRING; //STRING是一个类型,该类型是指向char的指针;STRING name, sign;相当于:char * name, * sign;typedef {double x; double y;} rect;rect r1 = {3.0, 6.0};rect r2;以上代码可以翻译成:typedef {double x; double y;} r1 = {3.0,6.0};typedef {double x; double y;} r2;r2 = r1;

用typedef定义类型的方法:

① 先按定义变量(或声明)的方法写出定义体(如:int i)。

② 将变量名换成新类型名(例如:将i换成COUNT)。

③ 在最前面加typedef(例如:typedef int COUNT)。

④ 然后可以用新类型名去定义变量。

如函数指针:

int add();typedef int (*pf)(); //pf就是对复合声明的一种简化pf f = add; 

使用typedef时记住,typedef并没有创建新的类型,它只是为某个已存在的类型增加了一个方便使用的标签。可以把它理解为一个可移植数据的工具,因为C是强类型语言。

8 枚举类型

枚举类型是一种特殊的自定义的整数类型,这种整数类型的取值有其特殊性,值的范围是有限的、可枚举的整形常量。

在开发应用程序时,经常需要使用一组标记来描述对象的状态。例如一个记录集对象可以有打开状态、编辑状态和关闭状态。在程序中为了描述记录集的状态,通常定义一组常量值来限制用户传递的参数。

枚举类型能够很好的解决上述问题,它能够将一组枚举常量与一个枚举类型名称关联。如果将函数的参数定义为某一个枚举类型,则只允许该枚举常量作为函数实际参数。

如果一个变量只有几种可能的整数值,可以一一列举出来,并希望为每一个值取一个名字代表,增加程序的可读性,则可以把该变量定义成枚举类型。

定义枚举类型的格式是:

enum { [= ],…, [ = ]};

enum week { sun,mon,tue,wed,thu,fri,sat,sun }day;

当然也可以把枚举类型的定义和枚举变量的定义分开,在定义了枚举类型之后,以如下的格式定义枚举变量:

[enum] ;

也可以使用typedef来简化声明:

typedef enum{false,true} bool;

相对于单独的#define宏定义,枚举定义的命名常量相互之间通过枚举类型建立了关联。

-End-

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值