大小端验证

  1. int c = 0xff000000; // 2个16进制数 = 1个byte
  2. unsigned char *pByte1 = &c;
  3. if(*pByte1 == 0xff){ // 低地址存储高位值,大端
  4. cout << "大端" << endl;
  5. }

内存对齐

针对类对象内部成员的内存地址对齐。

  • 对象大小必须是最大成员大小的整数倍。
  • 成员所在位置偏移量必须是成员大小的整数倍。
  • 虚函数表看成对象的一个指针放在对象的最前列,和对象地址相同。

比如,int是4个字节,必须放在偏移量是4的倍数的位置处,char是一个字节,可以随意存放。

include””和include<>

搜索目录不同。

  • include””
    • 优先搜索用户工作目录,然后在标准库位置搜索
    • 一般用于引入用户自定义的文件
  • include<>
    • 表示在标准(库)位置所搜文件。
    • 用于引入标准库文件。

为啥用补码表示负数

为了让满足-1 + 1 = 0。
补码 = 正数反码 + 1,
-1 + 1在内存上的表现如下:

  1. 1: 0 0 0 0 0 0 0 1
  2. + -1: 1 1 1 1 1 1 1 1
  3. -------------------------
  4. 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秒里面,又有新的字符传过来,那么这个字符将丢失。
    于是,研制人员想了个办法解决这个问题,就是在每行后面加两个表示结束的字符。一个叫做“回车”,告诉打字机把打印头定位在左边界;另一个叫做“换行”,告诉打字机把纸向下移一行。
    这就是“换行”和“回车”的来历,所以:
    \rcarriage return,回车,标记回到最左边界。
    \nline feed,换行,标记往下移一行。
    后来,计算机发明了,这两个概念也就被般到了计算机上。那时,存储器很贵,一些科学家认为在每行结尾加两个字符太浪费了,加一个就可以,于是,就出现了分歧。

  • Unix

    • 每行结尾\n(换行)。
  • Windows
    • 每行结尾\n\r(换行+回车)。
  • Mac
    • 每行结尾\r(回车)。

导致的后果:Unix/Mac系统下的文件在Windows里打开的话,所有文字会变成一行;而Windows里的文件在Unix/Mac下打开的话,在每行的结尾可能会多出一个^M符号。

++和—运算符

默认返回对象的拷贝,如++a返回的是a的拷贝,并不是a的指针或引用。

  1. ++a = 10; //返回a的拷贝,并不会使a = 10
  2. --a = 10; //返回a的拷贝,并不会使a = 10
  3. a++ = 10; //返回a的拷贝,并不会使a = 10
  4. a-- = 10; //返回a的拷贝,并不会使a = 10