《C++ Primer Plus》学习笔记——第3章 处理数据

  • 内置的C++类型分为两组:简单类型和复合类型,本章介绍基本类型:整数和浮点数。

3.1 简单变量

3.1.1 变量名

  • 变量名命令规则:

1、在名称中只能使用字母字符、数字和下划线
2、名称的第一个字符不能是数字
3、区分大小写字符
4、不能将C++关键字用于变量名称
5、以两个下划线打头或下划线和大写字母打头的名称被保留给实现(编译器及其使用的资源)使用,一个下划线开头的名称被保留给实现,用作全局标识符
6、C++对于名称长度没有限制,但是平台会有限制

3.1.2 整型

  • C++整型分别为:char、short、int、long、和C++11新增的long long。

3.1.3 整型short、int、long和long long

  • C++中对类型的长度采取灵活的实现,确保了最小的长度:

1、short至少16位
2、int至少和short一样
3、long至少32位,且至少与int一样长
4、long long至少64位,且至少与long一样长

  • Ubuntu 20.0.4 64位显示
#include <iostream>
#include <climits>
using namespace std;

int main() {
    int a = INT_MAX;
    short b = SHRT_MAX;
    long c = LONG_MAX;
    long long d = LLONG_MAX;
    cout << "int size is " << sizeof a << endl;
    cout << "short size is " << sizeof b << endl;
    cout << "long size is " << sizeof c << endl;
    cout << "long long size is " << sizeof d << endl;
    cout << endl;
    cout << "Maximum values:" << endl;
    cout << "int: " << a << endl;
    cout << "short: " << b << endl;
    cout << "long: " << c << endl;
    cout << "long long: " << d << endl;
    return 0;
}
输出
int size is 4
short size is 2
long size is 8
long long size is 8

Maximum values:
int: 2147483647
short: 32767
long: 9223372036854775807
long long: 9223372036854775807
  • 可对类型名或者变量名使用sizeof,当对类型名使用时,需要加括号,如sizeof (int) ,而对变量名时,括号是可选的。

3.1.4 无符号整型

  • 上节中的4种整型都有一种无符号的变体,优点是可以增大变量能够存储的最大值。
  • 无符号整型和有符号整型都存在整数溢出行为,无符号数超过最大值后会从0重新开始,有符号数则是从最小值重新开始。

3.1.5 选择整型类型

  • 通常,int被设置为对目标计算机来说处理效率最高的长度。如果没有其他理由,一般使用int
  • 如果为非负整数,则选择无符号类型
  • 如果整数数值大于16位,则应选择long,即使系统int是32位的,这样将程序移植到16系统上时,就不会无法工作
  • 通常仅当有大型整型数组时,才有必要使用short,即使short和int一样位数,因为从16位机移植到32位机,占用内存会翻倍,而short不会。

3.1.6 整型字面值

  • 对于C++整型字面值,使用前一(两)位来标识数字常量的基数,第一位为1~9,则基数为10;第一位为0,则基数为8;前两位为0x或0X则基数为16。
#include <iostream>
using namespace std;

int main() {
    int a = 42;
    int b = 0x42;
    int c = 042;
    cout << a << endl;
    cout << b << endl;
    cout << c << endl;
    return 0;
}
输出
42
66
34
  • cout提供了三种控制符,用于输出十进制、十六机制和八进制的数
#include <iostream>
using namespace std;

int main() {
    int a = 42;
    int b = 42;
    int c = 42;
    cout << dec;
    cout << a << endl;
    cout << hex;
    cout << b << endl;
    cout << oct;
    cout << c << endl;
    return 0;
}
输出
42
2a
52

3.1.7 C++如何确定常量的类型

  • 除非有理由储存为其他类型,否则都是int类型。理由有使用特殊的后缀来表示特定的类型,或者值太大,不能存储为int。
  • 后缀:数字后加l或者L表示long常量,u或者U表示unsigned int类型,组合起来uL表示unsigned long类型,以此类推。
  • 数据长度则根据具体系统支持的数据的最大长度来。

3.1.8 char类型:字符和小整数

  • char类型是专为存储字符设计的,是整型类型,可以表示比short更小的数,占一个字节。
#include <iostream>
using namespace std;

int main() {
    char a = 77;
    cout << a << endl;
    return 0;
}
输出
M
  • char存储的是字符的编码值,打印出M是因为cin和cout都能够处理字符。C++实现使用的编码是主机系统的编码。一般编码都包含ASCII编码,C++支持的wchar_t的宽字符类型能够存储更多的值,如Unicode编码。
#include <iostream>
using namespace std;

int main() {
    char a = 77;
    cout << "a is ";
    cout.put(a);
    return 0;
}
输出
a is M
  • cout的put函数提供了另一种显示字符的方法,可以替代<<运算符。
  • char字面值,char字面值使得在不同的编码中表示同一个字符,但其存储到计算机中的编码值可能不同。
  • 有些无法通过键盘输入的字符则需要转义,C++有专门的转义序列编码。
  • 与int不同的是,char在默认情况下既不是有符号的,也不是无符号的,是否有符号由C++实现决定,可以通过显示的将类型设置为signed char或unsigned char。
  • wchar_t可以扩展字符集,cin和cout对应char的字符流,对于wchar_t,也有相应的工具,是wcin和wcout。
  • C++11新增了char16_t和char32_t,前者是16位无符号类型的,后者是32位无符号类型的,可以使用u和U标识这两种类型
char16_t ch1 = u'q';
char32_t ch2 = U'/U0000222B';
  • 与wchar_t一样,char16_t和char32_t也都有底层类型——一种内置的整型,但底层类型可能随系统而变。

3.1.9 bool类型

  • bool值表示true或者false,C++中将非零值表示我true,零表示为false。
  • 任何数字或者指针都可以被隐式转换成bool值。

3.2 const限定符

  • 字符串常量可以使用define的预处理定义,也可以使用const修饰符定义字符串常量。

3.3 浮点数

  • 有小数类型的称为浮点数,对于浮点数,计算机将这样的值分为两部分存储,一部分表示值,另一个部分表示对值进行放大或缩小。由于放大缩小都是移动点的位置,所以称为浮点数,点的移动,缩放倍数是2的倍数。

3.3.1 书写浮点数

  • 浮点数的书写可以采用最常见的小数形式,也可以采用科学表示法。

3.3.2 浮点类型

  • C++有三种浮点类型:float、double和long double,三者的区别是能够表示的有效位数不同。
  • float至少32位,double至少48位,且不少于float;long double至少和double一样。

3.3.3 浮点常量

  • 书写浮点常量的时候通常默认是double的,如果像定义float的,则使用f或者F后缀。

3.4 算术运算符

  • 运算符就是常见的+,-,*,/等,算术运算符需要注意其结合的优先级,优先级不同则结合顺序不同。
  • 对于除法运算,如果两个操作数都是整数,将执行整数除法,小数部分将被省去。如果至少有一个是浮点数,则计算结果为浮点数,保留小数部分。
#include <iostream>
using namespace std;

int main() {
    int a = 10;
    int b = 3;
    cout << a / b << endl;
    float c = 3.0f;
    cout << a / c << endl;
    cout << typeid(a / c).name() << endl;
    double d = 3.0f;
    cout << a / d << endl;
    cout << typeid(a / d).name() << endl;
    auto e = 1.0;
    cout << typeid(e).name() << endl;
    cout << typeid(e / c).name() << endl;
}
输出
3
3.33333
f
3.33333
d
d
d

从上面的例子可以看到,当一方为float类型,另一方为整型时,计算结果为float类型。一方为double类型,另一方为整型时,计算结果为double类型。auto默认将浮点数设置为double类型。float和double类型运算结果为double类型。

  • 不同类型的数据在进行运算的时候会自动类型转换。也可以强制指定返回的数据的类型,强制转换的时候会采取截断读取,C++并没有定义结果应该是什么。
#include <iostream>
//#include <climits>
using namespace std;

int main() {
    char a {77};
    int b = a;
    char c = (char) b;
    char d = char (b);
    cout << a <<endl;
    cout << b <<endl;
    cout << c <<endl;
    cout << d <<endl;
    return 0;
}
输出
M
77
M
M
  • 强制类型转化可以有上面的两种格式。
  • C++中可以使用列表初始化的方式初始化变量。
#include <iostream>
using namespace std;

int main() {
    char a {77};
    cout << a << endl;
    return 0;
}
  • C++11中auto关键字能够使编译器根据初始值来推断变量的类型,但是一般都是用于比较复杂的类型,在简单类型中使用auto可能还会出错。

3.4.4 类型转换

C++将在一下情况下执行自动类型转换:

  • 将一种算数类型的值赋值给另一种算术类型的值时
  • 表达式中包含不同算术类型的值时
  • 将参数传递给函数时
    1.初始化和赋值进行的转换
    当将一种类型的值赋值给另一种类型时,值会被转换为接收变量的类型。将一个小的值赋值给大的数据类型通常不会导致什么问题,但将大的值赋值给小的数据类型的时候则会导致问题。
#include <iostream>
using namespace std;

int main() {
    short a = 39;
    int b = a;
    cout << a << endl;
    float c = b;
    cout << b << endl;
    float d = 3243.3243f;
    double e = d;
    cout << e << endl;
}
输出:
39
39
3243.32

小的数据类型向大数据类型转化的时候,通常不会有什么问题

#include <iostream>
using namespace std;

int main() {
    int a = 43243244;
    short b = a;
    cout << b << endl;
}
输出:
-10516

潜在问题出现了,通常会导致以下问题:

  • 较大的浮点数转换为小浮点数时,会丢失精度,也可能超出目标类型范围,结果不确定。
  • 浮点数转换为整数,小数部分丢失,也可能超出目标范围,结果不确定。
  • 较大整数转换为小整数,原来的值超出目标范围,截取右边的字节
    2、列表初始化转换
int x = 66;
char a {66};
char b {x}; //not allowed
char c {5435}; //not allowed

列表初始化时,会自动判断传入的数据是否能够储存,如果无法储存则会报错。x作为一个变量,编译器无法判断其值大小,所以编译无法通过。5435超过了char表示范围,也无法编译通过。
3、表达式中的转换
自动转换,在计算表达式时,C++将bool、char、unsigned char、signed char和short值自动转换为int类型,对于bool类型,true被转换成1,false被转换成0。

short a = 10;
short b = 10;
short c = a + b;

表达式中,a和b被转换成int类型,计算完成后赋值给short类型的c。
还有一些整型提升,如果short比int短,则unsigned short被转换成int类型,如果short和int一样长,则unsigned short被转换成unsigned int,确保数据不丢失。其他的类似wchar_t也是一样的,提升到能够存储其值的一个类型。
C++11校验表如下:

  • 如果一个操作数为long double,另一个操作数被提升为long double
  • 如果一个操作数为double,另一个操作数被提升为double
  • 如果一个操作数为lfloat,另一个操作数被提升为float
  • 否则,说明两个都是整型,则做整型提升
  • 如果两个都是有符号或者无符号的,如果其中一个类型更高,则另一个做类型提升
  • 如果一个有符号,一个无符号,且无符号级别高,则有符号数转换成无符号数
  • 如果有符号类型可表示所有无符号类型的取值,则无符号数转换成有符号数
  • 否则,将两个操作数都转换成有符号类型的无符号版本
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值