![041415e64add30dab4b1b1cb544f1708.gif](https://i-blog.csdnimg.cn/blog_migrate/5b92d21c6a93f1406dee4b754acce0e0.gif)
![124fa261282f83addf67cd849667b785.gif](https://i-blog.csdnimg.cn/blog_migrate/439190ea9bdc5ccef97f00f9664a21e0.gif)
今 日 寄 语
书读百遍,其义自见。
——陈寿
![a5e43dc885901d0e5f42768fd2f37628.png](https://i-blog.csdnimg.cn/blog_migrate/18d487ff627e8a0593a3312d8d4cc4d4.png)
No.1
操作符与表达式
1.运算符与表达式概述
教材第二章从数据类型的介绍开始,详细讲解了几个基本的数据类型,以及它们相应的操作以及各种表示形式。对不同的数据类型进行讲解之后又讲解了它们之间的相互转换。在此基础之上,运算符则是利用它们进行计算或处理的符号。相比于只需要记忆规则的各个数据类型,运算符之间的表示以及关系无疑会难上许多。
其中重点和难点是运算符的优先级,及在具体运算时,我们输入带有各种运算符的C++表达式给电脑时,电脑是按照何种顺序和规律进行计算的?
2.运算符的优先级
我们可以先从运算符的种类说起。运算符主要分为算术运算符,关系运算符,逻辑运算符,赋值运算符,自增/自减运算符。(其中具体包含哪些符号见教材这里不详细展开)那么,它们运用于一个表达式的时候会遵守什么样的规则和顺序?
当我们看见一个表达式时,需要记住的是:①优先级由高到低的顺序是:自增自减运算符>!>算数运算符>关系运算符>&&>||>赋值运算符
②其中++/--如果放在变量之前,是先使用变量,再自增/减。如果放在变量之后,是先自增/减,再使用变量。
③还需要注意是,逻辑表达式求解顺序自左至右,并不是所有逻辑运算符都被执行,只是在必须执行下一个表达式才能求解时才求解该运算符。
如何理解上述的话?我们可以看一道经典的例题(也被问过很多次)
![1d9cff144e0419e5ff38ea564677a8c6.png](https://i-blog.csdnimg.cn/blog_migrate/15e3b4a7ec09af756c79c246dc1a85b8.png)
E X A M P L E
例 题
整形变量a的值为10,b的值为3,则执行表达式b%=b++||a++
后两变量的值为:____
A.a=10,b=0 B.a=9,b=4 C.a=9,b=3 D.a=8,b=1
解析:这道题由于赋值符号优先级最小,所以先看等号右边的逻辑或运算,b++因为++在后,于是这里直接使用b为3代入,3>0所以逻辑或的结果肯定为0,所以没有必要执行右边的a++运算了,于是a大小不变,为10,其实到这里已经可以选出A答案。接下来因为右边表达式结果已经出来了,b进行自加为4,再进行赋值运算,b%=1,即b=4%1,结果为0,与A吻合。
![1d9cff144e0419e5ff38ea564677a8c6.png](https://i-blog.csdnimg.cn/blog_migrate/15e3b4a7ec09af756c79c246dc1a85b8.png)
上述题目包含了好几个前面的知识点,务必仔细理解和揣摩上述题目的计算过程,熟悉之后想必便就不会被这方面的题目难住了。
No.2
函数
函数,又称function,每个函数均具有相对独立的功能,任何C++程序都由若干个函数组成。
1 函数的参数传递
函数中较为容易犯错的是参数的传递,在有参函数中,接受外部数据的变量称为形式参数,而从外部传送过来的数据称实际参数。
需要注意的是:
①实参对形参变量的传递是“值传递”,即单向传递。在内存中实参,形参占不同单元,通常并不能通过改变形参来改变实参的值。但实参和形参类型一致,调用时一一对应。
②引用作为函数参数:引用是C++中的一种特殊类型的变量,其本质是给一个已定义的变量起一个别名(不占用内存空间),所以当用引用作为函数参数时,会和一般情况有明显区别:非引用情况下形参和实参分别占用两个不同的内存空间。而引用的参数占同一个。这就导致了利用引用变量传递参数时,是可以通过函数内部操作来改变实参的值的。
这里用书上的例子进行说明:
void swap1(float x,float y) { float t; t=y; t=x; x=t; } void swap2(float &x,float &y) { float t; t=y; t=x; x=t; } void main(void) { float a=10,b=20; swap1(a,b); cout< swap2(a,b); cout<}
运行函数会发现输出结果第一行是10 20 顺序是不会变的。因为过程中只涉及到实参数据像形参传递,形参在函数内进行操作,然而实参本身并没有发生改变。然而第二行结果是20 10,因为引用形参其实就是实参,只是可以理解为在函数中换了个名字,它们占用同一内存,形参变化实参自然会变化。
2 递归
汉诺塔问题是经典的递归问题:
完成目标:将n个block从A搬到C,需要移动多少次完成?
约束条件:每次搬运只能移动一个block,且不能出现大的block在小的blcok之上。
![329b0d3753a2e87f6a2562ac93e98283.png](https://i-blog.csdnimg.cn/blog_migrate/21efece3dec9596eb79bbfd249f0ff09.png)
算法分析:
第一次移动,把A柱子上的前n-1个移动到B上。
第二次移动,直接把A柱子上的最后一个移动到C柱子上。
第三次移动,把B柱子上的n-1个柱子通过柱子A移动到柱子C上。
![64e4339456a686bbbf1d956867303766.png](https://i-blog.csdnimg.cn/blog_migrate/6536198e0f635d894a1c60c2623c7a81.png)
![6601333640bccedb4e29f4c8985403e2.png](https://i-blog.csdnimg.cn/blog_migrate/e4c94a225356a38e50589aef53a72823.png)
![f955195f3b7f2db67fa110bd7220a310.png](https://i-blog.csdnimg.cn/blog_migrate/fb5027dad760297a87cf5b07946e4089.png)
递归是一种直接或间接调用函数自身的算法。上述算法中移动n块必须先解决移动内n-1块的问题,而n-1块又要解决n-2块的问题。
递归算法的特点:必须有一个明确的递归约束条件,成为递归出口,如n=1时就是上述算法的出口,如果没有递归出口,该函数将无休止调用自身,就不正确了。
![a4ab52eea78037af072f5fafae30de30.gif](https://i-blog.csdnimg.cn/blog_migrate/70ce434baa428772ba493d1f4b593990.gif)
![930b3d465d9bc14a5add94dfb6b25a0c.png](https://i-blog.csdnimg.cn/blog_migrate/5e1bdca54ff3208694bb5c05694feb99.png)
![373e2be996ff1e1170123ca0910f752f.gif](https://i-blog.csdnimg.cn/blog_migrate/9021605cc536fc15ae8c2bfab2ccc81e.gif)
![8cf2bd82988ee8f28717148a668d67d1.png](https://i-blog.csdnimg.cn/blog_migrate/b773f0f2a8e00477adef800610ab80c4.png)
文字 胡涵旭
排版 牟育生