C primer plus - HsuJv/Note GitHub Wiki

第二章

进入C++

  • 注释
    • C风格: /* */
    • C++风格: //
    • 尽可能使用C++风格, 避免结束符与起始符的匹配问题
  • cout输出
    • cout << "Hello world";
    • c++中, 输出是一个流, 即从程序流出的一系列字符, cout对象表示这种流
    • 插入操作符 << 表示将右侧的信息插入到流中
  • 源代码风格
    • 每行一条语句
    • 每个函数都有一个开始花括号和一个结束花括号, 各占一行
    • 函数中的语句相对于花括号进行缩进
    • 与函数名称相关的圆括号周围没有空白

函数

  • using
    • using namespace std; 放在函数定义之前, 让文件中的所有函数都能使用名称空间std
    • using namespace std; 放在特定的函数定义中, 让该函数能使用名称空间std
    • 使用 using std::cout; , 让该函数能使用指定的元素, 如cout
    • 完全不用编译指令using, 使用前缀显示指明名称空间, 如 std::cout << "Hello, world";
  • 命名约定: 一般而言, 有以下几种选择
    • Myfunction()
    • myfunciton()
    • myFunction()
    • my_function()
    • my_funct()

第三章: 处理数据

简单变量

  • 变量名
    • 同C
    • 以两个下划线, 下划线和大写字母打头, 一个下划线开头的名称被保留
    • 长度无限制
  • short, int, long, long long
    • short >= 16 bits
    • int >= short
    • long >= 32 bits && long >= int
    • long long >= 64 bits && long long >= long
  • 位域
    • struct demo{unsigned a:1; unsigned b:0; char c; unsigned d:4};
    • 位域a占1位(+0至+0)
    • 空位域b强制使下一个成员对齐到下一字节, 所以b占7位(+1至+7)
    • 字符c占8位(+8至+15)
    • 位域d占4位(+16至+19)
    • 位域中数值的负数实现未定义.
  • 初始化
    • int a = 5;
    • int a(5);
    • 如果变量未初始化, 则根据其类型分为:
      • 全局变量: 存储在bss段, 将在程序使用时被初始化为0
      • 静态变量: bss, 0
      • 局部变量: 函数栈帧, 值不确定
  • 整形常量
    • 如果没有显示声明, 默认为int类型存储, 除非值太大
    • 后缀U表示unsigned int, 后缀L表示long, 后缀UL表示unsigned long
  • cout.put()
     #include <iostream>
     using namespace std;
    
     int main(){
         int i;
         char ch = 'M';
    
         i = ch;
         cout << "char :" << ch << "\tint: "  << i << endl;
         cout << "cout.put :";
         cout.put(ch);
         cout.put('\t');
         cout.put(i);
         cout.put('\n');
         return 0;
     }
    
    • 输出:
    char :M	int: 77
    cout.put :M	M
    
  • 通用字符名:
    • \u + 8个十六进制位, 或者\U + 16个十六进制位, 表示Unicode编码
  • 宽字符wchar_t (2 Bytes)
    • 使用wcout, wcin进行输出输入
    • 使用前缀L, 如 L"123"L'1'
    • c++11新类型:
      • char16_t, 16bits, u'c', u"123"
      • char32_t, 32bits, U'c', U"123"
  • bool类型
    • 非零值被解释为true, 零解释为false
    • 任意数值或指针都可以被隐式转换为bool
    • true可以被隐式转换为(int)1, false为(int)0

const限定符

  • 尽量使用const定义常量而不是#define定义符号常量
  • const常量一般用全大写字母命名
  • const常量应在声明时被初始化, 否则无法编译

浮点数

  • float, double, long double
    • float >= 32 bits
    • double >= 48 bits && double >= float
    • long double >= 64 bits && long double >= float
  • 浮点常量
    • 如果可以, 则存储为double
    • 后缀F表示float, 后缀L表示long double

第四章: 复合类型

string类简介

  • c++库扩展了string类, 因此可以使用string类而不是字符数组来存储字符串
  • string类在很多方面与字符数组相同:
    • 可以使用C风格字符串来初始化string对象
    • 可以使用cin, cout
    • 可以使用数组表示法来访问string
  • 赋值, 拼接和附加
    • 可以将string对象赋值给另一个string对象(深拷贝)
    • 可以直接使用 +, +=, 符号进行string的拼接
    • 相比较而言, 使用strcpy以及strcat等函数容易造成越界访问
  • C++11初始化
    • char demo1[] = {"demo1"};
    • char demo2[] {"demo2"};
    • string demo3[] = {"demo3"};
    • string demo4 {"demo4"}

结构简介

  • C++允许在声明结构变量时省略关键字struct (作用域内必须不包含与该结构体名同名的结构体变量)
  • C++不提倡使用外部变量, 但提倡使用外部结构声明
  • 初始化: struct demo a = { value1, value2, ...};

指针和自由存储空间

  • 使用new
    • malloc仍然可以使用
    • new typeName 将返回合适类型的地址值
    • new typeName [num] 申请数组
    • 内存被耗尽时返回0
  • 使用delete
    • free仍然可以使用
    • 一个new对应一个delete
    • 重复释放已经释放的内存块是未定义的
    • delete[]指明释放数组
  • 使用new和delete时:
    • 不要使用delete来释放不是new分配的内存
    • 不要使用delete释放同一内存块两次
    • 使用new[]为数组分配内存, 使用delete[]释放
    • 使用new为实体分配内存, 使用delete释放
    • 对空指针使用delete是安全的

第五章: 循环和关系表达式

Range-Based for Loop

  • int a[5] = {1, 2, 3, 4, 5};
  • 使用 for (int x: a) 可以循环遍历a数组中所有元素
  • 使用 for (int &x: a) 可以通过x修改a数组中元素
  • 同样的, for (int x: {1, 2, 3, 4, 5}) 也是合法语句

循环和文本输入

  • cin
    • cin在读取char值时, 与读取其他基本类型一样, 会忽略空白符号
    • 发送给cin的输入会被缓冲直至遇到回车
  • cin.get()
    • 约等于getchar()
    • __istream_type& cin.get(char*, int)
    • __istream_type& cin.get(char&)
  • EOF
    • cin.fail()
    • cin.eof()
  • 接受输入的变量类型和实际输入不匹配
    • int n; cin >> n; // actually "abc" is typed
    • n的值保持不变
    • 不匹配的输入将被留在输入队列中
    • cin对象中的一个错误标记被置位
    • 对cin方法的调用将返回false(或者0)
    • 解决:
      • 重置cin ( cin.clear() )
      • 删除错误输入( while(cin.get() 1= '\n') )
      • 再次输入

文件输入输出

  • 文件输出
    • 包含头文件fstream
    • 创建一个ofstream对象
    • 将该对象与一个文件关联 (ofstream.open())
    • 判断是否打开成功 (ofstream.is_open())
    • 像使用cout那样使用ofstream对象
    • 关闭文件 (ofstream.close())
  • 文件输入
    • 同输出, ofstream -> ifstream

第七, 八章: 函数

指针与const

  • 如果数据类型本身不是指针, 则可以将const数据或非const数据的地址赋值给指向const的指针
  • 非const指针只能指向非const数据
  • 使用const使得函数能够处理const和非const实参

内联函数

  • 满足以下措施之一的函数, 是内联函数
    • 在函数声明前加上关键字inline
    • 在函数定义前加上关键字inline
  • 编译器将使用相应的函数代码替换内联函数的调用
    • 节省了函数调用开销
    • 占用更多内存

引用

注释

面向过程与面向对象

  • 面向对象编程与传统的过程性编程的区别在于, OOP强调在运行阶段进行决策, 而不是编译阶段

引用和取址

  • & 符号在赋值左边时, 为引用, 否则为取地址
  • 和类型连在一起为引用, 和变量在一起是取地址

return this和return *this

  • return *this返回的数据随返回类型而变化
    • 如果返回类型是引用, 则返回当期对象
    • 如果返回类型是当前对象的类型, 则返回一个当前对象的克隆
  • return this返回指向当前对象的指针
⚠️ **GitHub.com Fallback** ⚠️