1.原码、反码、补码
正数(包括+0):原=反=补
负数:反=原(除了符号位)取反,补=反+1
二进制在计算机中以补码的形式存在(原因在于0的表示):
若0用原码表示:
1)表示方法不唯一:0000 0000 或 1000 0000
2)计算结果错误:0=1-1=1+(-1)=0000 0001+1000 0001=1000 0010=-2
若0用反码表示:
1)表示方法不唯一:0000 0000 或 11111 1111(负0原码1000 0000除符号位取反)
2)计算正确:0=1+(-1)=0000 0001+1111 1110=1111 1111,
对其取反求原码:0000 0000, 即0
若0用补码表示:
1)表示方法唯一:0000 0000(负0:1000 0000取反1111 1111+1=0000 0000),
2)计算正确:0=1+(-1)=0000 0001+1111 1111=000 0000,
求原码:取反+1=1111 1111 + 1 = 0000 0000
2.常见算法类型所占内存大小
char: 1字节
wchar_t: 2字节 (宽字符型)
int: 2字节
short: 2字节
long:4字节
float:4字节(1bit符号位+8bit指数位+23bit尾数位)
int表示范围:-128-127
1000 0000(-128的补码) - 01111 1111
3.当赋值一个超出范围的值时,结果是该赋值对该类型的取值个数求模后的值
如给unsigned char赋值336, 结果为: 336 % 256 = 80
给unsigned char赋值-1,结果为:1111 1111(补码) % 256 = 255
4.float类型的存储表示
指数部分的存储采用移位存储:+127
如8.25,二进制表示为:1000.01,用科学记数法表示:1.00001 * 2^3,即指数部分为:3,小数部分为0.00001.
指数部分的存储为:3+127=130,即1000 0010,小数部分为00001
所以在计算机中的存储为:0(符号位) 1000 0010(指数位) 0000100…0(23位小数)
5.float类型至少能够保证6位有效数字(C++ Primer中说),查了查也有说7位的,不太理解.
6.初始化的方式及与赋值的区别
初始化方式:
1)复制初始化int ival = ‘1024’
2)直接初始化int ival(1024), string all_nines(10, ‘9’),结果:‘9999999999’
初始化与赋值的区别:
初始化:创建对象、赋初始值
赋值:擦除对象的当前值、用新值代替
7.函数体外定义的变量默认初始化为0,而函数体内定义的内置类型变量不会自动初始化.
8.声明(extern)与定义
1)定义是声明,但声明不一定是定义(若声明有初始化式,那么可以被当作是定义).
2)定义:用于为变量分配存储空间,还可以为变量指定初始值.在一个程序中,变量有且只有一次定义.
eg: int I;
声明:用于向程序表明变量的类型和名字.当变量定义时,我们声明了它的类型和名字,可以通过extern关键字声明变量名而不是定义它.
eg: extern int I;
3)extern声明不分配存储空间,它只是说明变量定义在程序的其它地方.程序中变量可以声明多次,但只能定义一次.
4)只有extern声明位于函数外部时,才可以有初始化式(而普通的定义不一定在函数外).
理解:有初始化式的extern相当于定义,而在程序中变量可以声明多次,但只能定义一次.如果在函数内部定义,那它的作用域为该函数内部.在函数外,对该变量进行声明时不产生任何作用的,即不能用函数内声明的变量.
extern double pi = 3.1415; // 定义
double pi; // 重复定义,函数外定义变量默认初始化为0
extern double pi; // 声明
extern double pi = 3.1415 // 重复定义
5)任何在多个文件中使用的变量都需要有与定义分离的声明.在这种情况下,一个文件中有变量的定义,其它使用该变量的文件包含该变量的声明.
9.const
在全局作用域中声明的const变量是定义该对象的文件的局部变量,此变量只存在于那个文件中,不能被其它文件访问.通过指定const变量为extern,就可以在整个程序中访问const对象.
// 错误代码.bufsize不能在file2.cc中使用.
// file1.cc
const int bufsize = 100;
// file2.cc
const int bufsize;
for (int i=0; i<bufsize; i++){
...
}
// file_1.cc
extern const int bufsize = fcn();
// file2.cc
extern const int bufsize;
for (int index = 0; index != bufsize; ++index){
...
}
注:非const变量默认为extern.要使const变量能够在其它文件中访问,必须显式的指定它为extern.
10.引用(&)
引用即别名.当引用初始化后,只要该引用存在,它就保持绑定到初始化时所指向的对象,不可能将引用绑定到另一个对象.
const int ival = 1024;
const int &reival = ival;
int &refinval2 = ival; // 错. 非const不能引用一个const常量,防止const对象被修改
非const引用只能绑定到与该引用同类型的对象;const引用可以绑定到不同但相关的类型的对象或绑定到右值.
// const引用,正确代码
double dval = 3.14;
cosnt int &ri = dval;
// 正确代码
int i=42;
const int &r = 42;
const int &r2 = r + i;
//错误代码
const int m = 10;
int &n = m;
// 编译器会把上述代码转换为:
const int temp = m;
int &n = temp;
// 修改n,但是m不会更改,所以非const类型不能作为const对象的引用
11.typeof用来定义类型的同义词
目的:1)隐藏特定类型的实现,强调使用类型的目的
2)简化复杂的类型定义,使其容易理解
3)允许一种类型用于多个目的,同时使得每次使用该类型的目的明确
12.enum枚举定义整数常量集,并把它们聚集成组
枚举成员本身是一个常量表达式,不能改变枚举成员的值.
// 默认第一个枚举成员赋值为0,后面的每个枚举成员的值比前面值大1
// 即input = 0, output = 1, append = 2
enum open_modes{input, output, append}
// 后面的每个枚举成员赋值比前一个值大1
// 即 sphere = 2, cylinder = 3, polygon = 4
enum forms{shape = 1, sphere, cylinder, polygon}
每个enum都定义了一种唯一的类型,枚举类型的对象初始化或赋值只能通过其枚举成员或同一枚举类型的其它对象来赋值.
Points pt3d = point3d;
// 错误,不能用int类型初始化
Points pt2w = 3;
Points pt2w = pt3d;
13.struct与class
默认情况下,struct的成员为public,class的成员为private,其他无区别
14.头文件
头文件包含类的定义、extern变量的声明、函数的声明.
头文件用于声明而不是用于定义,因为只能定义一次,可以声明多次,如果头文件包含在多个源文件中,则违背了定义一次的原则.
例外:头文件可以定义类、值在编译时就已知道的const对象、inline函数
15.预处理器
16.预处理器变量
预处理器变量经常用大些字母表示,且名字在程序中唯一.
#define 指定接受一个名字并定义该名字为预处理器变量
#ifndef 指示检测指定的预处理器变量是否未定义
// 测试SALESITEM_H预处理器是否未定义,如果SALESITEM_H未定义,那么#ifndef测试成功,跟在#ifndef后面的所有行都被执行,直到发现#endif.相反,如果SALESITEM_H已定义,那么#ifndef指示测试为假,该指示和#endif指示间的代码都被忽略.
# ifndef SALESITEM_H
# define SALESITEM_H
...
# endif
//表明该头文件为标准头文件,在预定义的位置集查找该文件
#include
// “ ”为非系统头文件,即用户自己写的文件,查找该头文件通常开始于源文件所在路径
#include "my_file.h"