C++ Primer Plus学习笔记:第三章 处理数据

1.变量名

  • 大部分书里说的就不说了
  • 以两个下划线或者下划线和大写字母打头的名称,为保留实现的,不知道会出什么问题,反正不要用就最保险
  • C++对于名称长度没有限制,名称中的长度都有意义,但是在不同的平台上有不同的限制
  • ANSI C(C99)中只保证有63个字符有效,就是说你前63个字符一样,第64个不一样也会认为是相同变量

2.变量长度

类型 长度
short 至少16bit
int 至少和short一样长
long int 至少和int一样长
long long int 至少和long一样长

long long int和long int不一样长

C的数据类型符号常量

符号常量 表示
CHAR_BIT char的位数
CHAR_MAX char的最大值
CHAR_MIN char的最小值
SCHAR_MAX signed char的最大值
SCHAR_MIN signed char的最小值
UCHAR_MAX unsigned char的最大值
SHRT_MAX unsigned char的最小值
SHRT_MIN short的最大值
USHRT_MAX short的最小值
INT_MAX int的最大值
INT_MIN int的最小值
UNIT_MAX unsigned int的最大值
LONG_MAX long int的最大值
LONG_MIN long int的最小值
ULONG_MAX unsigned long int 的最大值
LLONG_MAX long long的最大值
LLONG_MIN long long的最小值
ULLONG_MAX unsigned long long 的最大值

上表的常量均定义在库中


3. 变量范围与越界

我们先说一下计算机中的原码,反码,补码
可以先想想在计算机中数字是怎么存储的,二进制存储的,比如我要存储数据15那么就是二进制1111,这个好办,但是如果要存储-15呢,好像没有-,那该怎么办呢,这是一种解决办法:

下图全部引用自《编码:隐匿在计算机软硬件背后的语言》
C++ Primer Plus学习笔记:第三章 处理数据_第1张图片
C++ Primer Plus学习笔记:第三章 处理数据_第2张图片
C++ Primer Plus学习笔记:第三章 处理数据_第3张图片
C++ Primer Plus学习笔记:第三章 处理数据_第4张图片

我们知道了计算机中的负数的表示方法就可以看数据范围与溢出了,我们先定义一个int t=INT_MAX;
然后t++;看看得到什么,变成了-INT_MAX了,这就是溢出。顺便说一下unsigned int,因为不用考虑负数所以少表示了INT_MAX的数据,可以一直往上接,所以可以做这么一个实验,unsigned int m=2INT_MAX;(UNIT_MAX=INT_MAX2)然后m++;看输出得到0;然后m++;得到1

整型字面值:

  • 八进制:以0开头第二位数字小于8那么就认为他是8进制数字
  • 十六进制:以0x或者0X开头的认为他是16进制数据

如何确定常量的类型:

cout<<1234;

如何确定1234的类型:

  • 如果编译器认为int可以存下而且没有特殊说明就默认int,否则自己判断
  • 如果有特殊说明的话就按特殊说明处理:如果整数后面加的是l或者L就认为是long常量,如果是u或者U就认为是unsigned int常量,ul不论顺序,都认为是unsigned int ,当然还有ull,Ull,uLL,ULL

顺便提一下,从上面负数的表示我们也就知道了,为什么对于同一个数据类型unsigned会比正常的表示范围大一倍


4. 各种数据类型

  • char类型是为了存储字符而设计的,但是他还是可以存储数字范围是-128~128(8个bit),不过他一般不用来存储数字。
    目前我们常用的是ASCII字符集但是不是说C++只能用ASCII字符集,还可以用例如国际Unicode码,不过一个byte的char是存不下的,所以我们需要更宽的wchar_t
    关于char的字面值:对于常规字符表示方法就是将字母用单括号引起来,而不需要去纠结系统使用的是什么编码方式。例如编程环境是ASCII,但是机器是Unicode,如果使用char t=‘a’;没有问题,但是如果使用的是a的ASCII那么就会出现混乱
  • 但是有些字符不能直接输出到程序上,所以需要转义字符,这里只写几个陌生的:
    退格,\b,这个的效果和键盘上的Backspace是不一样的,键盘上的backspace是删除字符前移光标,但是这个是只退光标不删除字符。
    振铃,\a,这个会让系统发出提示音,但是兼容性差可能不识别
  • wcha_t:对于英文来说char足够用了,但是对于汉字或者是日文来说,这远远不够,所以我们需要更大的char——wchar_t这个数据类型的大小和整型是一样的,但是是什么整型依赖于系统底层。
    有一点不爽的是cout/cin不认这个wcha_t,所以iostream为我们提供了另一个输出函数wcin/wcout他们可以用来处理wchar_t流,下面演示wcha_t的使用
wcha_t ss=L'p';
wcout<<L'e';

比char多了一个L,因为有这个标记所以系统会分配两个char的空间去存储这个p

  • bool类
    int转bool非0为true,0为false,但是如果你这样写
int a=10;
bool t=a;
cout<<int(t)

输出是1,一旦被bool转换,只要非0直接转化为1
还有就是bool的输出格式:

bool a=true;
cout<<a;

输出是1
想要输出true需要这样写

cout.setf(ios_base::boolalpha);
bool a=true;
cout<<a;

输出就是true,看一下cout.setf(ios_base::boolalpha);
首先是cout.setf(),就是ostream类下的cout对象的方法setf,参数是ios_base域下的boolalpha,实际上这个boolalpha是一个枚举,他对应了一个数值。

  • const:
    在c-的时候我们使用#define来使用预处理器的方法定义一个常量,现在我们使用const限定符,这样的好处是指定了数据的类型,更加“智能”,分别运行下面两个程序
#include 
#include 
#define primer a
using namespace std;

int main() {
     
	cout << a;
	return 0;
}
#include 
#include 
using namespace std;
const string a="primer";

int main() {
     
	cout << a;
	return 0;
}

第一个会报错,是因为#define只是简单地替换,cout不知道一个primer是什么,但是因为const有数据类型,所以可以轻易输出
const的另一个好处是他可以限定常量的作用于,最后一个是他可以应用于复杂的数据类型,比如结构体

  • 浮点数
    他可以表示小数,并且由于占用空间大,他也可以表示很大的数字,但是有一个精度问题,这与他的浮点有关,如果一个数组无法用long long 表示了就可以考虑这个,但是现在有了long long_128…
    浮点数有两种写法
    1.直接写比如123.21
    2.用科学技术法比如1.234e15,这个e后面的正是小数点偏移的位数,所以是’浮点’
    由于有了浮点,我们可以存储很大的数字,但是由于占用空间大小的问题,所以有效位数是有限的,要求是float至少32位,double至少64位,long double为80、96或者128位。另外,后三个的指数至少是-37~+37次。

关于有效位数的显示,使用了ostream类的setf()方法

std::cout.setf(std::ios_base::fixed, std::ios_base::floatfield);
std::cout.precision(3);

第一行是禁用科学计数法,第二行是规定小数点位数,注意了,和刚才说的一样,里面是一个枚举值,所以可以写一个int把设置存储下来,以后就可以直接用了。

然后写一下浮点常量,就是正常数字后面加F或者L(大写是为了字母数字分开)


5.算术运算符

就说一个取模运算和求余运算的区别
通常取模运算也叫取余运算,它们返回结果都是余数 唯一的区别在于:
当 x 和 y 的正负号一样的时候,两个函数结果是等同的;当 x 和 y 的符号不同时,rem 函数结果的符号和 x 的一样,而 mod 和 y 一样。
这是由于这两个函数的生成机制不同,rem 函数采用 fix 函数,而 mod 函数采用了 floor 函数(这两个函数是用来取整的,fix 函数向 0 方向舍入,floor 函数向无穷小方向舍入)。 rem(x,y)命令返回的是 x-n.*y,如果 y 不等于 0,其中的 n = fix(x./y),而 mod(x,y) 返回的是 x-n.*y,当 y 不等于 0 时,n=floor(x./y)
两个异号整数取模取值规律 (当是小数时也是这个运算规律,这一点好像与 C 语言的不太一样)
先将两个整数看作是正数,再作除法运算:
1、能整除时,其值为 0
2、不能整除时,其值=除数×(整商+1)-被除数


6.类型转化

在普通的类型转化中加宽缩窄是接受的,但是在{}初始运算符中确实不允许缩窄的例如char t {99};是不被允许的

  • 在传递参数的时候进行数据转化是可以的,
  • 强制进行类型转化
int a=int(123.33);
int b=(int)123.33;

其中后者是c-风格的,但是在c++中更希望是前者,这样就好像强制类型转化是一个函数,更符合OOP的思想
强制类型转化不会修改值的本身,而是新建了一个目标格式的副本,但是不用该滥用强制转换

  • 更严格的转化运算符:C++引入了四个更严格的符号转化符, static_cast(value)

你可能感兴趣的:(#,C++)