声明: 以下笔记是我在学习C++PrimerPlus的过程中,自己记录的知识点。所以选择了原创标签。不妥会改标签。
1. 初始化
a) 将赋值与声明合在一起
常规常量赋值或者INT_MAX;另一个变量或表达式赋值,条件是当程序执行到该声明时,表达式中所有值已知。
b) 符号常量——预处理方式
C++使用const. 但被设计成可用于C或C++的头文件,必须使用 #define.
整形变量的范围像里程表,如果超越了限制,其值将为范围另一端的取值。C++确保了无符号类型的这种行为,但C++并不保证符号整型超越限制(上溢和下溢)时不出错,而这正是当前实现中最为常见的行为。
c) 值得类型将引导cout(cin)选择如何显示 Eg. char int.
2. 成员函数 cout.put()——通过类对象cout来使用函数put()
C++ OOP概念:成员函数
类:定义了如何表示和控制数据
成员函数归类所有,描述了操纵类数据的方法
3. Unicode 和 ISO 10646
4. wcha_t 宽字符类型 ——表示扩展字符集
与底层(underlying)类型的长度和符号属性相同
5. 浮点常量在默认情况下为double类型
6. 操作符重载 EgP58
7. 递增递减操作符
副作用和顺序点:副作用:在计算表达式时对某些东西(如存储在变量中的值)进行了修改;
顺序点:程序执行过程中的一个点,在这里,进入下一步之前确保对所有的副作用都进行了评估。; 任何完整的表达式末尾都是一个顺序点 Eg. While (guest++<10) printf(“%d \n”, guest);
前缀格式和后缀格式(执行速度:对于类:前缀版本的效率比后缀高;对于内置类型,无区别;对于用户定义的且有用户定义的递增递减操作符的类型,前缀格式效率更高)
复合语句:在语句块中定义的变量,仅当程序执行该语句块中的语句时,改变量才存在。执行完该语句块后,变量将被释放。
逗号操作符:常见用途:将两个或更多的表达式放在一个for循环表达式中。C++提供另外两个特性:首先,确保先算第一个表达式,然后计算第二个表达式(逗号操作符是一个顺序点)。其次,逗号表达式的值是第二部分的值。且优先级最低。
8. C-风格字符比较:
C++将C-风格字符串视为地址,因此若使用关系操作符比较它们,将无法得到满意结果。应使用c-风格字符串库中strcmp()函数。P127
9. 编写延时循环:
intmain()
{
using namespace std;
cout << "Enter the delay time:";
float secs;
cin >> secs;
clock_t delay = secs * CLOCKS_PER_SEC;
cout << "Starting\a\n";
clock_t start = clock();
while(clock()-start < delay)
;
cout << "done \a\n";
return 0;
}
类型别名 #define BYTE char; typedef char byte;
10. 循环:
入口循环:for 、while(不知次数)
出口循环:do while(至少执行一次循环)Eg.请求用户输入时,程序必须先获得输入,然后对它进行测试。
11. C++原型与ANSI C:C++中括号()为空与在(void)等效,但在ANSI C中,括号为空意味着不指出参数(C++用(…));
原型的功能:编译器正确处理函数返回值;检查使用的参数数目是否正确;使用的参数类型是否正确,如果不正确,则转换为正确的类型。
C++自动将传递的值转换为原型中指定的类型,条件是两者都是算数类型。
参数argument:实参
参量parameter:形参
参数传递将参量赋给参数
12. 函数如何使用指针来处理数组
C++将数组名解释为其第一个元素的地址:cookies == &cookies[0]
Int sum_arr (int * arr, int n) 用int * arr替换了int arr[]
arr[i] == *(ar + 1)
&arr[i] == ar + I
将指针(包括数组名)加1,实际上是加上了一个与指针指向的类型的长度相等的值。对于遍历数组而言,使用指针加法和数组下标是等效的。
13. 指针和const
C++禁止将const的地址赋给非const的地址,除非使用强制类型转换来突破这种限制。
P200
假如涉及的是一级间接关系,则将非const指针赋给const指针是可以的:
int age = 39;
const int * pt =&age;
如果数据类型本身并不是指针,则可以将const数据或非const数据的地址赋给指向const的指针,但只能将非const数据的地址赋给非const指针。
禁止将常量数组的地址赋给非常量指针意味着不能将数组名作为参数传递给使用非常量形参的函数。
P201:
尽可能使用const: 避免由于无意修改数据而导致的编程错误;能处理const和非const实参,否则只能接受非const数据。
如果条件允许,应该讲指针形参声明为指向const的指针。
int sloth = 3;
const int * ps =&sloth; // a pointer to constint 不允许使用ps 来修改sloth的值,但允许ps指向另一个位置
int * const finger = &sloth; //a const pointer toint 允许使用finger来修改sloth的值,但只能指向sloth
声明指向const对象的const指针:
const double * const stick = &trouble;
stick只能指向trouble,而stick不能用来修改trouble的值。即,stick 和 *stick都是const。
14. 函数和结构:
可以将一个结构赋给另外一个结构。同样,也可以按值传递结构,就像普通变量那样。在这种情况下,函数将使用原始结构的拷贝。另外,函数也可返回结构。与数组名就是数组第一个元素不同,结构名只是结构的名称,要获得结构的地址,用&。C++还用&表示引用变量。
15. 函数和string 对象
P213
16. 递归
17. 函数指针
18. 函数模板 如果需要多个将同一种算法用于不同类型的函数,使用模板。如果不考虑向后兼容的问题,并愿意键入较长单词,用typename.
使用通用类型来定义函数;(仅参数类型不同,如何修改)
允许以任意类型的方式来定义函数。模板并不创建任何函数,只是告诉编译器如何定义函数。需要交换int/double类型的函数时,编译器将按模板模式创建这样的函数,并用int/double代替Any.
其中:template <classAny>
Or template<typename Any>
函数模板不能缩短可执行程序。最终P249仍由两个独立的函数定义,就像以手工方式定义了这些函数一样。最终的代码不包含任何模板,而只包含了为程序生成的实际函数。
重载的模板 并非所有类型都使用相同算法
像重载常规函数定义那样重载模板定义,被重载的模板的函数特征标必须不同。并非所有的模板参数都必须是模板参数类型。
19. 显式具体化
即具体化函数定义,包含所需的代码。当编译器找到与函数调用匹配的具体化定义时,将使用该定义,而不再寻找模板。——结构可以相互赋值,但若想交换结构中的某个成员?
C++标准定义:第三代具体化:
·对于给定的函数名,可以有非模板函数、模板函数和显式具体化模板函数以及它们的重载版本。
·显式具体化的原型和定义应以template<>打头,并通过名称来指出类型。
·具体化将覆盖常规模板,而非模板函数将覆盖具体化和常规模板。优先级
即:如果有多个原型,则编译器在选择原型时,非模板版本优先于显式具体化和模板版本。显式具体化优先于模板版本。
用于交换job结构的非模板函数、模板函数和具体化的原型:
// non-template function prototype
Void Swap(job &, job &);
//template prototype
Template <class Any>
void Swap(Any &, Any &);
//explicit specialization for the jobtype
Template<> void Swap<job>(job &, job&);
*早期的具体化方法为要处理的类型定义一个常规函数P253
20. 实例化和具体化(模板)
模板并非函数定义,使用int的模板实例(instantiation)是函数定义。——隐式实例化(implicit instantiation)
C++还允许显式实例化(explicit instantiation),即可以直接命令编译器创建特定的实例,如Swap<int>()。 template void Swap<int> (int, int);——使用Swap()模板生成int类型的函数定义
而显式具体化:
template<> voidSwap<int> (int &, int &);
template<> void Swap(int&, int &);——不要使用Swap()模板来生成函数定义,而应使用独立的、专门的函数定义显式地位int类型生成函数定义。
22. 编译器选择使用哪个函数版本
1). 完全匹配和最佳匹配难!!!!!!
函数模板的部分排序规则
2). 有多个参数的函数
23. 存储持续性、作用域和链接性
1.自动存储持续性:
常规局部变量、使用auto声名的局部变量、使用register声明的局部变量的存储持续性都是自动的,作用域是局部的,都没有链接性。
intmain()
{
shortwaffles;
auto short pancakes;
register int muffins; //变量通过使用CPU寄存器快速访问,没有内存地址。频繁使用
}
2.静态持续变量
数目在程序运行期间不变,程序不需要使用特殊装置(堆栈)来管理它们。编译器将分配固定的内存块来存储所有的静态变量,在整个程序执行期间一直存在。默认0