C++ K2 (4)
提示:文章
文章目录
- 前言
- 一、背景
- 重载
- 总结
前言
前期疑问:
本文目标:
一、背景
接上文
重载
41、(单选)【重载】下面那种情形下myfunc函数声明是重载?【C】
A. int myfunc(int a,double b) 和 double myfunc(int a, double b)
B. int myfunc(int a,double b) 和 int myfunc(int a,double b=0.5)
C. int myfunc(int a,double b) 和 int myfunc(double b,int a)
D. int myfunc(int a,double b) 和 double myfunc(int , double )
函数重载:名字相同,形参列表不同
形参名字不同,不算重载
(重载不论返回值,只看参数的类型) 重载函数的声明。
42、(单选)【重载】需要实现连乘,以下哪种重载*的函数是正确的(B)
A、
const Rational& operator* (const Rational& lhs, const Rational& rhs) {
Rational *result = new Rational(lhs.numerator() * rhs.numerator, lhs.denominator() * rhs. denominator);
return result;
}
B、
const Rational operator* (const Rational& lhs, const Rational& rhs) {
return Rational(lhs.numerator() * rhs.numerator, lhs.denominator() * rhs. denominator);
}
C、
const Rational& operator* (const Rational& lhs, const Rational& rhs) {
std::shared_ptr<Rational> result = std::make_shared<Rational> Rational(lhs.numerator() * rhs.numerator, lhs.denominator() * rhs. denominator);
return *(result.get());
}
D、
const Rational& operator* (const Rational& lhs, const Rational& rhs) {
Rational result(lhs.numerator() * rhs.numerator, lhs.denominator() * rhs. denominator);
return result;
}
简单记选最短的吧
A new出来但是没有delte,导致使用者需要手动delete,不应该有这样的运算符。在函数中没有显示的delete,内存泄漏
C使用get获取原始指针,智能指针无法管理调用次数,函数return,指针生命周期结束,返回指针悬空。
D临时变量result生命周期在return后已经结束,此处返回的引用其实是一堆无效地址
43、(单选)【重载】假如运行环境int类型4bytes,short类型2bytes,long类型8bytes,存在代码
unsigned short x = 65530;
int a = myfunc(x, 20.0); -32768~32767
会优先匹配以下哪个重载函数(D)
A. int myfunc(double, double)
B. int myfunc(short, double)
C. double myfunc(int, float)
D. double myfunc(int, double)
实数常量默认为double。
向上提升:无符号到有符号,小整形到大整形。
44、(单选)【重载】假如运行环境int类型4bytes,short类型2bytes,long类型8bytes,存在代码: int a=myfunc(65530,20.0); 会优先匹配以下哪一个重载函数(D)
A. int myfunc(double,double)
B. int myfunc(unsigned short,double)
C. double myfunc(long,float)
D. double myfunc(long, double)
整数常量默认类型是int,所以不能选B
45、(单选)【重载】下面代码的输出是(A)
class A{
public:
void* operator new(size_t size){
cout<<"operator new 1"<<endl;
return malloc(size);
}
void* operator new[](size_t size){
cout<<"operator new 2"<<endl;
return malloc(size);
}
};
void* operator new(size_t size){
cout<<"operator new 3"<<endl;
return malloc(size);
}
void* operator new[](size_t size){
cout<<"operator new 4"<<endl;
return malloc(size);
}
int main()
{
A* pA = new A();
return 0;
}
A. operator new 1
B. operator new 2
C. operator new 3
D. operator new 4
解析:
自定义的 new 运算符相当于是对全局的 new 运算符的重载。
自定义了 new 操作符,并且是public 的,因此输出的是 operator new 1。
若未自定义new 操作符,则会输出operator new 3,作用相当于A* pA = ::new A(),表示调用全局的new操作符
若定义了,但不是 public的,则只能使用::new A()来调用全局的 new 操作符,此时输出operator new 3。
46、(单选)以下关于devid描述正确的是(C)
typedef int DevId;
typedef DevId* DevIdPtr;
const DevIdPtr devid;
A. 指向const DevId的指针,指针指向的内容不能被改变
B. 指向const DevId的指针,指针本身不能被改变
C. 指向DevId的const指针,指针本身不能被改变
D. 指向const DevId的const指针,指针本身合指针指向的内容都不能被改变
注意此处typedef之后,整体就变成了指针,因此const修饰的是这个指针
解析:const DevIdPtr devid;const 修饰的是DevIdPtr,因此是指针不能改变,是指针常量。
const DevIdPtr devid;并非相当于 const int* devid; 而是相当于int* const devid;
47、(单选)64位系统下执行如下指令(C)
#define T1 int*
typedef int* T2
T1 a, b;
T2 c, d;
请问sizeof(a), sizeof(b), sizeof©, sizeof(d)的值分别为
A. 8444
B. 4444
C. 8488
D. 8888
define其实只相当于语句替换,而typedef其实相当于整个内容的复制,所以此处等价于int* a, b; int* c, int* d;64位下指针8字节,int4四字节,故答案为8488
48、(单选)以下代码片段的输出中,最后一行的数字是(B)
#include <iostream>
int Foo(); // forward declaration
int Gear(); // forward declaration
int g_alice = Foo();
int g_bob = Gear();
int Foo()
{
std::cout << "Foo" << std::endl;
return g_bob;
}
int Gear()
{
std::cout << "Gear" << std::endl;
return 3;
}
int main()
{
std::cout << g_alice;
return 0;
}
A. 3
B. 0
C. 可能是0,可能是3
D. 随机值
解释:
代码编译时就已经确定的全局变量,包含const/constexpr修饰的量;
若被静态初始化为非零值,变量会被放去.data段;
若变量为0或无法确定,会被放去.bss段,零初始化(Zero Initialization)
在C++中,全局变量的初始化顺序是从上到下的,也就是说,g_alice在g_bob之前被初始化。在初始化g_alice时,调用了Foo()函数,而Foo()函数内部又调用了g_bob。但是此时g_bob还没有被初始化,因此会调用默认构造函数进行初始化,默认值为0。然后Foo()函数返回g_bob,也就是0。
这个题目有点神奇,之前完全没接触过这种情形。
之前的一个疑问再重复一遍:另外一个问题就是静态变量没有初始化是默认初始化为0吗?内置类型(如 int
, float
等)在全局或静态存储中会被初始化为零,在局部作用域中则未定义。
49、(单选)以下为两个文件中的代码片段(A)
a.cpp
int Foo()
{
static int alice = 7;
return alice;
}
b.cpp
extern int Foo();
int g_bob = Foo();
int main()
{
std::cout << g_bob;
return 0;
}
这两个文件编译链接成一个程序,运行结果输出为
A、7
B、0
C、可能是0,也可能是7
D、随机值
50、(单选)调用foo函数的返回值为(C)
char foo(void)
{
unsigned int a = 6;
int b = -20;
char c;
(a + b > 6) ? (c = 1) : (c = 0);
return c;
}
A.运行出错
B.编译错误
C.1
D.0
int与unsigned int的运算,int提升为unsigned int做计算 计算出一个很大的值。
如果a是int类型,a+b就是-16
51、(单选)下面代码中,c的值是(B)
unsigned int a = 5;
int b = -20;
int c;
(a + b) > 6 ? (c = 1) : (c = 0);
A. 0
B. 1
C. 运行出错
D. 编译出错
考察类型转换,int与unsigned int的运算,int提升为unsigned int做计算。
这个时候如果int的值是非负的,执行的结果和预期一样
如果int的值是负数,它的值就变成int的最大值 + 原值
Int b = 232 -20
52、(单选)C/C++右移位操作之后,左边的数据是怎么填充的(D)
A. 填0
B. 填1
C. 填符号位
D. 以上都有可能
左移操作时,移动到边界的位被丢弃,右边的位补0;
右移操作时,如果是无符号数或者有符号非负数,则左边补0,有符号负数则可以在左边补0也可以补1;
53、(单选)以下代码执行完成后i j的值是(B)
int main()
{
int i = 0;
int j = 0;
for (i = 10; i >= 0; --i) {
for (j = 10; j == 1; --j) {
i = j;
}
}
}
A. 0 0
B. -1 10
C. 执行超时
D. -1 0
循环开始后j=10,j==1始终为false,因此只执行外层i循环
54、(单选)下面输出的是什么(D)
int main(){
int a = 5;
int b = 3;
(!a && b++);
cout << a << " " << b;
}
A. 5 4
B. 0 4
C. 0 3
D. 5 3
!a逻辑取反为假,不往后判断了,!a不影响变量值
算术运算符>移位运算符>关系运算符>位运算符>逻辑运算符
注意运算符的短路行为
55、(单选)如下代码,c是多少(A)
int a = 8;
int b = 5;
int c;
c = a/b+0.3;
A 1
B 2
整形,不足1就忽略小数
56、 (单选)以下代码输出为(A)
int main()
{
int x = 1;
int y = 2;
if (++x >= 2 || y++ >= 2) { }
std::cout<<x<<“ ”<<y<<std::endl;
return 0;
}
A. 2 2
B. 2 3
C. 3 3
D. 1 2
A
或语句执行了前半句就结束了
如果||运算符左侧的子表达式为true,则右侧的子表达式将不被检查。因为只要有一个子表达式为true,整体表达式都可以被评估为true
http://c.biancheng.net/view/1360.html
57、(单选)以下程序输出结果为(C)
#include <iostream>
#include <array>
int main()
{
std::cout<<(1<30<5)<<std::endl;
return 0;
}
A. 编译错误
B. 10
C. 1
D. 0
没有连不等式的语义,而是会被编译成:先判断1<30,结果为1,然后判断1<5,结果为1
优先级相同,从左到右结合
58、(单选)以下代码的输出结果为(D)
#include <iostream>
#include <cstdint>
using namespace std;
int main()
{
uint32_t i =10;
cout<<i<<“,”;
cout<<sizeof(i++)<<”,”;
cout<<i;
return 0;
}
A. 10,10,11
B. 10,11,11
C. 10,4,11
D. 10,4,10
sizeof是一个操作符,i不管做什么操作不会影响他的类型,因此直接得到int的大小而不会进行运算
交叉知识点:sizeof在编译阶段起作用
59、(单选)问 a, b, c 分别输出多少(D)
int a = 0;
int b = 0;
int c = 0;
for (int i = 0; i < 100; ++i) {
b = a++;
c = c++;
}
cout << a << " " << b << " " << c << endl;
A. 100,100,100
B. 100,99,99
C. 100,99,100
D. 100,99,0
解析:这里c = c++等价于temp = c; c = c + 1; c = temp;因此每次循环,c的值都是0。
60、(单选)以下程序运行结果是(B)
int main()
{
double alpha[][4] = {{0}, {1,2}, {3,4,5}};
cout << sizeof(alpha)/ sizeof(double);
}
A. 6
B. 12
C. 4
D. 1
double alpha[][4] = {{0}, {1, 2}, {3, 4, 5}};
cout << sizeof(alpha)<<endl; // 总数96
cout << sizeof(double)<<endl; // 大小8
cout << sizeof(alpha) / sizeof(double) <<endl; // 个数12.3行4列
const char* p[] = {“abcd”**, “defd”, “rstd”, “xyzd”};
cout<<sizeof§<<endl; // 总数 32
cout<<sizeof(const char*)<<endl; // 大小8
61、(单选)下面代码段输出结果是(C)
int main()
{
int i = 0;
int j = 0;
for (i=100; i>=0; i--) {
for (j=100;j==0; j--) {
i= j;
}
}
cout << i << " " << j << endl;
return 0;
}
A、100 100
B、0 100
C、-1 100
D、死循环
第二个for循环中 j==0一直不成立 所以j一直是100
62、(单选)以下程序输出的结果是(C)
string a=“abc”, b=“bc”, c=“bbc”;
cout << (a<b)
cout << (b<c)
A. 0 0
B. 0 1
C. 1 0
D. 1 1
63、(单选)以下程序打印结果为(A)
int main()
{
int a=10,b=10;
float beta=5.2e1;
std::cout<<(a=static_cast<int>(beta));
std::cout<<a;
std::cout<<(static_cast<float>(b));
}
A. 525210
B. 52.5210.
C. 525210.
D. 52.52.10
无论float还是double,如果小数位没有值,就会自动省略小数点,显示成一个整数
64、(单选)以下代码输出()
#include<iostream>
using namespace std;
int main()
{
bool *p = new bool[3];
for (int i= 0; i < 3; ++i) {
cout<<p[i]<<endl;
}
return0;
}
A. 0
B. 1
C. 输出结果不确定
D. 程序运行报错
局部变量申明后未初始化
65、(单选)以下代码输出
#include <iostream>
using namespace std;
int main()
{
bool *ome = new bool[3];
for (int i = 0; i < 3; i++) {
cout << ome[i];
}
delete[] ome;
}
运行结果为:©
A. 输出falsefalsefalse
B. 输出000
C. 输出不可预期数据
D.编译错误
虽然作者的测试用例多次编译,多次运行均为000,但从不少热心同事的回复来看,大家验证出来的结果是不确定,考虑到有可能和自己的测试环境相关,本题参考答案改为大家倾向较大的C。
66、(单选)以下代码的输出结果是(C)
int alpha = 3;
const int* beta;
beta = α
*beta = 1;
std::cout << alpha << endl;
A. 3
B. 1
C. 编译错误
D. 随机值
beta是个常量指针,指针变量指向一个常量,指针指向的值不能改变,指针本身的值可以改变,也就是指针的指向可以改变Int* const beta,这个就是指针常量,指向一个变量,指针本身的值不可以改变(指向不能变),所指向的值可以改变
67、(单选)以下代码的输出结果是(C)
const char* alpha = “alpha”;
cout << alpha + 3;
A. alpha
B. alp
C. ha
D. pha
打印输出 “ha”
备注:如果不确定可以推断如果cout << alpha + 0 那应该就是全部输出
68、(单选)上述代码打印输出和下面哪个输出是一样的?()
#include <map>
#include <iostream>
using namespace std;
class AlmProcessUnit {};
int main() {
using AlmUnitMapType = map<int, AlmProcessUnit*>;
AlmUnitMapType almUnitMap;
almUnitMap.insert({1, new AlmProcessUnit()});
for (auto it : almUnitMap) {
cout << typeid(it.second).name() << endl;
}
return 0;
}
A. cout << typeid(int* ).name() << endl;
B. cout << typeid(AlmProcessUnit*).name() << endl;
C. cout << typeid(AlmProcessUnit).name() << endl;
D. cout << typeid(AlmUnitMapType::iterator).name() << endl;
typeid(AlmProcessUnit*).name()
typeid用于返回指针或引用所指对象的实际类型
69、(单选)下列程序的Test(3)运行结果是(D)
int Test(int i)
{
i--;
if(i <= 0 || i > 2) {
return 0;
} else {
static int y = Test(i);
return (y+1);
}
}
A. 0
B. 1
C. 2
D. 未定义
recursive_init_error,不能重复初始化同一个static变量
70、(单选)下列程序的运行结果是( A)
bool T(char c)
{
cout<<c;
return true;
}
bool F(char c)
{
cout<<c;
return false;
}
int main()
{
T('A') && T('B');
F('C') && T('D');
return 0;
}
A. ABC
B. ABCD
C. ABD
输出ABC
F(‘C’)输出false就不往后执行了
总结
未完待续