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"
- char16_t, 16bits,
- bool类型
- 非零值被解释为true, 零解释为false
- 任意数值或指针都可以被隐式转换为bool
- true可以被隐式转换为(int)1, false为(int)0
- 尽量使用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
- 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是安全的
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')
) - 再次输入
- 重置cin (
- 文件输出
- 包含头文件fstream
- 创建一个ofstream对象
- 将该对象与一个文件关联 (
ofstream.open()
) - 判断是否打开成功 (
ofstream.is_open()
) - 像使用cout那样使用ofstream对象
- 关闭文件 (
ofstream.close()
)
- 文件输入
- 同输出, ofstream -> ifstream
- 如果数据类型本身不是指针, 则可以将const数据或非const数据的地址赋值给指向const的指针
- 非const指针只能指向非const数据
- 使用const使得函数能够处理const和非const实参
- 满足以下措施之一的函数, 是内联函数
- 在函数声明前加上关键字inline
- 在函数定义前加上关键字inline
- 编译器将使用相应的函数代码替换内联函数的调用
- 节省了函数调用开销
- 占用更多内存
- 面向对象编程与传统的过程性编程的区别在于, OOP强调在运行阶段进行决策, 而不是编译阶段
- 当
&
符号在赋值左边时, 为引用, 否则为取地址 - 和类型连在一起为引用, 和变量在一起是取地址
- return *this返回的数据随返回类型而变化
- 如果返回类型是引用, 则返回当期对象
- 如果返回类型是当前对象的类型, 则返回一个当前对象的克隆
- return this返回指向当前对象的指针