第3章 处理数据
面向对象编程(OOP)的本质是设计并扩展自己的数据类型。
设计自己的数据类型就是让类型与数据匹配。
如果正确做到了这一点,将会发现以后使用数据时会容易得多。
内置的C++类型分两组:基本类型和复合类型。
基本类型,即整数和浮点数。
复合类型,包括数组、字符串、指针和结构。
标识存储的数据的方法,可以使用变量,或指针。
C++命名规则。
在名称中只能使用字母字符、数字和下划线(_)。
名称的第一个字符不能是数字。
区分大写字符与小写字符。
不能将C++关键字用作名称。
以两个下划线或下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用。以一个下划线开头的名称被保留给实现,用作全局标识符。
C++对于名称的长度没有限制,名称中所有的字符都有意义。
C++的基本整型(按宽度递增的顺序排列)分别是char、short、int、long和C++11新增的long long,其中每种类型都有符号版本和无符号版本,因此总共有10种类型可供选择。
初始化
初始化将赋值与声明合并在一起。
int uncles = 5;
int aunts = uncles;
int chairs = aunts + uncles + 4;
C++ 11 初始化方式
这种方式用于数组和结构,但在C++98中,也可用于单值变量:
首先可以使用等号,也可以不使用;
其次,大括号内可以不包含任何东西,这样变量将被初始化为零;
第三,这有助于更好地防范类型转换错误。
int hamburgers = {24};
int emus{7};
int rocs = {};
int psychics{};
以前, C++使用不同的方式来初始化不同的类型:
初始化类变量的方式不同于初始化常规结构的方式,而初始化常规结构的方式又不同于初始化简单变量的方式;
通过使用C++新增的大括号初始化器,初始化常规变量的方式与初始化类变量的方式更像。
所以,简单变量 等用于 常规变量呢?
3.1.4 无符号类型
3.1.5 选择整型类型
通常, int被设置为对目标计算机而言最为“自然”的长度。 自然长度(natural size) 指的是计算机处理起来效率最高的长度。
如果知道变量可能表示的整数值大于16位整数的最大可能值, 则使用long。 即使系统上int为32位, 也应这样做。
3.1.6 整型字面值
整型字面值(常量)是显式地书写的常量,如212或1776。
与C相同, C++能够以三种不同的计数方式来书写整数:基数为10、基数为8(老式UNIX版本)和基数为16(硬件黑客的最爱)。
在默认情况下, cout以十进制格式显示整数。
如果要以十六进制或八进制方式显示值,则可以使用cout的一些特殊特性。前面指出过,头文件iostream提供了控制符endl,用于指示cout重起一行。同样,它还提供了控制符dec、 hex和oct,分别用于指示cout以十进制、十六进制和八进制格式显示整数。
int chest = 42;
int waist = 42;
int inseam = 42;
cout << "Monsieur cu七 s a striking figure!" << endl;
cout << "chest = " << chest << "(decimal for 42)" << endl;
cout << hex;
cout << "waist = " << waist << "(hex for 42)" << endl;
cout << oct;
cout << "inseam = " << inseam << "(oct for 42)" << endl;
因此,控制符hex实际上是一条消息,告诉cout采取何种行为。另外,由于标识符hex位于名称空间std中,而程序使用了该名称空间,因此不能将hex用作变量名。
然而,如果省略编译指令using,而使用std::cout、 std::endl、 std::hex和std::oct,则可以将hex用作变量名。
3.1.7 C++ 如何确定常量的类型
默认情况下,整型常量存储为 int 类型。
首先可以使用后缀,L,UL;
其次是长度,在将40000表示为long的计算机系统中,十六进制数0x9C40(40000)将被表示为unsigned int。这是因为十六进制常用来表示内存地址,而内存地址是没有符号的,因此, usigned int比long更适合用来表示16位的地址。
3.1.8 char 类型:字符和小整数
专为存储字符(如字母和数字)而设计的。
如何在C++中书写字符字面值: 将字符用单引号括起, 如'M'
(注意,示例中没有使用双引号。 C++对字符用单引号, 对字符串使用双引号。cout对象能够处理这两种情况, 但正如第4章将讨论的, 这两者有天壤之别) 。
char ch = 'M';
int i = ch;
cout << "ch = " << ch << endl;
cout << "i = " << i << endl;
cout << "The ASCLL code for " << ch << " is " << i << endl;
cout << "Add one to the character code:" << endl;
ch = ch + 1;
i = ch;
cout << "The ASCLL code for " << ch << " is " << i << endl;
cout << "Displaying char ch using cout.put(ch):";
cout.put(ch);
cout << endl << "Done" << endl;
生成如下,程序将同样的值赋给 int 变量 i,这样 ch 和 i 的值都是 77。接下来, cout 把 ch 显示为 M,而把 i 显示为 77。
ch = M
i = 77
The ASCLL code for M is 77
Add one to the character code:
The ASCLL code for N is 78
Displaying char ch using cout.put(ch):N
Done
C++将字符表示为整数提供了方便,使得操纵字符值很容易。不必使用笨重的转换函数在字符和ASCII码之间来回转换。
即使通过键盘输入的数字也被视为字符。请看下面的代码:
如果您输入5并按回车键,将读取字符“5”,并将其对应的字符编码(ASCII编码53)存储到变量 中。
如果您也输入5并按回车键,将读取字符“5”,将其转换为相应的数字值 5,并存储到变量 b 中。
char a;
cin >> a;
cout << "a = " << a << endl;
int b;
cin >> b;
cout << "b = " << b << endl;
测试如下,由于 cout 的智能性,没办法就原始存储与输出作验证。
c
a = c
c
b = 0
3.1.8.2.成员函数
cout.put()是成员函数的第一个例子。类定义了如何表示和控制数据。成员函数归类所有,描述了操纵类数据的方法。
要通过对象(如cout)使用成员函数,必须用句点将对象名和函数名称(put( ))连接起来。
句点被称为成员运算符。
c
a = c
cout.put() = c
c
b = 0
cout.put() = 0
cout.put( )成员函数提供了另一种显示字符的方法,可以替代<<运算符。
为何需要cout.put( )。答案与历史有关。
在C++的Release 2.0之前, cout将字符变量显示为字符,而将字符常量(如‘M’和‘N’)显示为数字。
问题是, C++的早期版本与C一样,也将把字符常量存储为int类型。
也就是说, ‘M’的编码77将被存储在一个16位或32位的单元中。而char变量一般占8位。
3.1.9 bool 类型
3.2 const 限定符
符号名称指出了常量表示的内容。另外,如果程序在多个地方使用同一个常量,则需要修改该常量时,只需修改一个符号定义即可。
一种是 #define 语句
一种是使用 const 关键字来修改变量的声明和初始化。
但const比#defien好。
首先,它能够明确指定类型。
其次,可以使用C++的作用域规则将定义限制在特定的函数或文件中(作用域规则描述了名称在各种模块中的可知程度,将在第9章讨论)。
第三,可以将const用于更复杂的类型,如第4章将介绍的数组和结构。
3.3 浮点数
这是 C++ 的第二组基本类型。浮点数能够表示带小数部分的数字,或数字很大,无法表示为 long 类型。
一种用标准小数点表示法;
一种是 E 表示法;
E表示法确保数字以浮点格式存储,即使没有小数点。
注意,既可以使用E也可以使用e,指数可以是正数也可以是负数。然而,数字中不能有空格,因此7.2 E6是非法的。
注意, −8.33E4指的是−83300。前面的符号用于数值,而指数的符号用于缩放。
d.dddE+n指的是将小数点向右移n位,
而d.dddE~n指的是将小数点向左移n位。
之所以称为“浮点”,就是因为小数点可移动。
和ANSI C一样, C++也有3种浮点类型: float、 double和long double。
记住,对于float, C++只保证6位有效位。
3.4 算术运算符
表达式 等价于 操作数 和 运算符。
注意,仅当两个运算符被用于同一个操作数时,优先级和结合性规则才有效。
3.4.4 类型转换
C++自动执行很多类型转换:
将一种算术类型的值赋给另一种算术类型的变量时, C++将对值进行转换;
表达式中包含不同的类型时, C++将对值进行转换;
将参数传递给函数时, C++将对值进行转换。
(typeName) value
typeName (value)
第一种格式来自C语言,第二种格式是纯粹的C++。新格式的想法是,要让强制类型转换就像是函数调用。
这样对内置类型的强制类型转换就像是为用户定义的类设计的类型转换。
3.4.5 C++11 中的 auto 声明
C++11新增了一个工具,让编译器能够根据初始值的类型推断变量的类型。
3.6 复习题
1.为什么C++有多种整型?
包罗万象,bool,char,short,int,long,long long(2 + 10)
2.声明与下述描述相符的变量。
a. short整数,值为80
b. unsigned int整数,值为42110
c.值为3000000000的整数
short s = 88;
unsigned int us = 42110;
float f = 3e9
3. C++提供了什么措施来防止超出整型的范围?
无符号整型(×)
C++没有提供自动防止超出整型限制的功能,可以使用头文件 climits 来确定限制情况。
4. 33L与33之间有什么区别?
默认是 int
5.下面两条C++语句是否等价?
char grade= 65;
char grade = 'A';
不等价
6.如何使用C++来找出编码88表示的字符?指出至少两种方法。
7.将long值赋给float变量会导致舍入误差,将long值赋给double变量呢?将long long值赋给double变量呢?
如果long为4个字节,则没有损失。因为最大的long值将是20亿,即有10位数。
由于double提供了至少13位有效数字,因而不需要进行任何舍入。
long long 类型可提供19位有效数字,超过了double保证的13位有效数字。
8.下列C++表达式的结果分别是多少?
a. 8 * 9 + 2
b. 6 * 3 / 4
C. 3 / 4 ~;c; (i
d. 6.0 * 3 / 4
e. 15 ¾) 4
9.假设x1和x2是两个double变量,您要将它们作为整数相加,再将结果赋给一个整型变量。请编写一条完成这项任务的C++语句。如果要将它们作为double值相加并转换为int呢?
double x1, x2;
int x = x1 + x2;
10.下面每条语句声明的变量都是什么类型?
a. auto cars= 15;
b. auto iou = 150.37f;
C. auto level= 'a';
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)