每周100个C++知识点(备忘录)(二)

001-017 选择分支结构

1.if语句实现选择操作,语法是if (test-condition) statement,其中statement要么是一条语句,要么是{}括起来的一个语句块

2.test-condition被强制转换为bool值,0转换为false,非零为true

3.if语句的拓展还有if-else语句和if-else if-else语句。需要注意的是,在test-condition内,“相等”是"==“而不是”=",一般"="并不会造成程序编译不通过,但是会生成警告

4.逻辑表达式有或:||;与:&&;非:!。||、&&的运算顺序是从左至右,因此i++ < 6 || ij,假设i=10,则右侧比较的是11j是否成立;对于||,当第一个条件为true时,不对第二个条件进行判定,对于&&,当第一个条件为false时,不对第二个条件进行判定

5.在进行范围处理时,应当注意不能使用数学运算思维,因为17<age<35,被解释为(17<age)<35,不管age的值为多少,17<age总是小于35,因此整个逻辑表达式的值为1。正确的表达是age>17 && age<35

6.!是取反操作。可以使用头文件climits,它定义了符号常量INT_MAX和INT_MIN

7.优先级:①||和&&的优先级都低于关系运算符;②!运算符优先级高于所有关系运算符和算数运算符,因此使用!时一般需要将后面的表达式括起;③&&运算符的优先级高于||运算符的优先级

8.C++也提供了and/or/not的表达,分别替换&&/||/!

9.字符函数库cctype提供了:①isalpha(char)判断char是否为字符;②ispunct(ch)判断ch是否为标点;③如果满足条件,则返回一个非零值,否则返回0。这个库的意义在于,可以用if (!isalpha(ch))代替if ((ch>=‘a’&&ch<=‘z’) || (ch>=‘A’&&ch<=‘Z’));且第一种方法更通用,因为第二种方法是假设ASCII编码的前提下才使用的

10.cctype中的字符函数有:①isalnum()判断数字;②isalpha()判断字母;③iscntrl()判断控制字符;④isdigit()判断0-9;⑤isgraph()判断打印字符除空格;⑥islower()判断小写;⑦isprint()判断打印字符包括空格;⑧ispunct()判断标点;⑨isspace()判断空格回车制表符等;⑩isupper()判断大写;11.isxdigit()判断十六进制;12.tolower()如果大写字母,返回小写字母否则返回参数;13.toupper()如果小写字母,返回大写字母否则返回参数

11.条件运算符(?:):expression1 ? expression2 : expression3,如果表达式1为true,则返回表达式2的值,否则返回表达式3的值。这个表达式可以代替if else表达式

12.switch语句的格式是:switch (integer-expression){ case label1 : statement(s);break; case label2 : statement(s);break; … default : statement(s)}

13.C++中的switch,如果没有break,则会执行跳到某行后的所有内容,因此break;是需要的(对绝大多数操作来说,不然使用switch的意义何在?);但是,对于一些操作,如根据输入字母而不管大小写来进行判断,则可以case ‘a’ : case ‘A’ : statement(s);break;

14.使用枚举作为switch的判断条件,程序在编译时会将枚举量提升为int,在while等判断时也会将枚举量提升为int(书6.11)

15.选择使用switch和if else:如果遇见浮点型操作、范围操作,则选择if else为好;需要进行选择操作时,尤其是选项超过2个时,switch效率更高

16.break语句用在上述情况或任何循环中,可以让程序跳到switch或循环后面的语句处继续执行;continue语句用在循环中,让程序跳过循环中的余下代码并开始新的一轮循环

17.对于while循环,使用continue可能存在隐患:如果使用continue语句,则程序有可能跳过控制变量的更新,这样会导致死循环或其他错误

018-026 EOF和文件读写

18.cin.fail()判断是否成功读取下一个内容,cin.fail()==false意味着成功读取;还可以将读取成功直接写为:while (cin),因为cin返回一个bool值;且cin.get(ch)的返回值为cin

19.假设n是整形,则cin >> n时,若n的类型错误或检测到文件尾EOF,则cin返回false

20.对于错误信息的处理办法:首先要cin.clear()重置输入;然后要读取最后一句剩下的内容,读完为止

21.cin对于输入,会采取不同的办法进行读入,转换为相应的类型,进而利用。一般程序的控制台输入都是文本输入,所以可以通过文本I/O来从文件直接读写

22.文件写入,需要包含头文件fstream,创建一个ofstream对象,将该对象和一个文件关联起来(使用open()),然后就可以像使用cout一样使用方法

23.cout.precision(x);以及outFile.precision(x);设置了输出数据的保留精度

24.打开文件时,如果文件存在且有内容,则默认操作是:截断文件,即丢掉其原有内容,将新的输出加入该文件中,以后会介绍修改该默认行为

25.文件读取,需要包含头文件fstream,创建一个ifstream对象,将该对象和一个文件关联起来(使用open()),然后就可以像使用cin一样使用方法

26.如果试图打开一个不存在的文件,会导致后续使用ifstream对象失败,检查文件是否成功打开的方法是is_open(),检查语句是:if (!inFile.is_open()) {exit(EXIT_FAILURE);};其中符号常量EXIT_FAILURE定义在cstdlib中

027-058 函数基础

27.使用C++函数需要:①提供函数定义;②提供函数原型;③调用函数

28.函数的定义有两类:①第一类是无返回值的函数,格式是void functionName(paramenterList) {statement(s) return;};②第二类是有返回值的函数,格式是typeName functionName(parameterList) {statement(s) return value;}

29.C++函数的返回值不可以是数组;但是可以是结构、对象等数组以外的其他内容,因此可以将数组放在结构或对象中返回

30.函数原型的作用:描述了函数到编译器的接口,它将函数的返回值类型和参数的类型告诉给编译器;要么需要在main()使用函数前定义它,要么必须提供函数原型,因为将main()放在开头是C++的编程风格

31.函数原型是一条语句,使用分号结束;原型不要求提供变量名,如果存在变量名,则它的作用只是占位符,与函数定义中的变量名不必相同

32.函数原型的作用是确保编译器正确处理函数返回值;编译器检查使用的参数数目是否正确;编译器检查使用的参数类型是否正确,如果不正确则强制类型转换

33.C++标准中,用参数argument表示实参,用参量parameter表示形参,函数调用时参数传递,将参数赋给参量

34.函数可以有多个参数,调用时将他们用逗号分隔即可。函数声明中必须声明每个变量的类型,函数原型中可以不给各个参量命名,但是必须写其类型。比如void f_a(float ,float);是可以的,但是最好给相同的类型命名来进行区分

35.数组作为参数传递给函数时,传递的实质是数组的地址,即C++函数将数组名视为指针。在函数原型中,表达方式int name(int * arr)和int name(int arr[])是等价的,但是在其他上下文中并不等价,一般用第二种方式表达数组,第一种方式可以表达单个值

36.数组参数传递的其实是一个地址,函数通过访问该地址达到传递数组的作用。但传递的只是一个地址,因此需要显式地传递数组的大小

37.传递进函数的数组,依然可以遍历访问,对于不能修改的只读数组,可以在函数原型和声明中使用const修饰;对于可以进行修改的数组则不需要const修饰

38.如果要使用数组的某一区间,可以进行指针算数,比如取第4到7位,可以在函数原型中将函数写为type f_name(begin,end);,使用时用type=f_name(arr+3,arr+6)

39.const有两种使用方法,第一是将const指向一个常量对象,这样可以防止使用指针来修改指向的值;二是将指针本身声明为常量,这样可以防止改变指针指向的位置。声明方法是:const type * name=x;和type * const name=x;

40.const变量的地址可以赋给const指针,而const变量的地址不可以赋给常规指针

41.在函数声明中使用const意味着函数不能修改传递给它的数组中的值,用以保护数组;如果数组元素是指针,或者是指向指针的指针,则不可以用const

42.二维数组作为参数,传递的也是一组指针,因此可以这样声明:type f_name(type arr_name[][n],int size),这里声明了一个sizen大小的二维数组,等价于type f_name(type ( arr_name)[n],int size),这里和上述声明是等价的

43.C风格字符串作为参数传递,和char数组、字符常量、char指针地址是等价的,也就是都传递指针,但是并不需要字符串的结尾是’\0’

44.C风格字符串作为返回值传递,返回的是字符串的地址,也就是在函数中生成一个字符串,返回它的地址,再直接访问该字符串的地址。但是在建立完该字符串后,需要删除原来的指针★★★

45.结构作为参数传递,可以通过地址传递(要利用&取地址符),但是C++的结构也可以作为一个常规变量进行传递,因此可以直接像int等类型进行参数传递(当结构比较小时,如果结构较大,还是可以通过指针来进行传递)

46.传递结构的地址作为参数时需要注意:①调用函数时将函数的地址而不是结构本身传递给它;②形参声明为指向结构的指针,在不需要改变结构的值时,使用const修饰符修饰;③形参是指针不是结构,因此使用->而不是句点进行结构的访问;④指针的效率高,因此可以不返回值,即只改变指针指向地址的内容

47.string类型可以作为一个整体传递给函数,也可以作为函数的返回值,需要用#include 调用,但是注意别忘了需要std::string或Using命令

48.array的这一块儿留给第八章☆★☆★☆★🐀🐂🐅🐇🐉🐍🐎🐏🐒🐓🐕🐖

49.递归:C++不允许main()递归调用自己;一般递归需要一个if条件来确定断开调用链,每一次循环时的变量相互独立,且每一层的独立变量在递归前后的地址相同

50.多层递归:一般在针对左右分治的程序时,选择左右多层递归方法比较方便,如7.17

51.函数指针:可以将函数指针(函数的地址)作为参数传递给函数,这样一个函数可以调用另一个函数,允许在不同的时间传递不同函数的地址,使用不同的函数

52.函数指针的使用步骤:①获取函数的地址(直接使用函数名称,例如address是函数名称,这里也就是函数的地址,而address()是函数的返回值;②声明一个函数指针;③使用函数指针来调用函数

53.函数指针原型:type (*pointer_f_name)(parameter type);p_f_name是函数,p_f_name就是函数的指针。需要注意的是和括号的位置,如果没有括号,则声明了一个返回指针的函数

54.在使用函数指针时,本来的方法时(*pfname)(x),但也可写成pfname(x)。即(*pfname)代表了函数

55.auto使用在单值初始化,而不能用在列表初始化中。但声明数组后,就可以再使用auto规定其他数组类型

56.假设函数原型是:const double ((*pd)[3])(const double , int);则pd指向数组,则pd就是数组,而(pd)[i]是数组中的元素,也就是函数指针,调用函数可以是(pd)i(pd)i是返回的指针指向的值;还可以用((pd)[i])(param,3)来调用函数,((*pd)[i])(param,3)是指向的值

57.对56中的函数进行声明时,需要这样做:const double ((*pd)[3])(const double *, int)=&pa,&运算符在后文讨论,它的区别是,pa是数组的地址,也是第一个元素的地址,而&pa是整个数组的地址,也就是说pa是1单位字节,而&pa是3单位字节

58.对函数声明进行化简的两种方式:①使用auto进行标识;②使用typedef将复杂类型起个简单别名

059-060 内联函数

59.类似于C语言中的宏,在调用函数的过程中将源代码与调用关联起来。一般要求是,需要函数并不复杂,如果函数有多行,则不建议声明为内联函数

60.内联函数的声明多加一个inline标识符,即inline type f_name(param_type param_name);。内联函数不可以递归调用。使用内联函数可以在一定程度上提高程序效率

061-083 引用变量

61.引用变量是已定义的变量的别名。引用变量的主要用途是用作函数的形参,函数将使用原始数据而不是副本

62.引用变量的声明:使用&运算符,例如将rodents声明为rats的引用变量:int rats; int & rodents=rats;但是&不是取地址符。rats和rodents指向相同的值和内存单元

63.引用变量和指针:int rats=1; int &rodents=rats;int *parts=&rats;则rats可以和rodents、*parts互换,&rats可以和parts、&rodents互换。差别是,声明引用时就必须将其初始化,而声明指针时则不需要

64.当引用变量发生变化时,其原来变量也会发生相同的变化

65.引用作为函数参数传递时,使得函数中的变量名成为调用程序中的变量的别名,按引用传递允许被调用的函数能够访问调用函数中的变量

66.例子:比如交换两个变量的值,如果只是按值传递参数,则函数将交换两个变量的副本;方法一是通过引用变量,直接操作原始数据;方法二是通过使用指针,来访问原始数据

67.引用变量会改变内存中的值,因而改变main()函数中的值,所以如果需要让函数使用引用,又不对这些信息进行修改,则应该使用常量引用,声明方式是type name(const type name);

68.一般的值传递函数,不要用引用方式,但当数据比较大(结构和类)时,引用参数很有用

69.对于引用参数,调用时应当使用变量名,而不可以用常量,因为常量没有”别名“,也就是可以用&a=b;拿a来表示b,但是不可以&a=5;后者并不是一个变量。要这样表示的话,则必须使用const修饰符,具体原因和方法如下(首先介绍左值:C语言中出现在赋值语句左边的值)

70.左值参数:可被引用的对象,例如变量、数组元素、结构成员、引用和解除引用的指针;非左值:字面常量(引号括起的字符串除外)、包含多项的表达式

71.当引用变量的实参和引用参数不匹配,则C++将生成临时变量。生成临时变量的两种情况:①实参类型正确,但不是左值;②实参类型不正确,但可以转换为正确的类型。这种生成的临时变量即为”匿名变量“,这里也应当尽可能地使用const修饰符

72.使用const修饰符的好处:①避免无意修改数据的编程错误;②让函数能够处理const和非const数据;③使函数能够正确生成并使用临时变量

73.右值引用:使用&&声明,type && name=右值;常规函数的返回值也是右值。具体内容见后续(好远啊,第十八章,好难QAQ)

74.使用结构引用参数的方式和使用基本变量引用相同,在声明结构参数时使用引用运算符&

75.将引用作为函数的返回值:传统返回机制是计算关键字return后的表达式,并将结果返回给调用函数,复制的是一个临时位置,调用函数时使用这个值。而返回引用的函数直接返回的是被引用变量的别名,效率更高。但是需要注意的是,在传递引用变量时,不要传递临时变量的引用(传递形参就可以);或者使用new来分配新的存储空间;也可以将引用变量赋给一个指针,而返回指针,但使用这个方法容易忘记显式删除new分配的空间(用auto_ptr模板以及unique_ptr可以完成)

76.一般来说,引用函数的返回值可以设置为const类型,这样引用函数返回值被当作左值。尽量使用const,这样可以让函数不那么模糊

77.类作为参数被传递时,一般使用引用类型。比如string、fstream等类都可使用引用来传递。如果形参类型是const string &,则实参可以是string类型也可以是C-风格字符串,这是因为string类提供了转换为C-风格字符串的功能

78.★★★★★再次强调,在返回引用变量时,如果返回的是临时变量的引用,则会引发致命错误!

79.基类引用可以指向派生类对象,无需进行强制转换。可以定义一个接受基类引用作为参数的函数,调用函数时,可以将基类对象作为参数,也可以将派生类对象作为参数

80.使用引用参数的原因:①能够修改调用函数中的数据对象;②通过传递引用而不是整个数据对象,可以提高程序的运行速度。

81.什么时候使用引用、指针、按值传递:①数据对象很小,内置数据类型或小型结构,按值传递;②数组,用指针,而且最好是const指针;③较大的结构,用const指针或const引用,提高效率节省空间;④类对象,const引用

82.对于修改调用函数中数据的函数:①如果数据对象是内置数据类型,使用指针;②如果数据对象是数组,只能使用指针;③如果数据对象是结构,使用引用或指针;④如果数据对象是类对象,使用引用

83.第81、82条只是一般的指导原则,具体情况应当具体分析,这是马克思主义遇见问题时的正确处理方法,是马克思主义活得灵魂

084-086 默认参数

84.通过函数的原型,可以对默认参数进行赋值,默认参数赋值后,如果没有传递该参数,则函数将以默认值为该参数的传递值

85.要设置函数的默认参数,则必须从右向左添加默认值,这样做的目的是,在调用函数时,不会发生参数列表为(a,b, ,d)的情况

86.默认参数提供的是一种快捷的方式,可以减少要定义的析构函数、方法和方法重载的数量。原型中指定默认值,函数定义和没有默认参数时完全相同

087-095 函数重载

87.默认参数是使用不同数目的参数调用同一个函数,函数多态(重载)让用户可以使用多个同名的函数。根据上下文判断重载的目的和含义。重载的关键是函数的参数列表,也称为函数特征标

88.函数重载的要求是:函数的特征标不同,如果函数的参数数目和类型相同,参数的排列顺序也相同,则它们的特征标相同,变量名无关紧要

89.假设某函数有多个重载,而实参并不与任何原型匹配,则:①若只有一个重载函数可以通过强制类型转换达到使用的目的,则进行强制类型转换后输出;②若有多个重载函数可以通过强制类型转换达到使用目的,则该程序会报错

90.类型引用和类型本身的特征标,对于编译器来说是相同的:double cube(double x)和double cube(double &x)对于编译器来说是相同的

91.匹配函数时,非const值赋给const变量是合法的,而const赋值给非const变量是非法的

92.不允许返回类型不同但特征标相同的函数,重载是对特征标而非函数类型进行重载。也就是返回类型不同,特征标也必须不同

93.重载引用参数:①void func(double &v1);②void func(const double &v2);③void func(double &&v3);。对于以上三种,①提供了左值参数匹配;②提供了可修改左值、const左值和右值参数匹配;③提供了右值参数匹配。因此②与①③均有重叠,此时函数会自动调用最匹配的版本,但前提是定义了一个较为通用的版本

94.函数重载的使用时机:当函数基本上执行相同任务,但使用不同形式的数据时,才使用重载。另外,如果可以通过使用默认参数的方式来实现功能,则应尽可能不使用重载

95.函数重载的机制:名称修饰(名称矫正)。C++编译器对不同的函数重载给予了不同的内部表示,用不同的方式描述接口

096 补充

96.C++库中的数学函数假定角度单位是弧度;cmath库中的函数,atan2()可以根据xy的值计算角度,而atan()函数不能区分180度之内和之外的角度,一般用前者

097-100 碎碎念

97.C++真的难,略懂Python、系统学了C#,也用C#和Python写了三年的程序,但学起C++来还真是挺费劲。一遍肯定是吃不透的,我估计最起码要学四五遍,第一遍看书,第二遍开始边实践边看书,第三遍得过重难点,再把实践中的问题再解决了

98.C++和C在科研领域真的很实用,高效的背后隐藏的是计算机的机制,要真正学好C++和C真的不容易,得多花功夫嘤嘤嘤

99.希望自己可以坚持下来,其实也必须坚持下来!现在的目标(大四下学期的目标)是:毕设用C++做,花大功夫学C++以及Linux!

100.这100条水了五条,其实这就是个备忘录,就只能提供个提示作用,前提是写了一定相关的代码,不然如果想通过看备忘录学会C++,那就放弃吧hhhhhh!加油加油!

下期预告:函数模板、内存模型、命名空间、对象和类入门

对了,参考书《C++ Primer Plus》第六版,2012年版…看了这个觉得C++11还挺牛的嗷,然鹅现在已经C++20了都要,所以说学吧学吧,最后放一张图鼓励自己和看到文章的小伙伴(来源:知乎-烈日烤鱼。前辈前辈前辈!膜拜)
来源:知乎-烈日烤鱼。前辈前辈前辈!膜拜

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值