C++学习(57)

来源:互联网 发布:淘宝联盟下单跟不到单 编辑:程序博客网 时间:2024/05/18 15:27

 1.若有 C 语言表达式 2+3*4+7/3, 以下选项中叙述正确的执行顺序是(B )。 

A 先执行3*4=12,再执行7/3=2.5,最后执行2+12+2.5=16.5

B 先执行3*4=12,再执行2+12=14,再执行7/3=2,最后执行14+2=16

C 先执行7/3=2,再执行3*4=12,再执行12+2=14,最后执行2+14=16

D 先执行2+3=5,再执行5*4=20,再执行20+7=27,最后执行27/3=9

分析:这道题实际上考查了数据结构栈的实际应用----表达式求值。
就此题而言,从左到右以此计算压栈,运算过程中应用到(运算符栈为OPTR,操作数为OPND,运算起止符#,#运算优先级小于一切操作符):


步骤 OPTR栈 OPND栈 输入字符 主要操作

1 #2+3*4+7/3#   2->OPND(不是运算符入栈)

2 #2+3*4+7/3#+->OPTR(+优先级高入栈)

3 #+23*4+7/3#3->OPND(不是运算符入栈)

4 #+2 3*4+7/3#*->OPTR(*优先级高入栈)

5 #+*2 34+7/3#4->OPND(不是运算符入栈)

6 #+*2 3 4+7/3#3*4->OPND(+优先级不大于栈顶元素,计算3*4,结果入栈)

7 #+2 12+7/3#2+12->OPND(+优先级不大于栈顶元素,计算2+12,结果入栈)

8 #14+7/3#+->OPTR(+优先级高入栈)

9 #+147/3#7->OPND(不是运算符入栈)

10 #+14 7/3#/->OPTR(/优先级高入栈)

11 #+/14 73#3->OPND(不是运算符入栈)

12 #+/14 73#7/3->OPND(#优先级不大于栈顶元素,计算7*3=2截断取整,结果入栈)

13 #+14 2# 14+2->OPND(#优先级不大于栈顶元素,计算14+2,结果入栈)

14 #16# 运算结束


你以为他考得是优先级,其实主要考的是数据结构。


2.虚函数不能作为内联函数,虚函数在运行时通过虚函数表,是动态的;内联函数在编译时候进行代码嵌入,是静态的。

内联函数不能为虚函数,因为内联函数是直接将代码拷贝过去,不存在地址这一说法,而虚函数使用过程中需要一个虚地址。 虚函数可不可以为内联函数


3.首先看看各个容器的erase(pos)实现吧: 
1). vector,erase(pos),直接把pos+1到finish的数据拷贝到以pos为起点的区间上,也就是vector的长度会逐渐变短,同时iter会逐渐往后移动,直到iter == cont.end(),由于容器中end()返回的迭代器是最后一个元素的下一个(这个地方没有任何值),现在考虑这个状态前一个状态,此时要删除的点是iter, tempIt = iter, ++iter会指向此时的end(),但是执行erase(tempIt)之后,end()向前移动了!!!问题来了,此时iter空了!!!不崩溃才怪。 

2). list,erase(pos),干的事情很简单,删除自己,前后的节点连接起来就完了,所以iter自增的过程不会指空,不会崩溃喽。 


3). map,erase(pos),干的事情太复杂,但是我们需要知道的信息其实很少。该容器底层实现是RBTree,删除操作分了很多种情形来讨论的,目的是为了维持红黑树性质。但是我们需要知道的就是每个节点类似于list节点,都是单独分配的空间,所以删除一个节点并不会对其他迭代器产生影响,对应到题目中,不会崩溃喽。 


4). deque,erase(pos),与vector的erase(pos)有些类似,基于结构的不同导致中间有些步骤不太一致。先说说deque的结构(这个结构本身比较复杂,拣重要说吧,具体看STL源码),它是一个双向开口的连续线性空间,实质是分段连续的,由中控器map维持其整体连续的假象。其实题中只要知道它是双向开口的就够了(可以在头部或尾部增加、删除)。在题中有erase(pos),deque是这样处理的:如果pos之前的元素个数比较少,那么把start到pos-1的数据移到起始地址为start+1的区间内;否则把pos后面的数据移到起始地址为pos的区间内。在题中iter一直往后移动,总会出现后面数据比前面少的时候,这时候问题就和1一样了,必须崩溃!


4.#define和const 相比有如下劣势:
1).const定义常量是有数据类型的,而#define宏定义常量却没有
2).const常量有数据类型,而宏常量没有数据类型。编译器可以对const进行类型安全检查,
   而对后者只进行字符替换,没有类型安全检查,并且在字符替换中可能会产生意料不到的错误
3).有些集成化的调试工具可以对const常量进行调试,但是不能对宏常量进行调试。


原创粉丝点击