牛客 题库 5

1.如下代码,result变量的输出结果是多少?

链接:https://www.nowcoder.com/questionTerminal/fb01e2436c6d453abbbf9801f794165b
来源:牛客网

#include<iostream>
using namespace std;
int i=1;
class MyCls{
public:
    MyCls():m_nFor(m_nThd),m_nSec(i++),m_nFir(i++),m_nThd(i++){
        m_nThd=i;
    }
    void echo(){
        cout<<"result:"<<m_nFir+m_nSec+m_nThd+m_nFor<<endl;
    }
private:
    int m_nFir;
    int m_nSec;
    int m_nThd;
    int &m_nFor;
};
int main()
{
    MyCls oCls;
    oCls.echo();
    return 0;
}

解答:11


首先要明白变量初始化的顺序是其声明的顺序,跟初始化列表中的顺序无关。所以变量的初始化顺序不是构造函

数中的初始化列表的顺序,而是成员函数echo()中,cout语句中的顺序:m_nFir(i++),m_nSec(i++),m_nThd(i++),

&m_nFor(m_nThd)(注意:m_nFor为m_nThd的一个引用); i初始值为1,所以经过初始化列表初始化以后

m_nFir=1,m_nSec=2,m_nThd=3,m_nFor为m_nThd的一个引用(也就是说,构造函数初始化之后的值)。

并且此时i的值为4,然后执行构造函数中的执行语句m_nThd=i后,m_nThd=4,m_nFor是它的一个引用,

自然值也为4。输出结果m_nFir+m_nSec+m_nThd+m_nFor=1+2+4+4=11    

这里要注意变量初始化的顺序:是声明的顺序,而不是初始化列表中的顺序;初始化列表初始化完之后,就开始

执行构造函数中的执行语句。


如果我们把int &m_nFor;改一下,不让m_nFor作为m_nThd的引用,只是让m_nThd来初始化m_nFor,也就是:

int m_nFor;,那么结果会有什么不同呢?

最终运行的情况是:m_nFir=1,m_nSec=2,m_nThd=3,m_nThd来初始化m_nFor,所以m_nFor=3;然后

执行构造函数中的执行语句:m_nThd=i,此时m_nThd=4,但是m_nFor已经由m_nThd初始化完成,跟现在m_nThd

的值没有关系,所以m_nFor仍然等于3,最终结果就是10,而不是上面的11.


2.下面对静态成员的描述中,正确的是:

  • 静态数据成员可以在类体内初始化
  • 静态数据成员不可以被类的对象调用
  • 静态数据成员不能受private控制符的作用
  • 静态数据成员可以直接用类名调用
解答:D
A、 C++ Primer》第四版401页中说:   一般而言,类的static成员,像普通数据成员一样,不能在类的定义体中初始化。 相反,static成员通常在定义时才初始化。 这个规则的一个例外是,只要初始化式是: 一个常量表达式,整型const static 成员就可以在类的定义体中进行初始化。
链接:https://www.nowcoder.com/questionTerminal/dbf412c2a829492e8f936d698549dc17
来源:牛客网

class circle
{
int a; // 普通变量,不能在类中初始化
static int b; // 静态变量,不能在类中初始化
static const int c=2; // 静态常量,可以在类中初始化
static const double PI=3.1416;//error C2864: 只有静态常量整型数据成员才可以在类中初始化
} ;
b可以在类外进行初始化,且所有对象共享一个b的值:
int circle::b = 2;

也就是说, 普通变量和静态变量都不能在类中进行初始化,但是有一种特殊情况,只有静态常量整型数据成员才可以在类中进行初始化 ,A的说法不全面。
B .静态数据成员可以通过类的对象,指针,类名等直接调用静态成员
class A
{  
private:
    static int count ; // 类内声明
};

int A::count = 0 ;//这句就是通过类名直接调用静态成员

C. 静态数据成员同样受 private,public,protected 等权限符限制
D.正确

3.下列代码的输出为:
链接:https://www.nowcoder.com/questionTerminal/f310bd3981d74407b1af92e47f6892ce
来源:牛客网

#include<iostream>
#include<vector>
using namespace std;
 
int main(void)
{
    vector<int>array;
    array.push_back(100);
    array.push_back(300);
    array.push_back(300);
    array.push_back(500);
    vector<int>::iterator itor;
    for (itor = array.begin(); itor != array.end(); itor++)
    {
        if (*itor == 300)
        {
            itor = array.erase(itor);
        }
    }
    for (itor = array.begin(); itor != array.end(); itor++)
    {
        cout << *itor << " ";
    }
    return 0;
}

解答:100 300 500
考察了vector 的erase函数:删除容器内的一个元素
删除一个或一段元素更通用的方法是erase操作,该操作有两个版本:删除由一个迭代器指向的单个元素,或删除由一对迭代器标记的一段元素。erase的这两种形式都返回一个迭代器,指向被删除元素或元素段后面的元素,也就是说,如果元素j恰好紧跟在元素i后面,则将元素i从容器中删除后,删除操作返回指向j的容器。
   删除指定位置的元素时,返回值是一个迭代器,指向删除元素下一个元素。
     删除第一个300之后,返回的迭代器指向其后面的300,然后itor++,指向了500.

如果我们想将容器中的300都删除掉,程序应该怎么改呢?

vector中使用一次erase()方法后,原来的容器会被新的容器所取代,现在的容器指针指向的是一个野指针,所以需要
重新对容器指针进行赋值操作:itor=array.begin();,添加这条语句后就可以完全去掉两个300元素,完整代码如下:
int main(void)
{
	vector<int>array;
	array.push_back(100);
	array.push_back(300);
	array.push_back(300);
	array.push_back(500);
	vector<int>::iterator itor;
	for (itor = array.begin(); itor != array.end(); itor++)
	{
		if (*itor == 300)
		{
			itor = array.erase(itor);
			/*vector中使用一次erase()方法后,原来的容器会被新的容器所取代,现在的容器指针指向的是一个
			野指针,所以需要重新对容器指针进行赋值操作:itor=array.begin();,添加这条语句后就可以完全
			去掉两个300元素*/
			itor = array.begin();
		}
	}
	for (itor = array.begin(); itor != array.end(); itor++)
	{
		cout << *itor << " ";
	}
	return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值