1. 类定义了行为

它为了说明”类定义了行为“,直接给出一个定义好运算符重载的类……有点跳跃

2. 算术类型

一个 int 至少和一个 short 一样大
一个 long 至少和一个 int 一样大
一个 long long 至少和一个 long 一样大
其实就是说
short ≤ int ≤ long ≤ long long

3. 内置类型的机器实现


4. 强制类型转换的规则

总的来说,范围大的和范围小的一起用,会转换为范围小的
无符号相对有负号是另一种意义上的范围小

5. 字面值的类型

6. 初始化

指定初值:xian
没有指定初值:默认初始化
制定列表{}:列表初始化

默认初始化:
定义在函数体外部的变量被初始化为 0
定义在函数体内部的变量将不被初始化

包含了显式初始化的声明即成为定义

要声明一个变量,在前面添加 extern,并且不显式初始化

变量能且只能被定义一次,但是可以被多次声明

7. 引用

引用不是对象,没有实际地址,所以不能定义指向引用的指针

8. 指针

初始化为 nullptr

9. 其他指针操作

对这句话的理解:
https://www.php.cn/wenda/70513.html

已知:end() 返回指向容器最后一个数据单元+1的指针

”指针指向另一个对象的下一个地址“不难理解,令人困惑的是,为什么非要说”下一个“,它有什么特殊含义吗?指针是有什么特殊操作可以在初始化的时候指向初始化右侧值得下一个地址吗?不是得。他其实是说,经过某一段程序之后,指针的地址可能会被多次修改,改到最后才等于”一个对象的下一个地址“

10. void*

和别的指针比较
作为函数的输入或输出
或赋给另外一个 void*

11. 理解复合类型的声明

int* p; 中,int 是基本数据类型,* 是类型修饰符,修饰 p 而不是 int
因此 int* p1, p2; 中,p1 是 int 类型的指针,p2 是 int,因为 * 只修饰了 p1

12. 指向指针的引用

13. const 限定符

const 的常量特征仅仅在执行改变本常量的操作时才会发挥作用,故初始化可以用 const 或其他

默认状态下,const 对象仅在文件内有效
想在多个文件之间共享 const 对象,必须在变量的定义之前添加 extern 关键字

14. 常量引用

常量引用实际上是对常量的引用

常量引用的引用对象不一定是常量

15. 初始化和对 const 的引用


类型转换时,编译器把代码变成:”赋值语句右值类型转换为临时值,临时值赋给赋值语句左值“
那么如果赋值语句的左值是非常量引用,那么他绑定的这个临时值之后,对这个非常量引用的修改,只会关联到对临时值的修改,这是没有用的,我们拿不到这个临时值。所以非常量引用的赋值语句右侧不能出现类型转换,也就是”非常量引用的类型必须与其所引用对象的类型保持一致“
但是常量引用没有关系,因为就算是绑定到了临时值,我也不修改常量引用,我只是读而已,读常量跟我这个常量引用绑定到哪里没有关系。所以”常量引用的类型不用与其所引用对象的类型保持一致“

16. 指向常量的XX 常量XX

指向常量的XX 即不规定所指的对象必须是一个常量,而是要求不能通过 XX 改变对象的值,自然,对象的值可能通过其他途径改变

常量XX XX本身不变

XX 指代指针或者引用

例外是,引用不是对象,所以不能规定引用自身不变,所以没有常量引用
但是把指向常量的引用简称为常量引用

const <T> &var //指向常量的引用 不能被用作修改他所绑定的对象
const <T> *var //指向常量的指针 不能被用作修改他所指向的对象
<T> *const var //常量指针 指针本身是常量

声明的理解:
1.从右往左读
2.const 修饰 const 出现地点左边的声明类型
3.如果左边没有声明类型,就修饰右边

17. 顶层 const

const <T> &var //指向常量的引用 不能被用作修改他所绑定的对象 底层 const
const <T> *var //指向常量的指针 不能被用作修改他所指向的对象 底层 const
<T> *const var //常量指针 指针本身是常量 顶层 const

初始化时,
非常量 左值 = 顶层 const 右值
底层 const 左值 = 底层 const 右值
底层 const 左值 = 非常量 右值
顶层 const 左值 = 顶层 const 左值
顶层 const 左值 = 底层 const 左值
顶层 const 左值 = 非常量 右值
啊……这样写……有点麻烦,毕竟是4*4的情况
我希望根据一些简单的原则来判断是否合法,比如,不能违背右值设定的原意什么的
因为“底层 const”意味着需要保证指向的对象是一个常量,如果把这个地址给一个别的非底层 const 的变量,就意味着有可能通过这个别的非底层 const 的变量更改指向的对象,这与保证冲突了。

如果不想死记的话,尝试通过 const 的约束判断赋值是否合法也行,因为这就是编辑器的做法
比如

const double pi = 3.14;
double *ptr = &pi;

不考虑规则,& 是取地址,pi 是常量,那么 &pi 就是一个指向常量的地址,但是左值是一个普通的地址
不能通过普通的地址改变作为常量的对象,所以这个赋值不合法

报错也就容易理解了

error: invalid conversion from 'const double*' to 'double*' [-fpermissive]double *ptr = &pi;

又比如,向顶层 const 左值的声明没有限制,因为我只是把右值作为左值指向的对象,不管右值有什么约束,我左值都不会动它,所以我左值来者不拒

18. 指针和 constexpr

constexpr 把它所定义的对象置为了顶层 const

19. 指针、常量和类型别名

20. 复合类型、常量和 auto

21. decltype 和引用

22. 头文件不应包含 using 声明

23. 直接初始化和拷贝初始化

直接初始化使用括号

24. getline

25. size_type 类型

26. 字面值与 string 对象相加

27. C++ 版本的 C 标准库头文件

28. 使用基于范围的 for 语句

for (declaration:expression)statement

循环变量定义成引用类型,这个变量实际上被依次绑定到了序列的每个元素上

这个是可以正常运行的

int my_array[5] = { 1, 2, 3, 4, 5 };// 不会改变 my_array 数组中元素的值
// x 将使用 my_array 数组的副本
for (int x : my_array)
{x *= 2;cout << x << endl;
}

但是这个就不可以

#include <iostream>
using namespace std;  void print(const int arr[10])
{for (auto num : arr){cout<<num;}return;
}
int main()
{const int arr[3] = {1,2,3};print(arr);
}

报错为

test.cpp: In function 'void print(const int*)':
test.cpp:6:21: error: 'begin' was not declared in this scopefor (auto num : arr)^~~
test.cpp:6:21: note: suggested alternative:
In file included from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:51,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:42,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,from test.cpp:1:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:105:37: note:   'std::begin'template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);^~~~~
test.cpp:6:21: error: 'end' was not declared in this scopefor (auto num : arr)^~~
test.cpp:6:21: note: suggested alternative:
In file included from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:51,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:42,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,from test.cpp:1:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:107:37: note:   'std::end'template<typename _Tp> const _Tp* end(const valarray<_Tp>&);^~~

改成了

#include <iostream>
using namespace std;  void print(int arr[10])
{for (auto num : arr){cout<<num;}return;
}
int main()
{int arr[3] = {1,2,3};print(arr);
}

还是一样的报错

我再稍微改了一下:

#include <iostream>
using namespace std;  void print(int arr[10])
{for (auto num : arr){cout<<num;}return;
}
int main()
{int myarr[10] = {1,2,3,4,5,6,7,8,9,10};print(myarr);
}

这个时候我确实能够看到,编辑器自己都能在我悬浮鼠标到 for 中的 arr 时联想到 int arr[10]

但是运行的时候他就是说没有

然后我有一个同学说 for range 不能用于静态数组,我改成了

#include <iostream>
using namespace std;  void print(int arr[])
{for (auto num : arr){cout<<num;}return;
}
int main()
{int myarr[10] = {1,2,3,4,5,6,7,8,9,10};print(myarr);
}

也还是不行

#include <iostream>
#include <iterator>
using namespace std;  void print(int arr[])
{for (auto num : arr){cout<<num;}return;
}
int main()
{int myarr[10] = {1,2,3,4,5,6,7,8,9,10};print(myarr);
}

也还是不行

#include <iostream>
using namespace std;  void print(int (&arr)[])
{for (auto num : arr){cout<<num;}return;}
int main()
{int myarr[10] = {1,2,3,4,5,6,7,8,9,10};print(myarr);
}

使用引用也不行

#include <iostream>
#include <vector>
using namespace std;  void print(vector<int> arr[])
{for (auto num : arr){cout<<num;}return;
}
int main()
{vector<int> myarr[10] = {1,2,3,4,5,6,7,8,9,10};print(myarr);
}

如果换成 vector,更可怕
报错如下

test.cpp: In function 'void print(std::vector<int>*)':
test.cpp:7:21: error: no matching function for call to 'begin(std::vector<int>*&)'for (auto num : arr)^~~
In file included from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:36,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:51,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:42,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,from test.cpp:1:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/initializer_list:89:5: note: candidate: 'template<class _Tp> constexpr const _Tp* std::begin(std::initializer_list<_Tp>)'begin(initializer_list<_Tp> __ils) noexcept^~~~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/initializer_list:89:5: note:   template argument deduction/substitution failed:
test.cpp:7:21: note:   mismatched types 'std::initializer_list<_Tp>' and 'std::vector<int>*'for (auto num : arr)^~~
In file included from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:51,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:42,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,from test.cpp:1:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:48:5: note: candidate: 'template<class _Container> decltype (__cont.begin()) std::begin(_Container&)'begin(_Container& __cont) -> decltype(__cont.begin())^~~~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:48:5: note:   template argument deduction/substitution failed:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h: In substitution of 'template<class _Container> decltype (__cont.begin()) std::begin(_Container&) [with _Container = std::vector<int>*]':
test.cpp:7:21:   required from here
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:48:50: error: request for member 'begin' in '__cont', which is of pointer type 'std::vector<int>*' (maybe you meant to use '->' ?)begin(_Container& __cont) -> decltype(__cont.begin())~~~~~~~^~~~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:58:5: note: candidate: 'template<class _Container> decltype (__cont.begin()) std::begin(const _Container&)'begin(const _Container& __cont) -> decltype(__cont.begin())^~~~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:58:5: note:   template argument deduction/substitution failed:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h: In substitution of 'template<class _Container> decltype (__cont.begin()) std::begin(const _Container&) [with _Container = std::vector<int>*]':
test.cpp:7:21:   required from here
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:58:56: error: request for member 'begin' in '__cont', which is of pointer type 'std::vector<int>* const' (maybe you meant to use '->' ?)begin(const _Container& __cont) -> decltype(__cont.begin())~~~~~~~^~~~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:87:5: note: candidate: 'template<class _Tp, long long unsigned int _Nm> constexpr _Tp* std::begin(_Tp (&)[_Nm])'begin(_Tp (&__arr)[_Nm])^~~~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:87:5: note:   template argument deduction/substitution failed:
test.cpp:7:21: note:   mismatched types '_Tp [_Nm]' and 'std::vector<int>*'for (auto num : arr)^~~
In file included from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:51,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:42,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,from test.cpp:1:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:104:31: note: candidate: 'template<class _Tp> _Tp* std::begin(std::valarray<_Tp>&)'template<typename _Tp> _Tp* begin(valarray<_Tp>&);^~~~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:104:31: note:   template argument deduction/substitution failed:
test.cpp:7:21: note:   mismatched types 'std::valarray<_Tp>' and 'std::vector<int>*'for (auto num : arr)^~~
In file included from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:51,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:42,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,from test.cpp:1:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:105:37: note: candidate: 'template<class _Tp> const _Tp* std::begin(const std::valarray<_Tp>&)'template<typename _Tp> const _Tp* begin(const valarray<_Tp>&);^~~~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:105:37: note:   template argument deduction/substitution failed:
test.cpp:7:21: note:   mismatched types 'const std::valarray<_Tp>' and 'std::vector<int>*'for (auto num : arr)^~~
test.cpp:7:21: error: no matching function for call to 'end(std::vector<int>*&)'
In file included from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:36,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:51,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:42,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,from test.cpp:1:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/initializer_list:99:5: note: candidate: 'template<class _Tp> constexpr const _Tp* std::end(std::initializer_list<_Tp>)'end(initializer_list<_Tp> __ils) noexcept^~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/initializer_list:99:5: note:   template argument deduction/substitution failed:
test.cpp:7:21: note:   mismatched types 'std::initializer_list<_Tp>' and 'std::vector<int>*'for (auto num : arr)^~~
In file included from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:51,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:42,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,from test.cpp:1:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:68:5: note: candidate: 'template<class _Container> decltype (__cont.end()) std::end(_Container&)'end(_Container& __cont) -> decltype(__cont.end())^~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:68:5: note:   template argument deduction/substitution failed:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h: In substitution of 'template<class _Container> decltype (__cont.end()) std::end(_Container&) [with _Container = std::vector<int>*]':
test.cpp:7:21:   required from here
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:68:48: error: request for member 'end' in '__cont', which is of pointer type 'std::vector<int>*' (maybe you meant to use '->' ?)end(_Container& __cont) -> decltype(__cont.end())~~~~~~~^~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:78:5: note: candidate: 'template<class _Container> decltype (__cont.end()) std::end(const _Container&)'end(const _Container& __cont) -> decltype(__cont.end())^~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:78:5: note:   template argument deduction/substitution failed:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h: In substitution of 'template<class _Container> decltype (__cont.end()) std::end(const _Container&) [with _Container = std::vector<int>*]':
test.cpp:7:21:   required from here
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:78:54: error: request for member 'end' in '__cont', which is of pointer type 'std::vector<int>* const' (maybe you meant to use '->' ?)end(const _Container& __cont) -> decltype(__cont.end())~~~~~~~^~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:97:5: note: candidate: 'template<class _Tp, long long unsigned int _Nm> constexpr _Tp* std::end(_Tp (&)[_Nm])'end(_Tp (&__arr)[_Nm])^~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:97:5: note:   template argument deduction/substitution failed:
test.cpp:7:21: note:   mismatched types '_Tp [_Nm]' and 'std::vector<int>*'for (auto num : arr)^~~
In file included from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:51,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:42,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,from test.cpp:1:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:106:31: note: candidate: 'template<class _Tp> _Tp* std::end(std::valarray<_Tp>&)'template<typename _Tp> _Tp* end(valarray<_Tp>&);^~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:106:31: note:   template argument deduction/substitution failed:
test.cpp:7:21: note:   mismatched types 'std::valarray<_Tp>' and 'std::vector<int>*'for (auto num : arr)^~~
In file included from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/string:51,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/locale_classes.h:40,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/ios_base.h:41,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ios:42,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/ostream:38,from D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/iostream:39,from test.cpp:1:
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:107:37: note: candidate: 'template<class _Tp> const _Tp* std::end(const std::valarray<_Tp>&)'template<typename _Tp> const _Tp* end(const valarray<_Tp>&);^~~
D:/Tools/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/c++/bits/range_access.h:107:37: note:   template argument deduction/substitution failed:
test.cpp:7:21: note:   mismatched types 'const std::valarray<_Tp>' and 'std::vector<int>*'for (auto num : arr)^~~
test.cpp: In function 'int main()':
test.cpp:16:50: error: conversion from 'int' to non-scalar type 'std::vector<int>' requestedvector<int> myarr[10] = {1,2,3,4,5,6,7,8,9,10};^
test.cpp:16:50: error: conversion from 'int' to non-scalar type 'std::vector<int>' requested
test.cpp:16:50: error: conversion from 'int' to non-scalar type 'std::vector<int>' requested
test.cpp:16:50: error: conversion from 'int' to non-scalar type 'std::vector<int>' requested
test.cpp:16:50: error: conversion from 'int' to non-scalar type 'std::vector<int>' requested
test.cpp:16:50: error: conversion from 'int' to non-scalar type 'std::vector<int>' requested
test.cpp:16:50: error: conversion from 'int' to non-scalar type 'std::vector<int>' requested
test.cpp:16:50: error: conversion from 'int' to non-scalar type 'std::vector<int>' requested
test.cpp:16:50: error: conversion from 'int' to non-scalar type 'std::vector<int>' requested
test.cpp:16:50: error: conversion from 'int' to non-scalar type 'std::vector<int>' requested

后来还是我朋友告诉了我正确的写法:

#include <iostream>
using namespace std;  void print(int (&arr)[10])
{for (auto num : arr){cout<<num;}return;}
int main()
{int myarr[10] = {1,2,3,4,5,6,7,8,9,10};print(myarr);
}

因为
对于局部变量,处理的过程为,int arr[N]arr : int[N],最后这个形参是一个数组,所以可以遍历
向形参 T[N] 传入的实参会被编译器扔掉长度,处理的过程为,int arr[N]arr : int[N],但因为一些历史原因就是 int*。最后这个形参赋为一个指针,所以不能遍历一个指针
向形参 reference_of(T[N]) 传入的实参会被编译器正确处理,处理的过程为,int (&arr)[N]arr : &(int[N]),最后这个形参赋为一个数组,所以可以遍历
reference_of(T[]) 是不完整类型,编译器不知道怎么编译它的 range-based for
指针根本没迭代器

历史原因是
C语言并没有“带有长度的数组”类型,C++才有
编译器认为,你要是用了C++特有的用法,那就默认认为你知道这个用法伴随着C++特有的带有长度的数组,你要是不用,为了兼容我就直接舍弃
所以~

29. vector 值初始化

两个特殊限制:
有些类要求必须明确地提供初始值
只提供元素数量而没有初始值,只能使用直接初始化


30. Vector 为空

31. Vector 的下标


31. 泛型编程

32. 二分查找习题

在 100 页的二分搜索程序中,为什么用的是 mis = beg + (end - beg)/2,而非 mid = (beg + end)/2

危险的是 *midmid 如果大于等于初始 end,就会下标溢出
要使得 mid 大于等于初始 end,对于 (beg + end)/2,需要 beg 大于等于 end
那么接下来看 beg 怎么来的。要获得最大的 beg,需要在循环体中一直执行 beg = mid + 1。如果要执行语句之后得到 beg == end,那么在执行语句之前就有 beg == end - 1,这表示,在执行语句之前,beg 已经是数组的末尾了,这个时候,最近一次判断的 *mid != sought 中的 mid 是否在末尾?最近一次判断中要得到 beg == end - 1,说明该次 mid == end - 2,即 mid 在倒数第二位,即最近一次循环结束后 beg == end - 1 的情况是存在的,它结束后由 (beg + end)/2 算出 mid == end - 1,在末尾,即循环结束后 beg == end 的情况是不存在的,因为在通过 beg = mid + 1beg == end 之前,已有 mid == end - 1,一定会判断到 *mid == sought(因为一直找到最后一个元素之前还没有找到目标值的话,那么最后一个元素一定是目标值)。也就是说,使用 mid = (beg + end)/2 不会出现下标溢出的情况。
后面搜索了才知道:
① 假设 begend 都很大,超过了 int 的一半,那么 beg + end 可能会溢出,这时候再除 2 也无济于事。而如果用 beg+(end-beg)/2 就不会溢出,因为 (end-beg) 不会溢出,除 2 更不会溢出,至于 beg+(end-beg)/2,这个加法肯定不会超过 end,所以也就不会溢出
② 支持迭代器相减操作却不支持相加操作

33. 定义和初始化内置数组

声明时,维度需要是一个常量表达式


34. 复杂的数组声明


35. 指针和数组

数组名称为数组的首地址

&arr[arrLength] 可以取到数组尾部之后的那个地址

36. 标准库函数 begin 和 end

因为 begin 和 end 不是数组的成员函数,所以要用他们来求数组的首指针和尾后指针时,要写成
begin(arr)
end(arr)

37. 数组的索引值的类型

38. C 风格字符串

字符串存放在字符数组中并以空字符结束

目标字符串的大小由调用者指定,存在安全风险

使用标准库 string 更安全高效

39. 与旧代码的接口


40. 多维数组

① 范围 for 遍历

② 迭代 for 遍历 1

③ 迭代 for 遍历 2 使用 begin end

④ 类型别名简化多维数组

41. 组合运算符和运算对象

优先级
结合律
运算对象的求值顺序

42. 运算对象转换

例外的是,小整数类型通常会被提升为较大的整数类型

43. 左值和右值

当一个对象被用作右值的时候,用的是对象的值(内容)
当一个对象被用作左值的时候,用的是对象的身份(地址)

区分左值与右值的便捷方法:看能不能对表达式取地址,如果能,则为左值,否则为右值

44. 求值顺序

优先级规定了运算对象的组合方式,但没有说明运算对象按照什么顺序求值
在大多数情况下,不会明确指定求值的顺序

对于那些没有指定执行顺序的运算符来说,如果表达式指向并修改了同一个对象,将引发错误并产生未定义的行为。

45. 处理符合表达式中函数调用顺序

46. 溢出和其他算术运算异常

47. 算术运算符 逻辑和关系运算符

求余运算的运算对象必须是整数类型

商一律向 0 取整(即直接切除小数部分)

48. 赋值运算符

赋值运算满足右结合律

49. 递增和递减运算符

后置递增运算符的优先级高于解引用运算符

运算对象可按任意顺序求值

50. 成员访问运算符

解引用运算符呃优先级低于点运算符

51. 位运算符

移位运算符(IO 运算符)满足左结合律

移位运算符比算术运算符的优先级低,比关系运算符、赋值运算符和条件运算符的优先级高

52. sizeof 运算符

返回一条表达式或一个类型名字所占的字节数

满足左结合律

sizeof 运算不会吧数组转换成指针来处理

53. 类型转换



54. 异常安全

55. 建议使用引用

https://blog.csdn.net/a3192048/article/details/84621775

56. 使用引用形参返回额外信息

一个引用形参可以用于返回一个值

57. 向函数传递参数的本质是定义一个形参

因此涉及到 const 那些东西,就看前面的那一个原则就好了

尝试通过 const 的约束判断赋值是否合法

58. 数组引用形参

之前的值传递参数的函数,书上说是编辑器会自动忽略掉形参第一个维度的要求

void print(const int arr[10]);

但是对于引用传递参数的函数,书上又说会限制传入的数组的长度

void print(int (&arr)[10]);

试了一下,确实如此hhh

#include <iostream>
using namespace std;  void print(int (&arr)[3])
{for (auto num : arr){cout<<num;}return;}
int main()
{int myarr[10] = {1,2,3,4,5,6,7,8,9,10};print(myarr);
}
test.cpp: In function 'int main()':
test.cpp:17:11: error: invalid initialization of reference of type 'int (&)[3]' from expression of type 'int [10]'print(myarr);^~~~~
test.cpp:4:6: note: in passing argument 1 of 'void print(int (&)[3])'void print(int (&arr)[3])^~~~~


这就是需要那个从右往左看的原则就可以弄明白
* 修饰变量就是说明这个变量名是地址,修饰类型就是说明组合起来是这个类型的指针

59. 含有可变形参的函数

所有的实参类型相同:initializer_list
实参的类型不同:可变参数模版
与 C 函数交互的接口:省略号

与 vector 不同的是,initializer_list 中的元素永远是常量

60. return

61. 返回值

初始化变量 = 初始化形参 = 返回值

不要返回局部对象的引用或指针

调用一个返回引用的函数得到左值,其他返回类型得到右值





判断两个形参的类型是否相异

#include <iostream>
using namespace std;  void print(int (&)[10]);void print(int (&arr)[10])
{for (auto num : arr){cout<<num;}return;}
int main()
{int myarr[10] = {1,2,3,4,5,6,7,8,9,10};print(myarr);
}

从这个例子可以看出,只要类型相同,不论参数名字

62. 调用重载函数

1.找到与实参最佳匹配
2.无匹配,错误
3.有多个匹配,但都不是最优,有二义性,错误

63. 重载与作用域

64. 默认实参

默认实参用于填补函数调用缺少的尾部实参
默认实参的右侧也都应该是默认实参

在给定的作用域中一个形参只能被赋予一次默认实参

局部变量不能作为默认实参

65. 内联函数

调用函数一般比求等价表达式的值要慢

66. constexpr

用于常量表达式
隐式指定为内联

可以返回空

67. 内联函数和 constexpr 的定义

内联函数和 constexpr 与普通函数不同,可以多次定义
内联函数和 constexpr 一般定义在头文件中,防止多次定义

68. 预处理宏

assert
预处理名由预处理器而非编辑器管理,所以不需 std::

69. 函数匹配

类型转换
const

70. 函数类型的指针

向函数类型的形参传入函数名实参,可以自动转化为指针
返回类型不会自动转换
也可用尾置返回类型
decltype 作用于某个函数时,它返回函数类型而非指针类型

71. 类

定义在类内部的函数时隐式的 inline 函数

this 是底层 const,初始化时,不能把它绑定到常量对象上
常量对象,以及常量对象的引用或指针都只能调用常量成员函数

现编译成员变量,再编译成员函数

72. 构造函数

合成的默认构造函数:
如果存在类内的初始值,用它来初始化成员
否则,默认初始化该成员

定义在块中的内置类型或复合类型的对象被默认初始化,则他们的值是无定义的

有时候编译器不能为某些类合成默认的构造函数
例如,如果类中包含一个其他类类型的成员且这个成员的类型没有默认构造函数

= default 需要默认的行为

构造函数初始值列表
类名(类型1 名1 …) : 成员变量1(表达式1) … {}
其中没有显示初始化的还是和合成默认构造函数相同地隐式初始化

在类的外部定义构造函数,使用命名空间
类名::类名 说明是构造函数

73. 拷贝、赋值和析构

某些类不能依赖于合成的版本
如一些管理动态内存的类,但是常被用于管理动态内存的 vector string 的合成版本可以正常工作

74. class 和 struct 的区别

75. 友元的声明

76. 类的其他特性

定义一个类型成员

重载成员函数

可变数据成员 mutable 即使是 const 对象的成员

类数据成员的初始值

返回 *this 返回调用该函数的对象的引用

从 const 成员函数 返回 *this

基于 const 的重载

声明类而不定义它 前向声明 此时是不完全类型
例外:需要先定义,其数据成员才能被声明为这种类类型,因为不知类的储存空间
但是只要出现了类名,就相当于出现了声明,不需要知道类的储存空间就可以定义指向这个类的引用或指针

类的友元函数 若定义在类的内部就是隐式内联
类的友元类
类的友元的其他类的函数

friend class 其他类的类名;

friend 类型名 其他类的类名::函数名(参数列表);

一组重载函数中的每一个需要单独声明友元

一个类就是一个作用域

函数的返回类型通常出现在函数名之前 dng成员函数定义在类的外部时,返回类型中使用的名字都位于类的作用域之外


类的定义的两个步骤进行完了也没找到,就继续找外层

77. 构造函数再探

如果成员是 const 或者是引用,必须初始化
成员属于某种类类型,且该类没有定义默认构造函数时,必须初始化

构造函数初始值列表不限定初始化的具体执行顺序 如果初始化的结果依赖于顺序,就……gg

默认实参的构造函数

委托构造函数


只允许一步类类型转换

对构造函数添加 explicit 以阻止构造函数的隐式转换,并且只允许直接初始化(使用圆括号)而不允许拷贝形式的(使用 =) 只用于一个参数的,多个实参的构造函数不能隐式转换,就不需要 explicit 只能在类内用 explicit

聚合类

字面值常量类

类的静态成员

static

只定义一次

静态成员可以是不完全类型,比如,就声明成他所属的类型
可以使用静态成员作为默认实参

78. IO 对象无拷贝或赋值

以引用方式传递和返回流
读写 IO 会改变其状态,故不能用 const

79. 查询流的状态

while(cin >> word)// ok:读操作成功...

4个 iostate 类型的 constexpr 值
系统级错误 badbit 被置位
可恢复错误 failbit 被置位
到达文件尾 eofbit failbit 被置位 goodbit = 0
badbit failbit eofbit 任一个被置位 => 检测流状态的条件失败
定义了一组函数查询这些标志位的状态
所有位均未置位 good 返回 true
bad fail eof 对应位被置位 返回 true
但 badbit 被置位时 fail 也返回 true

rdstate 返回 iostate 对应流的当前状态
setstate 对条件位置位
clear 一个不接受参数的版本 一个接受 iostate 的版本

80. 管理输出缓冲

flush 刷新缓冲区,但不输出任何额外的字符
ends 向缓冲区插入一个空字符,然后刷新缓冲区

unitbuf 接下来每次写操作之后都进行一次 flush
nounitbuf 重置流,使其恢复使用正常的系统管理的缓冲区刷新机制

cout 和 cin 关联

tie
第一个版本 无参数 返回指向输出流的指针 如果本对象关联到一个输出流,则返回指向这个流的指针;如果对象未关联到流,则返回空指针
第二个版本 接受一个指向 ostream 的指针 将自己关联到此 ostream 即 x.tie(&o)

每个流同时最多关联到一个流,但多个流可以同时关联到同一个 ostream
哦,就是说 ostream 是例外咯

ifstream 读取
ofstrean 写入
fstream 读写

读写一个文件 要定义一个文件流对象,并将对象与文件关联起来

对一个已经打开的文件流调用 open 会失败,导致 failbit 被置位


81. 文件模式



以 out 模式打开文件会丢弃已有数据
阻止清空的办法是同时指定 app 模式

82. 严格弱序

https://developers.weixin.qq.com/community/develop/article/doc/000aac56e48f40f8981a05b2c51013
为什么STL要这么设计——严格弱序(stick weak ordering) 我有明珠一颗

83. 咕了

麻了,好多,看不完,不能这么写了,咕了……

[C++] C++ Primer 笔记相关推荐

  1. C++Primer笔记——拷贝控制

    CHAPTER13-拷贝控制(C++ Primer笔记) 13.1 拷贝.赋值与销毁 13.1.1 拷贝构造函数 13.1.2 拷贝赋值运算符 13.1.3 析构函数 13.1.4 三/五法则 13. ...

  2. c++ primer 笔记 (二)

    第二章笔记  (貌似记得有点多)   把负值赋给unsigned对象时完全合法的,其结果是该负数对该类型的取值个数求模后的值   -1     (对265求模)  255 float型只能保证6位有效 ...

  3. C++Primer笔记-A003-decltype使用

    导言 此次笔记分为三部分介绍 typedef 基本使用与cpp11新特性 自动推演数据类型 decltype使用(主要集中介绍) typedef typedef使用方法很简单,就是为一个数据类型取一个 ...

  4. C++ Primer笔记——顶层const和底层const区别

    顶层const和底层const的区别 书中的定义: 顶层const(top-level const):表示指针本身是个常量. 底层const(low-level const):表示指针所指的对象是一个 ...

  5. Primer笔记——typedef指针类型别名时的const陷阱

    目录 一.typedef int* pint 与 const pint 二.typedef const int *pint 与 pint 三.总结 <C++ Primer>中指出,type ...

  6. c++ primer 笔记[20190406]

    P406 复制控制 不管类是否定义了自己的析构函数,编译器都自动执行类中非static数据成员的析构函数. 复制构造函数 C++支持两种初始化形式:直接初始化和复制初始化. 复制初始化使用=符号,直接 ...

  7. C++primer笔记之关联容器

    在这一章中,有以下的几点收获: 1.pair类型的使用相当频繁,如果需要定义多个相同的pair类型对象,可考虑利用typedef简化其声明: typedef pair<string, strin ...

  8. C++ Primer笔记12_运算符重载_递增递减运算符_成员訪问运算符

    1.递增递减运算符 C++语言并不要求递增递减运算符必须是类的成员.可是由于他们改变的正好是所操作对象的状态.所以建议设定为成员函数. 对于递增与递减运算符来说,有前置与后置两个版本号,因此.我们应该 ...

  9. C++ primer 笔记 (一)

    C++基本要素: 内置类型.库类型.类类型.变量.表达式.语句和函数 main函数是代码的入口,其返回值必须是int 类型(有时为void),其返回值是一个状态指示器,返回值为0,则表示函数成功执行完 ...

  10. C++Primer笔记-----day04

    1.函数指针. 函数指针指向某种特定类型,函数的类型由它的返回类型和形参类型决定,与函数名无关. 比如:bool lengthCompare(const string &,const stri ...

最新文章

  1. 讯飞语音:客户端未被授权
  2. 网上商城代码实现_中国中铁网上商城转型敏捷开发模式,实现快速反应、快速迭代...
  3. 9种设计模式在Spring中的运用,一定要非常熟练!
  4. android 加载器loader详解
  5. Deseq的理论基础
  6. 在现有k8s集群中安装kubesphere时报错:metrics-server failed
  7. java调用webservice_笃学私教:Java开发网站架构演变过程-从单体应用到微服务架构详解...
  8. 从客户端检测到有潜在危险的Request.Form 值
  9. python 社区网络转化_python-将numpy打开网格转换为坐标
  10. 净水器怎么放_今日头条 | 如何清洗净水器的陶瓷滤芯,要不要来学一下!
  11. docker hub push_Docker系列-(2) 镜像制作与发布
  12. 谷歌浏览器开发调式工具文档
  13. 《软件定义数据中心:Windows Server SDDC技术与实践》——第1章 微软数据中心与SDDC漫谈1.1 微软数据中心建设之道...
  14. apache配置文件“注解内容”全翻译
  15. 视频剪辑入门技能快速分享
  16. 魔兽世界开服一条龙服务端架设服务器搭建
  17. 计算机软件研究方法与技术路线,开题报告研究方法与技术路线.doc
  18. H264---码率控制---CBR、VBR、ABR、CVBR四种编码方式
  19. poi XWPFDocument 实现word中内容换行
  20. AirServer2023免费无线Mac和PC电脑屏幕镜像投屏工具

热门文章

  1. 总结一些生物成像的 开源图像与插件网站
  2. YurunOAuthLogin v2.0.2,第三方 OAuth2 授权一把梭
  3. BZOJ4810:[YNOI2017]由乃的玉米田(莫队,bitset)
  4. WinDbg 命令三部曲:(二)WinDbg SOS 扩展命令手
  5. 『原创』.Net CF下ListView的数据绑定
  6. maven 多仓库和镜像设置
  7. 自定义behavior-仿华为应用市场
  8. Linux rsyslog 转存至日志服务器
  9. 系统安全:Nessus Home版安装使用
  10. 表likp新增第一次过账输入日期字段,vl02n/vl01n/vl03n/vl06o的增强