《C++自学入门》3.基本数据类型-1
面向对象编程OOP的本质是设计自己的数据类型,如果利用正确的数据结构,这对特定的项目解决起来事半功倍,在创建自己的数据结构之前,我们先了解C++内置的数据类型。内置的数据类型分为基本数据类型和复合类型。
1.整型变量
程序都要存储信息--》比如班级同学的成绩,今天的天气,恒生电子股票的价格等。为把信息存储在计算机中,程序必须记录三个基本属性:信息存储在哪?具体的数值是多少?信息的类型是什么?面对这些问题,这里我们只需要声明定义一个变量就可以了:
int moneyConut = 5;宁一般在家私房钱需要找个安静的地方存放,在C++中就利用变量存储宁想保存的数据。
1.1 变量名
我们使用变量时,名字时需要考虑的重点,如果只是 int a,b,c;那么一个稍微大一点的程序,可阅读性就会很差。因为不知道这些变量存放的是什么数据。如果变量表示出差旅费,应将其命名为cost_of_trip或者costOfTrip。但是变量名也应该遵循C++的规则,就像宁给儿子取名一样。大致上有三点:名字只能由数字、字母、下划线组成,名字的第一个字符不能是数字,不能使用C++关键字作名字。
有时一个单词组成的名字往往不够表达意义,通常的做法是用下划线将单词分开,如my_money;或者从第二个单词开始将每个单词的第一个字母大写。比如myMoney。(C程序员喜欢使用下划线,而在JAVA里更倾向于大写的方式)。
随着对 C++的逐步了解,将发现很多有关前缀命名风格的示例,还有其他更奇异、更违反直觉的风格,采不采用这些风格,完全取决于程序员。在C++所有主观的风格中,一致性和精确度是最重要的。根据自己的需要、喜好和个人风格来使用变量名(或必要时,根据雇主的需要、喜好和个人风格来选择变量名)。
1.2 整型数据存储
整数和浮点数是最常见的数据,也是理解起来最简单的。整型数据就是没有小数的数据,就像1,-99,0一样。在数学上,整数没有界限,是负无穷到正无穷的开区间,但是计算机内存是有限的,因此,C++语言只能提供一个整数的部分子集。
C++基本类型有char、short、int、long和C++新增的long long。这些数据类型还分有符号和无符号,无符号不能表示负值,(因为最高位不是符号位)在定义变量时数据类型前加上 unsigned就可以表示无符号型数据。比如--》unsigned int a = 99;C++整型分为short、int、long、和long long。这些类型通过使用不同数目的位来存储值,最多能够表示四种不同的整数宽度。如果在所有的系统中,每种类型的宽度都相同,那么使用起来将非常方便。但是现实没那么简单,没有一种选择能满足所有的计算机设计要求。
下面说说位和字节:计算机内存由一些叫做位(bit)的基本单元组成。可以将位看成电子开关,通路就是1,短路就是0。这就是我们说的二进制,假设我们有8位,那么可以演变出2^8也就是256种不同的数字,(每一位都有两种选择),而16位单元可以表示2^16个数字。字节(byte)通常指的是8位的内存单元,字节是描述计算机内存量的度量单位,1KB等于1024个字节,1MB等于1024KB。
整型数据的大小和操作系统有关,在老式的IBM PC机上,int占16位(2个字节),而在Windows XP,Windows 7和其他很多微型计算机中,int 占4个字节。一般声明的变量都是有符号整型,这意味着在每种类型的取值中,负值和正值几乎相同,比如16位的int取值范围是-32768到+32767。(上面解释了16位可以表示65536个值)。下面通过两个方法判断系统整型所占的位数:1--》利用运算符sizeof(),它将返回小括号内的数据长度,单位是字节。2--》利用climits头文件,其中包含了各种限制的宏定义。利用这些名称,可以了解整型最大取值。下面看程序:==>
点击查看代码
#include <iostream>
#include <climits>
using namespace std;
int main()
{
cout << "int 占" << sizeof(short) << "位" << "最大值是" << SHRT_MAX << endl;
cout << "short 占" << sizeof(int) << "位" << "最大值是" << INT_MAX << endl;
cout << "long 占" << sizeof(long) << "位" << "最大值是" << LONG_MAX << endl;
cout << "long long 占" << sizeof(long long) << "位" << "最大值是" << LLONG_MAX << endl;
return 0;
}
如此我们便得到了自己操作系统的整型数据大小:

个人感觉sizeof好用一点,下面是一些climits头文件中的符号常量:
点击查看
/*<climits>头文件定义的符号常量--》
CHAR_MIN char的最小值
SCHAR_MAX signed char 最大值
SCHAR_MIN signed char 最小值
UCHAR_MAX unsigned char 最大值
SHRT_MAX short 最大值
SHRT_MIN short 最小值
USHRT_MAX unsigned short 最大值
INT_MAX int 最大值
INT_MIN int 最小值
UINT_MAX unsigned int 最大值
UINT_MIN unsigned int 最小值
LONG_MAX long最大值
LONG_MIN long最小值
LLONG_MAX long long最大值
LLONG_MIN long long最小值
ULONG_MAX unsigned long 最大值
FLT_MANT_DIG float 类型的尾数
FLT_DIG float 类型的最少有效数字位数
FLT_MIN_10_EXP 带有全部有效数的float类型的负指数的最小值(以10为底)
FLT_MAX_10_EXP float类型的正指数的最大值(以10为底)
FLT_MIN 保留全部精度的float类型正数最小值
FLT_MAX float类型正数最大值
*/
1.3 整型数据初始化
要使用变量,首先要创造变量,对变量初始化。初始化就是将声明定义合并在一起:int myMoney = 0;或者将变量给另一个变量初始化:int yourMoney = myMoney;C++不常见的几种初始化:int h(1)、int h{1}(C++11特性,需要注意精度丢失,被称为初始化器列表)、int h = {1}。
将大括号初始化器用于单值变量的情形还不多,C++11标准使得这种情形更多了,使用花括号初始化器时,括号内可以不包含任何东西,此时变量值为0。最好在声明时就给变量赋值,将变量声明赋值分开,可能带来一些意想不到的麻烦:前面我们声明int a;后文:int b = a;此时a的值是不确定的。(如果是全局变量或者静态变量,值为0;但如果是局部变量,它的值是未知的,这取决于它被创建之前相应内存单元保存的值。这涉及到虚拟内存图,我们后面再谈。)
1.4 无符号类型
前面介绍的都是有符号整型,也就是最高位为符号位。下面介绍无符号类型,其优点是可以增加变量能够存储的最大值,理解起来也很简单,最高位不代表符号位,它的最大值就比有符号多一倍,例如,short表示的范围是-32768到+32767,那么无符号版本的范围就是0到65535。前面说了使用关键字unsigned修饰无符号类型,这里需要注意--》unsigned x = 9;这个也是对的,因为unsigned 本身是unsigned int的缩写。下面来看一个有关无符号和有符号整型的经典案例:==》
点击查看代码
#include <iostream>
#include <climits>
using namespace std;
int main()
{
short shortMax = SHRT_MAX;
unsigned short ushortMax = shortMax;
cout << "shortMax=" << shortMax << endl;
cout << "ushortMax=" << ushortMax << endl;
shortMax++;
ushortMax++;
cout << "shortMax+1=" << shortMax << endl;
cout << "ushortMax+1=" << ushortMax << endl;
shortMax = 0;
ushortMax = 0;
shortMax--;
ushortMax--;
cout << "shortMax=" << shortMax << endl;
cout << "ushortMax=" << ushortMax << endl;
return 0;
}
我们可以猜猜打印的结果是什么,答案如下:--》

首先shortMax是short的最大值,把它转换成无符号给ushortMax赋值,所以打印出来32767。但是我们强行让shortMax加一,这就超过了它的范围,这称为上溢,像个轮回一样,它将会从它的另一端取值(同理,我们加2,就是-32767)。但这对于无符号整型来说毫无问题,因为它的范围还大着呢。我们再看:对于shortMax归零后执行减一,这没问题,仍然在它的范围之内。但对于无符号来说,它不能表示负数,此时下溢出错,它也会从另一端也就是最大值段取值,变成65535。

我们后面还会有数据类型转换的问题,这涉及到整数在计算机的存储方式(二进制)。也是一个经典的问题。我们一般在处理硬件内存地址的时候用到unsigned比较多,因为地址没有符号,(还会用到另一个关键字volatile,当然都是后话了)。
2.字符类型
2.1 打印字符
下面介绍另一种类型:char,在实际操作中,不可能光是数字就能解决存储信息的问题,char类型就是专门存储字符而设计的。编程语言通过使用字母的数值编码实现存储字母,因此char是另一种整型。它足够长,能够表示目标计算机系统中的所有基本符号,实际上。很多系统支持的字符都不超过128个,因此用一个字节就可以表示所有的符号。
最常用的字符集是ACSLL字符集,它其中的每个字符都有对应的编码也就是ASCLL码。例如:A的编码为65,M的编码为77。下面简单输出一个字符:--》
点击查看代码
#include <iostream>
using namespace std;
int main()
{
char ch,ch1;
ch1 = 'A';
int i = ch1;
cout << "请输入一个字符" << endl;
cin >> ch;
cout << "==============" << endl;
cout << i << endl;
cout << ch1 << endl;
cout.put(ch);
return 0;
}
前面我们知道了整型是直接赋具体的数值,字符有点不一样,它用单引号' '来表示。程序运行时会被阻塞直到从键盘输入一个值并且敲下回车键,如果这里我们输入M,看看运行结果:

有趣的是,我们输入的是M,而不是对应的字符编码77.另外,程序打印M,而不是77。通过查看内容可以知道,77是存储在变量ch中的值,这种神奇的力量不是来自char类型,而是来自cin和cout,这些工具为宁完成了转换工作。输入时,cin将键盘输入的M转换为77,输出时,cout将值77转换为所显示的字符M,cin和cout的行为都是由变量类型所引导的。如果将77存储在int变量中,则cout将把它显示为77(也就是说,cout显示两个字符7)。
2.2 成员函数cout.put()
cout.put()到底是个什么东西,为什么名称中有一个句点,学过C语言的都知道,一般'.'用于struct结构体。函数cout.put()是一个重要的C++OPP概念。类定义了如何表示和控制数据,成员函数归类所有,描述了操纵类数据的方法。类ostream有一个put()成员函数,用来输出字符,但是只能通过对象(比如这里的cout对象)来使用,而'.'句点称为成员运算符,cout.put()的意思是,通过类对象cout来使用函数put()。cout.put()提供了另一种显示字符的方法,可以替代'<<'运算符。那为何需要 cout.put()。答案与历史有关。在C++的 Release 2.0之前,cout将字符变益显示为字符,而将字符常量显示为数字。问题是,C++的早期版本与C 一样,也将把字符常盘存储为int类型。也就是说,'M'的编码77将被存储在一个16位或32位的单元中。而char变量占8位。所以早期的'<<'将一个字符常量打印为ASCLL码值。
2.3 char字面值
我们通过单引号''可以方便地表示字符常量,但有些字符不能直接通过键盘输入到程序中,例如按回车键并不能表示一个换行符。比如我们要表示'这个字符怎么办呢?C++提供了一种特殊的表示方法--》转义序列。如下表:

3.bool类型
3.1 bool类型
ANSI/ISO C++标准添加了一种名叫bool的新类型。它的名称来着英国数学家George Boole,是他开发了逻辑律的数学表示法。在计算中,布尔变量的值只能是true或false。过去C++和C一样,也没有布尔类型,一般零解释为false,非零解释为true。现在表示可以这样编写语句:bool is_ready = true;而字面值true和false都可以通过强制转换为int类型,true被转换为1,而fakse被转换为0。另外,任何数字都可以隐式转换为bool值,任何非零值都被转换为true,而非零被转换为false。

存储数据的变量
浙公网安备 33010602011771号