C++随笔_2

1.假定一个函数原型为“char* func(int n)”,则该函数的返回类型为?

答:char*

解析:
函数的返回类型就是定义函数的类型

2.以下程序的输出结果是?

      # define  ADD ( x )   x + x
      main ( )
      { int  m = 1 ,  n = 2 ,  k = 3 ,  sum  ;  
        sum = ADD ( m + n ) * k ; 
        printf ( “ sum = %d \n ” ,  sum ) ;
      }

答:10 (m+n+m+n*k)=10

解析:
宏定义:原样替换
ADD ( x ) x + x
sum = ADD ( m + n ) * k
替换结果为
把 m+n 作为 x ,替换得到 m+n+m+n*k,
将 m = 1 , n = 2 , k = 3带入得1+2+1+2*3 = 10

  1. CONTAINER::iterator iter , tempIt;
    for (iter = cont.begin() ; iter != cont.end() ; )  
    {
    tempIt = iter;
    ++iter;
    cont.erase(tempIt);
      
    }

假设cont是一个CONTAINER的示例,里面包含数个元素,那么当CONTAINER为:
1、vector
2、list
3、map
4、deque
会导致上面的代码片段崩溃的CONTAINER类型是?

答:vector deque

解析:
\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一样了,必须崩溃!

关联容器(如map, set, multimap,multiset),删除当前的iterator,只会使当前的iterator失效,只要在erase时,递增当前iterator即可。
对于序列式容器(如vector,deque),删除当前的iterator会使后面所有元素的iterator都失效。这是因为vetor,deque使用了连续分配的内存,删除一个元素导致后面所有的元素会向前移动一个位置。不过erase方法可以返回下一个有效的iterator,cont.erase(iter++)可以修改为cont.erase(iter)
list使用了不连续分配的内存,并且它的erase方法也会返回下一个有效的iterator。

4.下列程序段的输出结果为()?

int a=7,b=9,t;  
t=a*=a>b?a:b;  
printf("%d",t);  

答:63
解析:
?:运算符优先级高于*=和=运算符,所以先计算?:的值
计算过程:a不大于b,所以三目运算符的结果为b,原式变为t=a*=b,计算得出t=7*9=63

5.标识符只能以数字,字母,下划线组成;标识符开头必须是英文字母或下划线;不能用c关键词为标识符命名

**6.一个类可以有多个不同名的构造函数? **
正确
错误

答:错误
解析:
构造函数与类名相同,在new一个对象时调用 构造函数,构造函数可以重载。

7.下列 描述中,() 是抽象类特有的

选项:
不可以声明虚函数

不可以定义友元函数

不可以进行构造函数重载

不可以实例化

答案:不可以实例化
解析:抽象类是含有纯虚函数的类,因为纯虚函数没有函数体,也就是这个类是不完整的,需要继承他并实现虚函数才能实例化,否则不能实例化

8.设有一个判断语句

if(!(ch>=‘0’&&ch<=‘9’))printf(“This is not a digit!\\n”);
else printf(“This is a digit!\\n”);

为实现判定—条件覆盖,需要设计的测试用例个数至少应为
选项为:1、2、3、4
答案:3
解析:判定条件最多有三种情况,一是大于0也大于9,二是小于9也小于0,三是大于0小于9

9.对于纯虚函数描述正确的是

选项:
A.含有纯虚函数的类不能被声明对像,这些类被称为抽象类
B.继承抽象类的派生类可以被声明对像,但要在派生类中完全实现基类中所有的纯虚函数
C.继承抽象类的派生类可以被声明对像,不需要实现基类中全部纯虚函数,只需要实现在派生类中用到的纯虚函数
D.虚函数和纯虚函数是一样的,没什么区别

答案:AB

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容