3.1 简单变量
程序必须记录3个基本属性:
信息将存储在哪里;要存储什么值;存储何种类型的信息
&运算符可以用来检索变量的内存地址
3.1.1变量名
提倡使用有一定含义的变量名,命名规则:
在名称中只能使用字母字符、数字和下划线(_)。
名称的第一个字符不能是数字。
区分大写字符与小写字符。
不能将C++关键字用作名称。
以两个下划线或下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用。以一个下划线开头的名称被保留给实现,用作全局标识符。
C++对于名称的长度没有限制,名称中所有的字符都有意义
3.1.2 整型
宽度(width)用来描述存储整数时使用的内存量。使用的内存越多,则越宽。
C++的基本整型(按宽度递增的顺序排列):char,short,int ,long,long long
有符号类型和无符号类型
3.1.3 整型short、int、long和long long
计算机内存的基本单元是位(bit)
字节(byte)通常指的是8位的内存单元
sizeof运算符返回类型或变量的长度,单位为字节
1.运算符sizeof和头文件limits
可对类型名或变量名使用sizeof运算符,对类型名使用sizeof时应将名称放在括号中
头文件climits定义了符号常量来表示类型的限制
CHAR_BIT | char的位数 |
CHAR_MAX | char的最大值 |
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的最小值 |
UNIT_MAX | unsigned int的最大值 |
LONG_MAX | long的最大值 |
LONG_MIN | long的最小值 |
ULONG_MAX | unsigned long的最大值 |
LLONG_MAX | long long的最大值 |
LLONG_MIN | long long的最小值 |
ULLONG_MAX | unsigned long long的最大值 |
符号常量——预处理器方式
#define INT_MAX 32767
2.初始化
int n_int = INT_MAX //赋值与声明合并在一起
C语言没有的初始化语法:
int owls = 101; //C初始化
int wrens(432); //C++初始化
3. C++11初始化方式
数组和结构,在C++98中,也可用于单值变量
int hamburgers = {24}; //hamburgers=24
int emus{7}; //初始化emus=7
int rheas = {12}; //rheas=12
int rocs = {}; //rocs=0
int psychics{}; //psychics=0
3.1.4 无符号类型
3.1.5选择整型类型
自然长度指的是计算机处理起来效率最高的长度。int被设置为对目标计算机而言最为自然的长度。
变量值不可能为负,可以使用无符号类型
变量可能表示整数整大于16位整数的最大可能值,使用long
如果要存储的值超过20亿,可以使用long long
如果short比int小,则使用short可以节省内存。仅当有大型整型数组时,才有必要使用short
如果节省内存很重要,则应使用short
如果只需要一个字节,使用char
3.1.6 整型字面值
整型字面值(常量)是显式地书写的常量,如111
十进制,八进制,十六进制
诸如cout<<hex;等代码不会在屏幕上显示任何内容,而只是修改cout显示整数的方式。
3.1.7 C++如何确定常量的类型
除非有理由存储为其他类型(如使用了特殊的后缀来表示特定的类型,或者值太大,不能存储为int),否则C++将整型常量存储为int类型。
后缀是放在数字常量后面的字母,用于表示类型。
L或l表示整数为long常量
u或U表示unsigned int常量(l看上去像1,因此应使用L做后缀)
对于不带后缀的十进制整数,将使用int,long,long long中能够存储该数的最小类型来表示
对于不带后缀的十六进制和八进制,使用int,unsigned int, long,unsigned long, long long 或unsigned long long 表示
unsigned int 比long更适合用来表示16位的地址
3.1.8 char类型:字符和小整数
char类型是另一种整型
ASCII字符集,ASCII码
EBCDIC编码,Unicode字符集
C++中对字符使用单引号,对字符串用双引号
ch='M'; //ch=77,是一个整数
cout.put(); //通过类对象cout来使用函数put()
句点称为成员运算符。
将字符用单引号括起,表示的是字符的数值编码
转义序列:\a,\n,\"
通用字符名,用法类似于转义序列,可以以\u或\U打头
\u后面是8个十六进制位,\U后面是16个十六进制位
8位char表示基本字符集,wchar_t表示扩展字符集
wchar_t可以表示系统使用的最大扩展字符集,与另一种整型(底层(underlying)类型)的长度和符号属性相同
wcin和wcout可用于处理wchar_t流
可以通过加上前缀L来知识宽字符常量和宽字符串
类型char16_t与/u00F6形式的通用字符名匹配,类型char32_t与/U0000222B形式的通用字符名匹配
3.1.9 bool类型
布尔变量的值可以是true或false
bool is_ready = true;
字面值true和false都可以通过提升转换为int类型,true被转换为1,而false转换为0
任何数字值或指针值都可以被隐式转换为bool值,任何非零值都被转换为true,而零被转换为false
3.2 const限定符
符号名称指出了常量表示的内容。
const type name = value; //创建常量的通用格式
应在声明中对const进行初始化。
如果在声明常量时没有提供值,则该常量的值将是不确定的,且无法修改。
3.3 浮点数
3.3.1 书写浮点数
两种书写浮点数的方式:第一种时使用常用的标准小数点表示法;第二种表示浮点值的方法叫做E表示法,外观像是:3.45E6,指的是3.45与1000000相乘的结果,6被称为指数,3.45被称为尾数
d.dddE+n指的是将小数点向右移n位,而d.dddE-n指的是将小数点向左移n位
3.3.2 浮点类型
C++有3种浮点类型:float,double和long double。这些类型是按它们可以表示的有效数位和允许的指数最小范围来描述的。
有效位是数字中有意义的位。
通常float为32位,double为64位,long double为80、96或128位
指数范围至少是-37到37
3.3.3 浮点常量
1.234f //float常量
2.45E20F //float常量
2.345324E28 //double常量
2.2L //long double常量
3.3.4 浮点数的优缺点
优点:1.可以表示整数之间的值;2.由于有缩放因子,它们可以表示的范围大得多
3.4 C++算术运算符
5种基本的算数计算:加法、减法、乘法、除法、求模
每种运算符都使用两个值(操作数)来计算结果。运算符及其操作数构成了表达式。。
%运算符求模,两个操作数必须都是整数
3.4.1 运算符优先级和结合性
算数运算符遵循通常的代数优先级,先乘除,后加减。
结合性:乘除都是从左到右结合的。
3.4.2 除法分支
除法运算符(/)的行为取决于操作数的类型。
两个操作数都是整数,将执行整数除法,结果是一个整数。
有一个(或两个)操作数是浮点值,结果为浮点数。
浮点常量在默认情况下为double类型
3.4.3 求模运算符
求模运算符返回整数除法的余数。
3.4.4 类型转换
C++自动执行很多类型转换:
将一种算术类型的值赋给另一种算术类型的变量时,C++将对值进行转换;
表达式中包含不同的类型时,C++将对值进行转换;
将参数传递给函数时,C++将对值进行转换。
1.初始化和赋值进行的转换
将一种类型的值赋给另一种类型的变量。值将被转换为接收变量的类型
转换 | 潜在的问题 |
将较大的浮点类型转换为较小的浮点类型,如将double转换为float | 精度(有效数位)降低,值可能超出目标类型的取值范围,在这种情况下,结果将是不确定的 |
将浮点类型转换为整型 | 小数部分丢失,原来的值可能超出目标类型的取值范围,在这种情况下,结果将是不确定的 |
将较大的整型转换为较小的整型,如将long转换为short | 原来的值可能超出目标类型的取值范围,通常只复制右边的字节 |
2. 以{ }方式初始化时进行的转换(C++11)
使用大括号的初始化称为列表初始化,常用于给复杂的数据类型提供值列表。
列表初始化不允许缩窄(narrowing),即变量的类型可能无法表示赋给它的值。
3. 表达式中的转换
同一个表达式中包含两种不同的算数类型时,C++将执行两种自动转换:一些类型在出现时变会自动转换;有些类型在与其他类型同时出现在表达式中时将被转换。
整型提升,在计算表达式时,C++将bool、char、unsigned char、signed char和short值转换为int
4. 传递参数时的转换
由函数原型控制
取消原型对参数传递的控制,char和short应用整型提升,float参数提升为double
5. 强制类型转换
强制类型转换机制显示的进行类型转换
//强制类型转换
(long) thorn
long (thorn)
强制类型转换不会修改变量本身,而是创建一个新的、指定类型的值,可以在表达式中使用这个值
static_cast<>可用于将值从一种数值类型转换为另一种数值类型
3.4.5 C++11中的auto声明
auto,让编译器能够根据初始值的类型推断变量的类型。
auto n=100; //n为int
auto x=1.5; //n为double
3.6 复习题
1.为什么C++有多种整型?
为了满足不同大小的变量长度
有多种整型类型,可以根据特定需求选择最适合的类型。例如,可以使用short来存储空格,使用long来确保存储容量,也可以寻找可提高特定计算机的速度的类型。
2.声明与下述描述相符的变量。
a.short整数,值为80
short a=80;
b.unsigned int整数,值为42110
unsigned int a=42110;
c.值为3000000000的整数
long long a =3000000000;
3.C++提供了什么措施来防止超出整型的范围?
C++没有提供自动防止超出整型限制的功能,可以使用头文件climits来确定限制情况。
4.33L与33之间有什么区别?
33L为long型,33为int型
5.下面两条C++语句是否等价?
char grade=65;
char grade='A';
不等价
这两条语句并不是真正等价,虽然对于某些系统来说,它们是等效的。最重要的是,只有在使用ASCII码的系统上,第一条语句才将得分设置为字母A,而第二条语句还可用于使用其他编码的系统。其次,65是一个int常量,而‘A’是一个char常量。
6.如何使用C++来找出编码88表示的字符?指出至少两种方法。
char c=88;
cout<<c<<endl;
cout.put{char(88)};
cout<<char(88)<<endl;
cout<<(char)88<<endl;
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 74
b. 6*3/4 4
c. 3/4*6 0
d. 6.0*3/4 4.5
e. 15%4 3
9.假设x1和x2是两个double变量,您要将它们作为整数相加,再将结果赋给一个整型变量。请编写一条完成这项任务的C++语句。如果要将它们作为double值相加并转换为int呢?
int c=(int)x1+(int)x2;
int c=x1+x2;作为double类型相加,int pos=int(x1+x2);
10.下面每条语句声明的变量都是什么类型?
a. auto cars=15; 整型
b.auto iou=150.37f; 浮点型float
c. auto level ='B'; 字符型
d. auto crat=U'/U00002155'; 整型char32_t
e.auto fract=8.25f/2.5; 浮点型double