在()情况下适宜采用 inline 定义内联函数
A 函数体含有循环语句 B 函数体含有递归语句
C 函数代码少、频繁调用 D 函数代码多,不常调用
内联函数的概念:
以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。
内联函数的特性:
(1)inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率
(2)inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。
下图为《C++prime》第五版关于inline的建议:
(3)inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。
内联函数举例:
#include
using namespace std;
// 声明内联函数
inline int Max(int a, int b) {
return a > b ? a : b;
}
int main() {
int x = 5;
int y = 10;
int max_value = Max(x, y); // 直接调用内联函数
std::cout << "The maximum value is: " << max_value << std::endl;
return 0;
}
所以在编译阶段,会将内联函数展开,将函数直接使用函数体来替换。这样子可以减少调用函数压栈及创建栈帧等开销。一般内联函数没有循环、递归且不是很长。
答案选:C
内联函数在以下场景中最有用的()
A 当函数代码较长且多层嵌套循环的时候
B 当函数中有较多的静态变量的时候
C 当函数代码较小并且被频繁调用的时候
D 以上都不对
从上面的解释可以得到,内联函数不适合在循环、递归且代码很长的时候使用,且在当函数代码较小并且被频繁调用的时候,内联函数最有用。
答案选:C
在 C++ 语言中,对函数参数默认值描述正确的是()
A 函数带默认值的参数只能有一个
B 一个函数的参数若有多个,则参数默认值的设定可以不连续
C 函数参数必须设定默认值
D 在设定了参数的默认值后,该参数后面定义的所有参数都必须设定默认值
缺省参数概念:
缺省参数是声明或定义函数时为函数的参数指定一个缺省值。在调用该函数时,如果没有指定实参则采用该形参的缺省值,否则使用指定的实参。
缺省参数分类:
(1)全缺省参数
void Func(int a = 10, int b = 20, int c = 30)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
(2)半缺省参数
void Func(int a, int b = 10, int c = 20)
{
cout<<"a = "<<a<<endl;
cout<<"b = "<<b<<endl;
cout<<"c = "<<c<<endl;
}
缺省参数也有很多的注意事项:
1.半缺省参数必须从右往左依次来给出, 不能间隔着给
2.缺省参数不能在函数声明和定义中同时出现
3.缺省值必须是常量或者全局变量
4.C语言不支持(编译器不支持)
//a.h
void Func(int a = 10);
// a.cpp
void Func(int a = 20)
{}
// 注意:如果生命与定义位置同时出现,恰巧两个位置提供的值不同,
// 那编译器就无法确定到底该用那个缺省值。
所以根据上面的内容,函数的缺省参数可以没有默认值或者有多个默认值,如果有默认值必须从右往左依次来给,如果参数有默认值,那么这个参数后面定义的所有参数都必须设定默认值。
答案选:D
关于重载函数,哪个说明是正确的()
A 函数名相同,参数类型或个数不同 B 函数名相同,返回值类型不同
C 函数名相同,函数内部实现不同 D 函数名称不同
函数重载概念:
函数重载: 是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同 ,常用来处理实现功能类似数据类型不同的问题。
函数重载中三种参数不同的实现方式:
#include
using namespace std;
// 1、参数类型不同
int Add(int left, int right)
{
cout << "int Add(int left, int right)" << endl;
return left + right;
}
double Add(double left, double right)
{
cout << "double Add(double left, double right)" << endl;
return left + right;
}
// 2、参数个数不同
void f()
{
cout << "f()" << endl;
}
void f(int a)
{
cout << "f(int a)" << endl;
}
// 3、参数类型顺序不同
void f(int a, char b)
{
cout << "f(int a,char b)" << endl;
}
void f(char b, int a)
{
cout << "f(char b, int a)" << endl;
}
函数重载举例:
#include
// 函数重载一:无参数
void display() {
std::cout << "Hello, World!" << std::endl;
}
// 函数重载二:带一个整数参数
void display(int num) {
std::cout << "Displaying number: " << num << std::endl;
}
// 函数重载三:带两个整数参数
void display(int num1, int num2) {
std::cout << "Displaying numbers: " << num1 << " and " << num2 << std::endl;
}
int main() {
// 调用无参数的 display 函数
display();
// 调用带一个整数参数的 display 函数
display(5);
// 调用带两个整数参数的 display 函数
display(3, 7);
return 0;
}
函数重载是在相同的作用域中,函数的名字相同,参数列表不同实现的,其中参数列表不同有 (1.参数个数不同、2.参数类型不同、3.参数类型次数不同) 与函数的返回值和内部实现都没有关系。
答案选:A
不能作为重载函数的调用的依据是:
A 参数个数 B 参数类型
C 函数类型 D 函数名称
和上面的内容一样,函数重载是在相同的作用域中,函数的名字相同,参数列表不同实现的,其中参数列表不同有 (1.参数个数不同、2.参数类型不同、3.参数类型次数不同) 与函数的返回值和内部实现都没有关系。
答案选:C
下面关于类定义的说法中,正确的是:
A 类定义中包括数据成员和函数成员的声明
B 类成员的缺省访问权限是保护的
C 数据成员必须被声明为私有的
D 成员函数只能在类体外进行定义
类的定义的概念:
class为定义类的关键字,ClassName为类的名字,{}中为类的主体, 注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。
class className
{
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
类包含数据成员(变量)和函数成员(方法)。 在类定义中,我们可以声明数据成员和函数成员。类成员的缺省访问权限是按照声明顺序决定的,在类体内部声明的成员默认是公有(public)的。
数据成员的访问权限可以是公有(public)、保护(protected)或私有(private),具体取决于设计需求。通常情况下,为了控制对数据成员的访问,我们可以将数据成员声明为私有(private),然后通过公有(public)的函数成员来访问它们。
成员函数可以在类体内进行定义,也可以在类体外进行定义。 在类体内部定义的成员函数默认是inline函数,而在类体外部定义的成员函数需要通过作用域限定符来访问。
答案选:A
类定义的外部,一定可以被访问的成员有( )
A 所有类成员 B private或protected的类成员
C public的类成员 D public或private的类成员
在C++中,类的成员有公有(public)、保护(protected)和私有(private)三种访问权限。 公有成员可以在类的外部直接访问,而保护和私有成员只能在类的内部或派生类中访问。类定义的外部,一定可以被访问的成员是public的类成员。在类定义的外部,只有公有成员是可以被直接访问的。
答案选:C
用class关键字定义的类,其成员默认的访问属性为()
A private B protected
C public D 无定义
在class中,成员的默认访问属性为private。
答案选:A
解题思路:
使用vector
#include
#include
using namespace std;
int main()
{
int w,h,res = 0;
cin >> w >> h;
vector<vector<int>> a;
a.resize(w);
for(auto& e : a)
e.resize(h, 1);
for(int i=0;i<w;i++)
{
for(int j=0;j<h;j++)
{
if(a[i][j]==1)
{
res++;
// 标记不能放蛋糕的位置
if((i+2)<w)
a[i+2][j] = 0;
if((j+2)<h)
a[i][j+2] = 0;
}
}
}
cout << res;
return 0;
}
解题思路:
就是上次计算的结果*10,相当于10进制进位,然后加当前位的值。但是要注意:空字符串、正负号处理、数字串中存在非法字符。
class Solution {
public:
int StrToInt(string str)
{
if(str.empty())
return 0;
int symbol = 1;
if(str[0] == '-') //处理负号
{
symbol = -1;
str[0] = '0'; //这里是字符'0',不是0
}
else if(str[0] == '+') //处理正号
{
symbol = 1;
str[0] = '0';
}
int sum = 0;
for(int i=0;i<str.size();++i)
{
if(str[i] < '0' || str[i] > '9')
{
sum = 0;
break;
}
sum = sum *10 + str[i] - '0';
}
return symbol * sum;
}
};
解题思路:
本题可以通过先找到距离N最近的两个Fibonacci数,这两个数分别取自距离N的最近的左边一个数L和右边一个数R,然后通过min(N - L, R - N)找到最小步数。
#include
using namespace std;
int main()
{
int N, f, l = 0,r = 0,f0 = 0,f1 = 1;
cin >> N;
while(1)
{
f = f0 + f1;
f0 = f1;
f1 = f;
//找到比N小且距离N最近的数,求出距离
if(f < N)
l = N-f;
else
{
//找到比N大且距离N最近的数,求出距离
r = f - N;
break;
}
}
//取最小距离
cout << min(l,r) << endl;
return 0;
}
解题思路:
用栈结构实现,栈中存放左括号,当遇到右括号之后,检查栈中是否有左括号,如果有则出栈,如果没有,则说明不匹配。
class Parenthesis {
public:
bool chkParenthesis(string A, int n) {
stack<char> sc;
for (auto ele : A)
{
switch (ele)
{
case '(':
sc.push(ele);
break;
case ')':
{
if (sc.empty() || sc.top() != '(')
return false;
else
sc.pop();
}
break;
default:
return false;
}
}
return true;
}
};