【C/C++笔试练习】内联函数、缺省参数、函数重载、类定义、不要二、字符串转成整数、Fibonacci数列、合法括号序列判断

C/C++笔试练习

1.内联函数

(1)内联函数的使用

  在()情况下适宜采用 inline 定义内联函数

  A 函数体含有循环语句      B 函数体含有递归语句

  C 函数代码少、频繁调用     D 函数代码多,不常调用

  
  内联函数的概念:

  以inline修饰的函数叫做内联函数,编译时C++编译器会在调用内联函数的地方展开,没有函数调用建立栈帧的开销,内联函数提升程序运行的效率。

  
  内联函数的特性:

  (1)inline是一种以空间换时间的做法,如果编译器将函数当成内联函数处理,在编译阶段,会用函数体替换函数调用,缺陷:可能会使目标文件变大,优势:少了调用开销,提高程序运行效率

  (2)inline对于编译器而言只是一个建议,不同编译器关于inline实现机制可能不同,一般建议:将函数规模较小(即函数不是很长,具体没有准确的说法,取决于编译器内部实现)、不是递归、频繁调用的函数采用inline修饰,否则编译器会忽略inline特性。

  下图为《C++prime》第五版关于inline的建议:

在这里插入图片描述

  (3)inline不建议声明和定义分离,分离会导致链接错误。因为inline被展开,就没有函数地址了,链接就会找不到。

  
  内联函数举例:

#include <iostream>
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

  

(2)内联函数的使用

  内联函数在以下场景中最有用的()

  A 当函数代码较长且多层嵌套循环的时候

  B 当函数中有较多的静态变量的时候

  C 当函数代码较小并且被频繁调用的时候

  D 以上都不对

  
  从上面的解释可以得到,内联函数不适合在循环、递归且代码很长的时候使用,且在当函数代码较小并且被频繁调用的时候,内联函数最有用。

   答案选:C

                 

2.缺省参数

(3)缺省参数概念理解

  在 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

                 

3.函数重载

(4)函数重载的定义

  关于重载函数,哪个说明是正确的()

  A 函数名相同,参数类型或个数不同  B 函数名相同,返回值类型不同

  C 函数名相同,函数内部实现不同     D 函数名称不同

  
  函数重载概念:

  函数重载: 是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数这些同名函数的形参列表(参数个数 或 类型 或 类型顺序)不同 ,常用来处理实现功能类似数据类型不同的问题。

  函数重载中三种参数不同的实现方式:

#include<iostream>
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 <iostream>  
  
// 函数重载一:无参数  
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

  

(5)函数重载的定义

  不能作为重载函数的调用的依据是:

  A 参数个数      B 参数类型

  C 函数类型     D 函数名称

  
  和上面的内容一样,函数重载是在相同的作用域中,函数的名字相同,参数列表不同实现的,其中参数列表不同有 (1.参数个数不同、2.参数类型不同、3.参数类型次数不同) 与函数的返回值和内部实现都没有关系。

   答案选:C

                 

4.类定义

(6)类定义访问限定符

  下面关于类定义的说法中,正确的是:

  A 类定义中包括数据成员和函数成员的声明

  B 类成员的缺省访问权限是保护的

  C 数据成员必须被声明为私有的

  D 成员函数只能在类体外进行定义

  

类和对象中类的定义和访问限定符

   类的定义的概念:

   class为定义类的关键字,ClassName为类的名字,{}中为类的主体, 注意类定义结束时后面分号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者成员函数。

class className
{
	// 类体:由成员函数和成员变量组成
 
}; // 一定要注意后面的分号

  
  类包含数据成员(变量)和函数成员(方法)。 在类定义中,我们可以声明数据成员和函数成员。类成员的缺省访问权限是按照声明顺序决定的在类体内部声明的成员默认是公有(public)的。

  数据成员的访问权限可以是公有(public)、保护(protected)或私有(private),具体取决于设计需求。通常情况下,为了控制对数据成员的访问,我们可以将数据成员声明为私有(private),然后通过公有(public)的函数成员来访问它们。

  成员函数可以在类体内进行定义,也可以在类体外进行定义。 在类体内部定义的成员函数默认是inline函数,而在类体外部定义的成员函数需要通过作用域限定符来访问。

   答案选:A

  

(7)类定义访问限定符

  类定义的外部,一定可以被访问的成员有( )

  A 所有类成员         B private或protected的类成员

  C public的类成员     D public或private的类成员

  
  在C++中,类的成员有公有(public)、保护(protected)和私有(private)三种访问权限。 公有成员可以在类的外部直接访问,而保护和私有成员只能在类的内部或派生类中访问。类定义的外部,一定可以被访问的成员是public的类成员。在类定义的外部,只有公有成员是可以被直接访问的。

   答案选:C

  

(8)类定义访问限定符

  用class关键字定义的类,其成员默认的访问属性为()

  A private      B protected

  C public       D 无定义

  
  在class中,成员的默认访问属性为private。

   答案选:A

                 

5.编程题

day6

(9)不要二

不要二

  解题思路:

  使用vector<vector>定义一个二维数组,resize开空间并初始化,每个位置初始化为1,表示当蛋糕,a[i][j]位置放蛋糕,则可以标记处a[i][j+2]和a[i+1][j]位置不能放蛋糕,遍历一遍二维数组,标记处不能放蛋糕的位置,统计也就统计出了当蛋糕的位置数。

#include<iostream>
#include<vector>
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,相当于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;
	}
};

                 

day7

(11)Fibonacci数列

Fibonacci数列

   解题思路:

   本题可以通过先找到距离N最近的两个Fibonacci数,这两个数分别取自距离N的最近的左边一个数L和右边一个数R,然后通过min(N - L, R - N)找到最小步数。

#include <iostream>
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;
}

  

(12)合法括号序列判断

合法括号序列判断

   解题思路:

   用栈结构实现,栈中存放左括号,当遇到右括号之后,检查栈中是否有左括号,如果有则出栈,如果没有,则说明不匹配。

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;
	}
};
  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 18
    评论
评论 18
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

鳄鱼麻薯球

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值