问答题1:以下代码输出的是?
#include
int main(){
char a[10] = { '1','2','3','4','5',\
'6','7','8','9',0};
int i = 8;
char* p = a + i;
printf("%s\n", p - 3);
return 0;
}
提示:这道题靠的是字符串结尾的结束符,如果把左后一个字符 0
换成'0'
,那么结果是未定义的,因为这并不是一个完整的字符串,一个完整的字符串后面一定要有一个反斜杠0表示字符串的结束.数字0也可以代表'\0'
问答题2:当一个类对象的生命周期结束后,关于调用析构函数的描述正确的是:
(A) 如果派生类没有定义析构函数,则只调用基类的析构函数
(B) 如果基类没有定义析构函数,则只调用派生类的析构函数
(C) 先调用派生类的析构函数,后调用基类的析构函数
(D) 先调用基类的析构函数,后调用派生类的析构函数
提示:析构函数就算没有定义,也会调用编译器默认的析构函数,析构函数和构造函数正好相反,首先构造基类对象,然后构造派生类对象,所以析构函数,先调用派生类的析构,再调用基类的析构函数.
问答题3:在函数中如何返回两个参数
在c
语言中可以利用结构体,数组,两个指针,或者两个全局变量,但是在 c++ 中是可以利用花括号{}
直接返回两个参数的
问答题4:下面代码输出啥?
int main(){
vector<int>array;
array.push_back(100);
array.push_back(300);
array.push_back(300);
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;
}
提示:第一个 for() 循环的次数不是 6 次;因为在循环体中把数据抹除掉两个,这就导致只循环了三次就到了array.end 的位置,erase函数在删除当前元素的同时,自动指向下一个元素,然后才执行循环中的 ++ itor ,所以一共只有两个 300 被删除
答案:100 300 300 500
问答题5:下面关于一个类的静态成员描述中,不正确的是
(A) 静态成员变量可被该类的所有方法访问
(B) 该类的静态方法只能访问该类的静态成员函数
(C) 该类的静态数据成员变量的值不可修改
(D) 子类可以访问父类的静态成员
(E) 静态成员无多态特性
提示a:类的静态成员变量属于整个类,并不属于某个对象,它只存储了一份,供所有对象使用,当然也可以被所有方法访问.
示例
class A{
public:
static void a_print(){
cout <<"a_print调用"<<a<< endl;
}
void fun(){
cout <<"fun()调用"<<a << endl;
}
private:
static int a;
};
int A::a = 1;
int main(){
A a;
a.a_print();
a.fun();
return 0;
}
编译可以通过.
提示b:该类的静态方法只能访问该类的静态成员函数或静态成员变量,不可以访问非静态成员,因为非静态成员是在对象创建之后才有的,但是静态成员在创建对象之前就有了,所以用静态访问非静态就相当于使用一个未定义的变量.
提示c:该类的静态数据成员变量的值可修改,不存在不安全的问题
class A{
public:
static void a_print(){
a = 2;
cout <<"a_print调用"<<a<< endl;
}
private:
static int a;
};
int A::a = 1;
编译可以通过.
提示d:子类可以访问父类的静态成员,体现了类的继承性.
提示e:静态成员无多态性,由于 static 成员是属于类的,并不属于对象,但是多态的实现是由多个对象完成,比如基类指针指向子类的对象;另外 static 方法不允许被重写,而多态的必备条件之一就是要实现重写.
编程题1 :字符串中找出连续最长的数字串
读入一个字符串str
,输出字符串str
中的连续最长的数字串
输入描述:1个测试输入包含1个测试用例,一个字符串str
,长度不超过 255
输出描述:在一行内输出 str
中里连续最长的数字串
输入 abcd12345ed125ss123456789
输出 123456789
提示:进行一次循环遍历,遇到数字就计算后面的字符串长度,并比较每次的长度,最后返回长度最长的字符串.
#include
#include
using namespace std;
int main(){
string str,temp,res;
int maxnum = 0;
while(getline(cin,str)){
for(int i=0;i<str.size();++i){
temp = "";
if(str[i]>='0' && str[i]<='9'){
while(i<str.size() && str[i]<='9' && str[i]>='0'){
temp+=str[i];
++i;
}
}
if(temp.size()>res.size()){
res = temp;
}
}
cout<<res<<endl;
}
return 0;
}
代码简化…
#include
#include
using namespace std;
int main(){
string str,temp,res;
while(getline(cin,str)){
for(int i=0;i<str.size()+1;++i){
if(str[i]>='0' && str[i]<='9'){
temp+=str[i];
}else{
if(temp.size()>res.size()){
res = temp;
}else{
temp.clear();
}
}
}
cout<<res;
}
return 0;
}
注意字符串的长度比 size计算出来的大一个字节,所以在循环的时候要多执行一次,否则会提前退出,导致最后一次的数字字符串没有被计算在内.
编程题2 :输入n个整数,输出出现次数大于等于数组长度一半的数
方法一:首先进行排序,然后取中间数的,中间的数就是超过一半的数字,时间复杂度为 O(n * logn)
#include
#include
#include
using namespace std;
int main(){
int n;
vector <int> vec;
while (cin >> n){
vec.push_back(n);
}
sort(vec.begin(), vec.end());
cout << vec[vec.size() / 2 - 1] << endl;
return 0;
}
方法二:借助O(N)的辅助空间,使用复杂度可以降低到O(N),使用哈希映射的方法,然后遍历,如果记录的数大于等于一半,则输出当前数字.
#include
#include
using namespace std;
int main(){
int n = 0;
vector<int>vec;
while(cin>>n){
vec.push_back(n);
}
int array[50] = {0};
for(int i = 0;i<vec.size();++i){
array[vec[i]]++;
if(array[vec[i]]>=(vec.size()/2)){
cout<<vec[i]<<endl;
break;
}
}
return 0;
}
方法三(推介):只使用 O(N)的时间复杂度,也不借助任何辅助空间完成
提示:如果当前数字等于前面的数字,则记录次数+1,如果不等于则 -1,当计数次数的变量等于0时,把当前变量赋值给记录变量.把记录次数赋值为1,最后的记录变量一定是大于长度一半的变量.
#include
#include
using namespace std;
int main(){
int n;
vector<int>vec;
while(cin>>n){
vec.push_back(n);
}
int temp = vec[0];
int time = 1;
for(int i = 1;i<vec.size();++i){
if(vec[i]==temp){
time++;
}else{
time--;
}
if(time == 0){
temp = vec[i];
time++;
}
}
cout<<temp<<endl;
return 0;
}