问答题
问答题1:以下函数中,和其他函数不属于一类的是?
(A) fwrite
(B) putc
(C) pwrite
(D) putchar
(E) getline
(F) scanf
提示:pwrite 是系统调用,其余都是库函数,库函数是对系统调用的封装…
从用户空间到内核空间一般有三种方法,一种是直接使用 shell 内核命令,第二种是通过系统调用,第三种是通过库函数. 使用库函数简单方便,也更加安全
问答题2:在重载一个运算符为成员函数时,其参数表中没有任何参数,这说明该运算符是?
提示:如果重载函数是 A operator++(int)
表示重载后缀 ++ 即是 a++;如果重载函数是 A operator++()
表示重载前缀++ 即是 ++a
答案:前缀一元运算符
问答题3:以下结果输出什么?
class A{
public:
virtual void func(int val = 1){
std::cout << "A->" << val << std::endl;
}
virtual void test(){
func();
}
};
class B : public A{
public:
void func(int val = 0){
std::cout << "B->" << val << std::endl;
}
};
int main(int argc, char* argv[]){
B*p = new B;
p->test();
system("pause");
return 0;
}
提示:
拓展…
class A{
public:
virtual void func(int val = 1){
std::cout << "A->" << val << std::endl;
}
virtual void test(){
func();
}
};
class B : public A{
public:
void func(int val = 0){
std::cout << "B->" << val << std::endl;
}
};
int main(int argc, char* argv[]){
A*p1 = new A;
A*p2 = new B;
// B*p3 = new A; //error
B*p3 = reinterpret_cast<B*> (new A);
B*p4 = new B;
// 基类对象调用成员函数
p1->test(); //A->1
// 静态联编 首先将 val 设为1
p2->test(); //B->1
// p3 被重新编译为一个 A类指针
p3->test(); //A->1
p4->test(); //B->1
//测试func()
p1->func(); //A->1
p2->func(); //B->1
p3->func(); //A->0
p4->func(); //B->0
}
如果没有虚函数 virtual ,则不用考虑虚拟那些比较复杂的东西,只看基类的指针就行了.
class A{
public:
void func(int val = 1){
cout<< "A->"<<val << endl;
}
//这个test()的virtual可有可无
void test(){
func();
}
};
class B : public A{
public:
void func(int val = 0){
cout<< "B->"<<val << endl;
}
};
int main(int argc, char* argv[]){
A*p1 = new A;
A*p2 = new B;
// B*p3 = new A; //error
B*p3 = reinterpret_cast<B*> (new A);
B*p4 = new B;
p1->test(); //A->1
p2->test(); //A->1
// B 类中没有 test 函数,调用基类的 test 函数
// 然后再调用基类的 fun 函数
p3->test(); //A->1
p4->test(); //A->1
p1->func(); //A->1
p2->func(); //A->1
p3->func(); //B->0
p4->func(); //B->0
return 0;
}
问答题4:下面程序的输出是?
class A{
public:
void foo(){
printf("1");
}
virtual void fun(){
printf("2");
}
};
class B : public A{
public:
void foo(){
printf("3");
}
// fun 为虚函数
void fun(){
printf("4");
}
};
int main(void){
A a;
B b;
A *p = &a;
p->foo(); //1
p->fun(); //2
p = &b;
p->foo(); //1
p->fun(); //4
A *ptr = (A *)&b;
ptr->foo(); //1
ptr->fun(); //4
system("pause");
return 0;
}
提示: A *ptr = (A *)&b;
虽然 b 对象被强制转换为A类型的指针,但是虚函数表中存放的仍然是子类函数的地址,所以ptr->fun()
仍然会调用子类的fun
函数.
答案:121414
编程题
编程题1:井字棋
对于一个给定的井字棋棋盘,请设计一个高效算法判断当前玩家是否获胜。给定一个二维数组board
,代表当前棋盘,其中元素为 1 的代表是当前玩家的棋子,为 0 表示没有棋子,为 -1 代表是对方玩家的棋子
测试样例:[[1,0,1],[1,-1,-1],[1,-1,0]] 返回:true
class Board {
public:
bool checkWon(vector<vector<int>> board) {
// write code here
int row = board.size();
int sum = 0;int i = 0;int j = 0;
// 检查每一行
for(i = 0;i<row;++i){
sum = 0;
for(j = 0;j<row;++j){
sum+=board[i][j];
}
if(sum ==row ){
return true;
}
}
// 检查每一列
for(i = 0;i<row;++i){
sum = 0;
for(j = 0;j<row;++j){
sum +=board[j][i];
}
if(sum == row){
return true;
}
}
// 检查主对角线
sum = 0;
for(i = 0;i<row;++i){
sum+=board[i][i];
}
if(sum ==row){
return true;
}
// 检查副对角线
sum = 0;
for(i = 0;i<row;++i){
sum += board[i][row-i-1];
}
if(row ==sum){
return true;
}
return false;
}
};
编程题2 :密码强度等级
密码按如下规则进行计分,并根据不同的得分为密码进行安全等级划分
一、 密码长度:
5 分: 小于等于4 个字符
10 分: 5 到7 字符
25 分: 大于等于8 个字符
二、字母:
0 分: 没有字母
10 分: 全都是小(大)写字母
20 分: 大小写混合字母
三、数字:
0 分: 没有数字
10 分: 1 个数字
20 分: 大于1 个数字
四、符号:
0 分: 没有符号
2. 10 分: 1 个符号
3. 25 分: 大于1 个符号
五、奖励:
2 分: 字母和数字
3 分: 字母、数字和符号
5 分: 大小写字母、数字和符号
最后的评分标准 >=
90 表示非常安全
= 80: 安全(Secure)
= 70: 非常强
= 60: 强(Strong)
= 50: 一般(Average)
= 25: 弱(Weak)
= 0: 非常弱
对应输出为:
VERY_WEAK,
WEAK,
AVERAGE,
STRONG,
VERY_STRONG,
SECURE,
VERY_SECURE
请根据输入的密码字符串,进行安全评定。
注:
字母:a-z, A-Z
数字:0-9
符号包含如下: (ASCII码表可以在UltraEdit的菜单view->ASCII Table查看)
!"#$%&’()*+,-./ (ASCII码:x21~0x2F)
:;<=>?@ (ASCII<=><=><=><=><=>码:x3A~0x40)
[]^_` (ASCII码:x5B~0x60)
{|}~ (ASCII码:x7B~0x7E)
输入描述:输入一个string的密码
输出描述:输出密码等级
提示:分模块写函数,每个模块返回一个分数
字母模块
int numChar(string str, int k){
//根据ASCII码判断字母大小写
int small = 0;
int big = 0;
for (int i = 0; i < k; i++){
if (str[i] >= 65 && str[i] <= 90){
big++;
}
else if (str[i] >= 97 && str[i] <= 122) {
small++;
}
}
if ((small + big) == 0) {
return 0;
}
else if (small == k || big == k) {
//我靠,居然还可以返回10 ,这种写法值得记一下
return 10;
}
else if (small > 0 && big > 0) {
return 20;
}
return 0;
}
数字模块
int numNumber(string str, int k){
//根据ASCII码判断数字个数,减去字符‘0’之后在0~9之间的即为数字
int num = 0;
for (int i = 0; i < k; i++){
//这里需要注意的是,因为传进来的是字符char,所以要减去 ‘0’变为 int 数字
if (str[i] - '0' >= 0 && str[i] - '0' <= 9) {
num++;
}
}
if (num == 0){
return 0;
}
else if (num == 1) {
return 10;
}
else {return 20;}
}
其他字符
int numSymbal(string str, int k){
int num = 0;
for (int i = 0; i < k; i++){
//除去字母,数字,其它都为符号
if (!(str[i] >= 65 && str[i] <= 90)
&& !(str[i] >= 97 && str[i] <= 122)
&& !(str[i] - '0' >= 0 && str[i] - '0' <= 9))
num++;
}
if (num == 0) {
return 0;
}
else if (num == 1) {
return 10;
}
else{return 25;}
}
主函数
int main(){
string str;
while (cin >> str){
int sum1 = 0, sum2 = 0, sum3 = 0, sum4 = 0, sum5 = 0;
int k = str.size();
if (k <= 4){
sum1 = 5;
}
else if (k >= 8){
sum1 = 25;
}
else{sum1 = 10;}
sum2 = numChar(str, k);
sum3 = numNumber(str, k);
sum4 = numSymbal(str, k);
if ((sum2 > 0) && (sum3 > 0) && (sum4 > 0)){
if (sum2 == 10){
sum5 = 3;
}
else{
sum5 = 5;
}
}
else if (sum2 > 0 && sum3 > 0 && sum4 == 0){
sum5 = 2;
}
if (sum1 + sum2 + sum3 + sum4 + sum5 >= 90)
cout << "VERY_SECURE" << endl;
else if (sum1 + sum2 + sum3 + sum4 + sum5 >= 80)
cout << "SECURE" << endl;
else if (sum1 + sum2 + sum3 + sum4 + sum5 >= 70)
cout << "VERY_STRONG" << endl;
else if (sum1 + sum2 + sum3 + sum4 + sum5 >= 60)
cout << "STRONG" << endl;
else if (sum1 + sum2 + sum3 + sum4 + sum5 >= 50)
cout << "AVERAGE" << endl;
else if (sum1 + sum2 + sum3 + sum4 + sum5 >= 25)
cout << "WEAK" << endl;
else
cout << "VERY_WEAK" << endl;
}
return 0;
}