大小端验证
int c = 0xff000000; // 2个16进制数 = 1个byte
unsigned char *pByte1 = &c;
if(*pByte1 == 0xff){ // 低地址存储高位值,大端
cout << "大端" << endl;
}
内存对齐
针对类对象内部成员的内存地址对齐。
- 对象大小必须是最大成员大小的整数倍。
- 成员所在位置偏移量必须是成员大小的整数倍。
- 虚函数表看成对象的一个指针放在对象的最前列,和对象地址相同。
比如,int是4个字节,必须放在偏移量是4的倍数的位置处,char是一个字节,可以随意存放。
include””和include<>
搜索目录不同。
- include””
- 优先搜索用户工作目录,然后在标准库位置搜索
- 一般用于引入用户自定义的文件
- include<>
- 表示在标准(库)位置所搜文件。
- 用于引入标准库文件。
为啥用补码表示负数
为了让满足-1 + 1 = 0。
补码 = 正数反码 + 1,
-1 + 1在内存上的表现如下:
1: 0 0 0 0 0 0 0 1
+ -1: 1 1 1 1 1 1 1 1
-------------------------
1 0 0 0 0 0 0 0 0 //高位的1超出范围,丢弃。得到结果0。
文本流、二进制流
《C和指针》书中指出,C中把流分为文本流和二进制流,两者不同仅仅在于:
- 对于文本流,标准规定了文本行的长度至少254个字符
对于文本流,在windows平台读写文件时,C会处理\n和\r\n的转换问题。
\r、\n、\r\n
在计算机还没有出现之前,有一种叫做电传打字机(Teletype Model 33)的玩意,每秒钟可以打10个字符。但是它有一个问题,就是打完一行换行的时候,要用去0.2秒,正好可以打两个字符。要是在这0.2秒里面,又有新的字符传过来,那么这个字符将丢失。
于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。
这就是“换行”和“回车”的来历,所以:
\r:carriage return,回车,标记回到最左边界。
\n:line feed,换行,标记往下移一行。
后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以,于是,就出现了分歧。Unix
- 每行结尾\n(换行)。
- Windows
- 每行结尾\n\r(换行+回车)。
- Mac
- 每行结尾\r(回车)。
导致的后果:Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。
++和—运算符
默认返回对象的拷贝,如++a返回的是a的拷贝,并不是a的指针或引用。
++a = 10; //返回a的拷贝,并不会使a = 10
--a = 10; //返回a的拷贝,并不会使a = 10
a++ = 10; //返回a的拷贝,并不会使a = 10
a-- = 10; //返回a的拷贝,并不会使a = 10