C/C++公共基础练习题及答案
一、程序题
C++的HelloWorld!

#include <iostream>
using std::cout;
using std::endl;
int main()
{
cout << "Hello,World!" << endl;
return 0;
}输入一个圆半径( r )当r>=0时,计算并输出圆的面积和周长,如果r<0输出input error字符串。(PI取3.14159)

#include <iostream>
#include <stdlib.h>
#define PI (3.14159)
using std::cout;
using std::cin;
using std::endl;
int main()
{
double r;
cout << "请输入圆的半径:";
cin >> r;
if (r < 0)
{
cout << "input error" << "\n";
}
else {
double area = PI * r * r;
double perimeter = 2 * PI * r;
cout << "圆的面积为:" << area << endl;
cout << "圆的周长为:" << perimeter << endl;
}
system("pause");
return 0;
}
输入10个整形数,并按从小到大输出这10个数。

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int main() {
const int N = 10;
int nums[N];
cout << "请输入10个整数:" << endl;
for (int i = 0; i < N; i++) {
cin >> nums[i];
}
for (int i = 0; i < N - 1; i++) {
for (int j = 0; j < N - i - 1; j++) {
if (nums[j] > nums[j + 1]) {
int temp = nums[j];
nums[j] = nums[j + 1];
nums[j + 1] = temp;
}
}
}
cout << "从小到大排序后的结果为:" << endl;
for (int i = 0; i < N; i++) {
cout << nums[i] << " ";
}
cout << endl;
return 0;
}
如果一个 3 位数等于其各位数字的立方和,则称这个数为水仙花数。
例如:153 = 1^3 + 5^3 + 3^3,因此 153 就是一个水仙花数 编写程序打印出所有的水仙花数

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
int main()
{
for (int i = 100; i < 1000; i++)
{
int digit1 = i / 100;
int digit2 = (i / 10) % 10;
int digit3 = i % 10;
if (i == digit1 * digit1 * digit1 + digit2 * digit2 * digit2 + digit3 * digit3 * digit3)
{
cout << i << endl;
}
}
return 0;
}
将Shandong University of Technology字符串实现逆序输出(用数组)

#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;
int main()
{
char str[] = "Shandong University of Technology";
int length = sizeof(str)/sizeof(str[0]);
for (int i = length - 1; i >= 0; i--)
{
cout << str[i];
}
cout << endl;
return 0;
}
定义一个返回值是float的函数,输入圆的半径,计算圆的面积。并在主函数内输出该函数计算出的面积。(用宏定义 pi = 3.14159)

#include <iostream>
#define PI 3.14159
using std::cout;
using std::cin;
using std::endl;
float calculateArea(int radius); //声明函数
int main()
{
int radius;
cout << "请输入圆的半径:";
cin >> radius;
auto area = calculateArea(radius); //调用函数
cout << "圆的面积为:" << area << endl;
return 0;
}
float calculateArea(int radius) //定义函数
{
float Area = PI * radius * radius;
return Area;
}
定义函数fun的功能是:根据输入的三个边长(整型值),判断能否构成三角形;构成的是等边三角形,还是等腰三角形。若能构成等边三角形函数返回3,若能构成等腰三角形函数返回2,若能构成三角形函数返回1,若不能构成三角形函数返回0。
并调用该函数实现判断三角形的功能:例如,输入的值为" 3 4 5 ",则输出为" 1 ",若输入的值为" 3 5 9 ",则输出的值为" 0 "。

#include <iostream>
using namespace std;
int fun(int x,int y,int z);
int main()
{
int x,y,z,shape;
cout << "\n请输入x,y,z: " << endl;
cin >> x >> y >> z;
shape=fun(x,y,z);
cout << "\n类型是:" << shape << endl;
return 0;
}
int fun(int x,int y,int z)
{
if(x+y>z&&y+z>x&&x+z>y)
{
if(x==y&&y==z)
return 3;
else if(x==y||y==z||x==z)
return 2;
else
return 1;
}
else
return 0;
}
输入n(奇数)个数,这n个数用scanf或者cin输入,要求输入的所有元素中, 其中只有一个数出现了奇数次,其他数都出现了偶数次,请找出这个数。(提示:位操作符)

#include <iostream>
using namespace std;
int main()
{
int n;
cout << "请输入n的值:";
cin >> n;
int result = 0;
for (int i = 0; i < n; i++) {
int num;
cout << "请输入第" << i+1 << "个数:";
cin >> num;
result ^= num;
}
cout << "出现奇数次的数是:" << result << endl;
return 0;
}与运算符(&)
与运算符对两个操作数的每一位执行逻辑与操作。只有当两个对应位都为1时,结果位才为1,否则为0。
或运算符(|)
或运算符对两个操作数的每一位执行逻辑或操作。只要有一个对应位为1,结果位就为1。
异或运算符(^)
异或运算符对两个操作数的每一位执行逻辑异或操作。当两个对应位不同,结果位为1;相同,结果位为0。
^运算符满足交换律和结合律。
取反运算符(~)
取反运算符对操作数的每一位执行逻辑取反操作。0变1,1变0。
左移运算符(<<)
左移运算符将操作数的所有位向左移动指定的位数,右边补0。左移n位相当于乘以2的n次方。
示例:
int a = 5; // 二进制: 0000 0101
int b = a << 1; // 左移1位,结果: 0000 1010,即10
右移运算符(>>)
右移运算符将操作数的所有位向右移动指定的位数。对于无符号数,左边补0;对于有符号数,补符号位(算术右移)或补0(逻辑右移)。
示例:
int a = 5; // 二进制: 0000 0101
int b = a >> 1; // 右移1位,结果: 0000 0010,即2
题目:使用C语言的头文件stdio.h中的scanf(如果编译器报错用scanf_s)和printf在.cpp文件中进行混合编程,需要输入一个浮点型数a,并打印该浮点型数并保留2位小数。

#include <stdio.h>
int main()
{
float x;
scanf_s("%f",&x);
printf("%.2f",x);
return 0;
}
//scanf_S是Microsoft在win中使用的一种更安全的输入函数,相比scanf 可以避免内存溢出的风险题目:创建一个命名空间ns1,在该命名空间中有一个函数swap,他的作用是交换两个数的值,返回值是void。请调用这个函数,交换两个数的值。

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
namespace ns1
{
void swap(int *a,int *b);
}
int main()
{
int x , y;
cout << "X:";
cin >> x;
cout << "Y:";
cin >> y;
ns1::swap(&x,&y);
cout << "交换后:\nX=" << x << "\nY=" << y << endl;
return 0;
}
void ns1::swap(int *a,int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
}**题目:请使用联合体来完成输入一个字母,并打印他的ascii码。 **

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
union Convert
{
int asc;
char letter;
};
typedef Convert con;
con con__; //有的编译器需要初始化后三个字节,所以需要用全局变量。
int main()
{
cin >> con__.letter;
cout << con__.asc << endl;
return 0;
}这里体现了联合体公用一块内存,以及小端存储的特性:
假如当cin输入一个字符c时,由于c的ascii码为99,其在内存中的顺序为:
99 00 00 00(十六进制格式)
当读取时,由于letter和asc共用一块内存,char占1字节,int占4字节,但是因为是小端存储,排在前面的是低地址位,所以读取出来的是0x000099,故输出的为99,即ascii码
假如是大端存储,那么读取出来的就是0x99000000,即1660944384
题目:编写一个自己的库(.cpp和.h) :请创建一个文件out_test.cpp,请在该文件中定义一个短整型变量a,并赋值5,在该文件中继续定义一个函数print_short(short int x),该函数的功能是打印一个短整型变量。请在主函数中调用out_test.cpp中的print_short函数并打印变量a。

主函数****main.cpp:
#include <iostream>
#include "out_test.h"
// using std::cout;
// using std::cin;
// using std::endl;
extern short int a;
int main()
{
print_short(a);
return 0;
}out_test.cpp:
#include "out_test.h"
short int a = 5;
void print_short(short int x)
{
std::cout << x << endl;
}out_test.h:
#ifndef __OUT_TEST_H_ //条件编译,选写,建议以后学习用条件编译
#define __OUT_TEST_H_ //条件编译,选写,建议以后学习用条件编译
#include <iostream>
void print_short(short int x);
#endif //条件编译,选写,建议以后学习用条件编译**题目: 请创建一个结构体student_stru,其有2个成员变量name和math_score,一个存姓名,一个存数学分数,请在主函数中用****stu student1;**创建一个结构体变量student1(需要用typedef),然后name赋值李华,math_score赋值70。然后创建一个函数change_score,返回值为void,该函数的作用是把math_score改成80,把姓名改成李丽。然后在主函数先打印没调用该函数之前的结果,然后再调用该函数,并在主函数中打印调用函数后的name和math_score。

#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;
typedef struct student_stru
{
std::string name;
float math_score;
}stu; //这里注意区分C&C++在结构体定义上的细微差别
void change_score(stu *ps);
int main()
{
stu student1;
student1.name = "李华";
student1.math_score = 70;
cout << "调用函数前:" << endl;
cout << student1.name << "的数学成绩是" << student1.math_score << endl;
change_score(&student1);
cout << "调用函数后:" << endl;
cout << student1.name << "的数学成绩是" << student1.math_score << endl;
return 0;
}
void change_score(stu *ps)
{
ps->name = "李丽";
ps->math_score = 80;
}在许多数据协议中,数据串都是以字节(uint8_t)为单位发送的。但是1个字节的数据只能存放8位二进制数据,有的数据需要16位甚至更多二进制才能存放,所以我们在传送一个数据的时候,通常要连续发送若干个字节,这若干个字节构成一个数据。 现在,我们需要处理我们接收到的数据串,一共有2个字节,该协议规定,第一个字节为数据的高8位(DH),第二个字节为数据的低8位(DL)。请创建一个函数 ' int16_t data_calc(uint8_t DH,uint8_t DL) ' ,该函数的作用是将这两个字节的数据串,进行数据处理,处理成一个有符号短整型(int16_t)的数据。DH我们规定是0x50,DL是0x2E。[tips: uint8_t就是unsigned char的别名,int16_t就是short int的别名,都是由typedef关键字起别名而来,C++头文件中自带该别名,可以直接使用]

#include <iostream>
#include <ios> //hex和dec是该头文件下的std命名空间中的
using std::cout;
using std::cin;
using std::endl;
/* 常用的别名(部分C++自带,不用咱们写)
typedef unsigned char byte;
typedef unsigned char uint8_t;
typedef short int int16_t;
typedef float fp32;
typedef double fp64;
*/
int16_t data_calc(uint8_t DH,uint8_t DL);
int main()
{
uint8_t DH = 0x50,DL = 0x2E;
cout << "高8位DH:";
cout << std::hex << "0x" << (int)DH << endl;
cout << "低8位DL:";
cout << std::hex << "0x" << (int)DL << endl; //此行的hex可以不写
auto DATA = data_calc(DH,DL);
cout << "经数据处理后的结果是:" << std::dec << DATA << "\n";
return 0;
}
int16_t data_calc(uint8_t Data_H,uint8_t Data_L)
{
int16_t Data = (int16_t)((int16_t)Data_H << 8 | Data_L);
return Data;
}C++函数重载:定义3个的函数print,一个print用来打印整形,第二个用来打印双精度浮点数,第三个用来打印字符串。

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
/* 常用的别名(部分C++自带,不用咱们写)
typedef unsigned char byte;
typedef unsigned char uint8_t;
typedef short int int16_t;
typedef float fp32;
typedef double fp64;
*/
void print(int i);
void print(double f);
void print(char c[]);
int main()
{
int x;
double y;
char z[50];
cout << "请输入整形X:";
cin >> x;
cout << "请输入双精度浮点形Y:";
cin >> y;
cout << "请输入字符串Z:";
cin >> z;
cout << "以下是调用print函数打印的结果:" << endl;
print(x);
print(y);
print(z);
return 0;
}
void print(int i)
{
cout << "整数为: " << i << endl;
}
void print(double f)
{
cout << "双精度浮点数为: " << f << endl;
}
void print(char c[])
{
cout << "字符串为: " << c << endl;
}
函数模板:定义1个的函数模板print,使该函数模板完成上一题的要求。

#include <iostream>
#include <ios>
using std::cout;
using std::cin;
using std::endl;
/* 常用的别名(部分C++自带,不用咱们写)
typedef unsigned char byte;
typedef unsigned char uint8_t;
typedef short int int16_t;
typedef float fp32;
typedef double fp64;
*/
template<typename T>
void print(T a)
{
cout << a << endl;
}
int main()
{
int x;
double y;
char z[50];
cout << "请输入整形X:";
cin >> x;
cout << "请输入双精度浮点形Y:";
cin >> y;
cout << "请输入字符串z:";
cin >> z;
cout << "以下是调用print函数打印的结果:" << endl;
cout << "整数为: ";
print(x); //第一种调用方式:不指定T的类型,由编译器自己推导出来T是int
cout << "双精度浮点数为: ";
print<double>(y); //第二种调用方式:指定类型的调用方式
cout << "字符串为: ";
print<char *>(z); //这个地方一定是 char* 类型的
return 0;
}
内存管理:请用不定长数组,完成以下要求:输入已知数量的若干的整数,并打印出其相加后的结果。

#include <iostream>
using std::cout;
using std::cin;
using std::endl;
/* 常用的别名(部分C++自带,不用咱们写)
typedef unsigned char byte;
typedef unsigned char uint8_t;
typedef short int int16_t;
typedef float fp32;
typedef double fp64;
*/
int main()
{
int n;
int sum = 0;
cout << "输入数组元素数量n:";
cin >> n;
int *arr = new int[n];
for(int i = 0;i < n;i++)
{
cout << "请输入第" << i+1 << "个数的值:";
cin >> arr[i];
sum += arr[i];
}
cout << "结果是:" << sum << endl;
delete []arr;
return 0;
}
智能指针**:创建一个结构体stu,内有成员name和math_score,一个存放名字,一个存放数学成绩。请使用智能指针创建一个结构体指针变量pstudent,并使用指针给该结构体变量中的成员变量赋值,并打印出来。**

#include <iostream>
#include <memory>
#include <string>
using std::cout;
using std::cin;
using std::endl;
struct stu
{
std::string name;
float math_score;
};
int main()
{
auto pstudent = std::make_shared<stu>();
(*pstudent).name = "小明"; //第一种调用方法
pstudent->math_score = 90; //第二种调用方法
cout << pstudent->name << "的数学分数为" << pstudent->math_score << endl;
return 0;
}class(类):请创建一个class circle(圆类),该类通过构造函数传入双精度浮点数类型的半径参数,有两个公开(public)的方法,分别是print_circumference()和print_area(),第一个方法用来打印圆的周长,第二个方法用来打印圆的面积,该类还有析构函数用来打印字符串“析构函数运行完毕!”。请使用该类计算一个圆的周长和面积,并打印。(圆周率取3.1415926)

#include <iostream>
#define pi (3.1415926)
using std::cout;
using std::cin;
using std::endl;
/* 常用的别名(部分C++自带,不用咱们写)
typedef unsigned char byte;
typedef unsigned char uint8_t;
typedef short int int16_t;
typedef float fp32;
typedef double fp64;
*/
class circle
{
public:
circle(double r);
~circle(void);
void print_circumference();
void print_area();
private:
double radius;
};
int main()
{
double r1;
cout << "请输入圆的半径r:";
cin >> r1;
circle cir1(r1);
cir1.print_circumference();
cir1.print_area();
return 0;
}
circle::circle(double r)
{
this->radius = r;
}
circle::~circle(void)
{
cout << "析构函数运行完毕!" << endl;
}
void circle::print_circumference()
{
double circumference = 2 * this->radius * pi;
cout << "圆的周长是:" << circumference << endl;
}
void circle::print_area()
{
double area = this->radius * this->radius * pi;
cout << "圆的面积是:" << area << endl;
}
智能指针:请用shared_ptr创建一个上一题的类对象指针,并使用指针来完成上一题的要求。

#include <iostream>
#include <memory>
#define pi (3.1415926)
using std::cout;
using std::cin;
using std::endl;
/* 常用的别名(部分C++自带,不用咱们写)
typedef unsigned char byte;
typedef unsigned char uint8_t;
typedef short int int16_t;
typedef float fp32;
typedef double fp64;
*/
class circle
{
public:
circle(double r);
~circle(void);
void print_circumference();
void print_area();
private:
double radius;
};
int main()
{
double r1;
cout << "请输入圆的半径r:";
cin >> r1;
auto cir1_ptr = std::make_shared<class circle>(r1);
cir1_ptr->print_circumference();
cir1_ptr->print_area();
return 0;
}
circle::circle(double r)
{
this->radius = r;
}
circle::~circle(void)
{
cout << "析构函数运行完毕!" << endl;
}
void circle::print_circumference()
{
double circumference = 2 * this->radius * pi;
cout << "圆的周长是:" << circumference << endl;
}
void circle::print_area()
{
double area = this->radius * this->radius * pi;
cout << "圆的面积是:" << area << endl;
}
混合编译
写一个C语言的工程,但是要求调用C++的库。
主函数写在main.c文件中,然后新建两个C++的库,分别是main_inherit.cpp、main_inherit.h和test_lib.cpp,test_lib.h。
test_lib库用来定义一个命名空间叫ns_demo,该命名空间里有一个swap函数,返回值是void,用来交换两个整形的值。
main_inherit库里定义一个main_mix_com函数,该函数会被main函数调用,该函数的作用是输入X,Y的值,并调用test_lib库里的swap函数进行交换X,Y的值,最后打印X,Y的值。
main.c中用来调用main_mix_com函数。

main.c(注意这里是.c不是.cpp)
#include <stdio.h>
#include "main_inherit.h"
int main()
{
main_mix_com();
return 0;
}
main_inherit.cpp
#include "main_inherit.h"
#include "test_lib.h"
#include <iostream>
void main_mix_com(void)
{
int a;
int b;
std::cout << "请输入a:" << std::endl;
std::cin >> a;
std::cout << "请输入b:" << std::endl;
std::cin >> b;
ns_demo::swap(&a, &b);
std::cout << "交换后a的值:" << a << std::endl;
std::cout << "交换后b的值:" << b << std::endl;
}main_inherit.h
#ifndef __MAIN_INHERIT_H_ //头文件防止引用重复的条件编译
#define __MAIN_INHERIT_H_ //头文件防止引用重复的条件编译
#ifdef __cplusplus //混合编译的条件编译
extern "C" //混合编译的条件编译
{ //混合编译的条件编译
#endif //混合编译的条件编译
/* 头文件内容开始 */
//头文件内容:预处理、函数声明、变量声明
void main_mix_com(void);
/* 头文件内容结束 */
#ifdef __cplusplus //混合编译的条件编译
} //混合编译的条件编译
#endif //混合编译的条件编译
#endif //头文件防止引用重复的条件编译
test_lib.cpp
#include "test_lib.h"
void ns_demo::swap(int* a, int* b)
{
int temp = *a;
*a = *b;
*b = temp;
}test_lib.h
#ifndef __TEST_LIB_H_ //头文件防止引用重复的条件编译
#define __TEST_LIB_H_ //头文件防止引用重复的条件编译
#ifdef __cplusplus //混合编译的条件编译
extern "C" //混合编译的条件编译
{ //混合编译的条件编译
#endif //混合编译的条件编译
/* 头文件内容开始 */
//头文件内容:预处理、函数声明、变量声明
namespace ns_demo
{
void swap(int* a, int* b);
}
/* 头文件内容结束 */
#ifdef __cplusplus //混合编译的条件编译
} //混合编译的条件编译
#endif //混合编译的条件编译
#endif //头文件防止引用重复的条件编译
中间部分涉及到C/C++的混合编译的问题
使用混合编译用于确保代码可以在C和C++环境下正确编译。C++编译器会将函数名进行“名称修饰”(name mangling),而C编译器不会。为了在C++中调用C函数,需要使用 extern "C" 来防止名称修饰。
友元函数
请创建一个class circle(圆类),该类通过构造函数传入双精度浮点数类型的半径参数,有一个公开(public)的方法,是print_circumference(),有三个私有(private)的变量,分别是radius(半径),cirumference(周长)和area(面积),通过该类里的方法用来计算圆的周长并把结果存放到circumference中,然后并打印circumference的值,该类还有析构函数用来打印字符串“析构函数运行完毕!”。然后新建一个外部函数print_area(),使该函数是该类的友元函数,通过该函数可以计算圆的面积,并把结果存放到上面类中的area变量中,并打印area变量。
请创建一个类对象,然后打印周长和面积。

#include <iostream>
#define pi (3.1415926)
using std::cout;
using std::cin;
using std::endl;
/* 常用的别名(部分C++自带,不用咱们写)
typedef unsigned char byte;
typedef unsigned char uint8_t;
typedef short int int16_t;
typedef float fp32;
typedef double fp64;
*/
class circle
{
public:
circle(double r);
~circle(void);
void print_circumference();
friend void print_area(circle *p_cir);
private:
double radius;
double circumference;
double area;
};
int main()
{
double r1;
cout << "请输入圆的半径r:";
cin >> r1;
circle cir1(r1);
cir1.print_circumference();
print_area(&cir1);
return 0;
}
circle::circle(double r)
{
this->radius = r;
}
circle::~circle(void)
{
cout << "析构函数运行完毕!" << endl;
}
void circle::print_circumference()
{
this->circumference = 2 * this->radius * pi;
cout << "圆的周长是:" << this->circumference << endl;
}
void print_area(circle *p_cir)
{
p_cir->area = p_cir->radius * p_cir->radius * pi;
cout << "圆的面积是:" << p_cir->area << endl;
}友元类
请创建一个class circle(圆类),该类通过构造函数传入双精度浮点数类型的半径参数,有两个公开(public)的方法,分别是calc_circumference()和calc_area(); 有三个私有(private)的变量,分别是radius(半径),cirumference(周长)和area(面积)。第一个方法用来计算圆的周长并把结果存放到circumference中,不打印circumference的值,第二个方法用来可以计算圆的面积,并把结果存放到上面类中的area变量中,不打印area变量。该类还有析构函数用来打印字符串“析构函数运行完毕!”。
请再创建第二个类class big_circle(大圆类),该类是circle的友元类,里面有1个方法,用来打印circle类中circumference和area变量。

#include <iostream>
#define pi (3.1415926)
using std::cout;
using std::cin;
using std::endl;
/* 常用的别名(部分C++自带,不用咱们写)
typedef unsigned char byte;
typedef unsigned char uint8_t;
typedef short int int16_t;
typedef float fp32;
typedef double fp64;
*/
class circle
{
public:
circle(double r);
~circle(void);
void calc_circumference();
void calc_area();
friend class big_circle;
private:
double radius;
double circumference;
double area;
};
class big_circle
{
public:
void print(circle cir);
};
int main()
{
double r1;
cout << "请输入圆的半径r:";
cin >> r1;
circle cir1(r1);
big_circle big_cir1;
cir1.calc_circumference();
cir1.calc_area();
big_cir1.print(cir1);
return 0;
}
circle::circle(double r)
{
this->radius = r;
}
circle::~circle(void)
{
cout << "析构函数运行完毕!" << endl;
}
void circle::calc_circumference()
{
this->circumference = 2 * this->radius * pi;
}
void circle::calc_area()
{
this->area = this->radius * this->radius * pi;
}
void big_circle::print(circle cir)
{
cout << "圆的周长是:" << cir.circumference << endl;
cout << "圆的面积是:" << cir.area << endl;
}
运算符重载
请创建一个class circle(圆类),该类通过构造函数传入双精度浮点数类型的半径参数,有两个公开(public)的方法,分别是calc_circumference()和calc_area(); 有三个***公开(public)***的变量,分别是radius(半径),cirumference(周长)和area(面积)。第一个方法用来计算圆的周长并把结果存放到circumference中,并打印circumference的值,第二个方法用来可以计算圆的面积,并把结果存放到上面类中的area变量中,并打印area变量。该类还有析构函数用来打印字符串“析构函数运行完毕!”。
请先创建3个circle对象,cir1,cir2,cir3,并重载加法运算符,使两个类中的面积和周长都分别想加,并储存在第三个类中对应的变量中。然后在主函数中输出第三个类中的周长和面积(也用输出cout重载)。

#include <iostream>
#define pi (3.1415926)
using std::cout;
using std::cin;
using std::endl;
/* 常用的别名(部分C++自带,不用咱们写)
typedef unsigned char byte;
typedef unsigned char uint8_t;
typedef short int int16_t;
typedef float fp32;
typedef double fp64;
*/
class circle
{
public:
circle(double r);
~circle(void);
void calc_circumference();
void calc_area();
circle operator+(circle &cir)
{
circle sumcir(0);
sumcir.circumference = this->circumference + cir.circumference;
sumcir.area = this->area + cir.area;
return sumcir;
}
double radius;
double circumference;
double area;
};
std::ostream & operator<<(std::ostream &output,circle &cir)
{
output << "周长:" << cir.circumference << endl << "面积:" << cir.area;
return output;
}
int main()
{
double r1,r2,r3;
cout << "请输入第一个圆的半径r1:";
cin >> r1;
cout << "请输入第一个圆的半径r2:";
cin >> r2;
r3 = 0;
circle cir1(r1);
circle cir2(r2);
circle cir3(r3);
cir1.calc_circumference();
cir1.calc_area();
cir2.calc_circumference();
cir2.calc_area();
cir3 = cir1 + cir2;
cout << cir3 << endl;
return 0;
}
circle::circle(double r)
{
this->radius = r;
}
circle::~circle(void)
{
cout << "析构函数运行完毕!" << endl;
}
void circle::calc_circumference()
{
this->circumference = 2 * this->radius * pi;
}
void circle::calc_area()
{
this->area = this->radius * this->radius * pi;
}继承1
创建一个父类(基类) class shape,该类中有两个公开方法分别是setwidth(int w)和setheight(int h),还有两个受保护的变量,width和height。这两个方法的作用是将这两个函数的入口参数w赋值给width,h赋值给height。
再创建一个衍生类class Rectangle,该类继承父类class Shape,该类中有一个公开的方法print_area是用来计算宽乘高,并打印面积的。
请创建一个class Rectangle对象,并输入宽和高,并打印面积。

#include <iostream>
using namespace std;
// 基类
class Shape
{
public:
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};
// 派生类
class Rectangle: public Shape
{
public:
int getArea()
{
return (width * height);
}
};
int main(void)
{
Rectangle Rect;
int width, height;
cout << "输入Width:";
cin >> width;
cout << "输入Height:";
cin >> height;
Rect.setWidth(width);
Rect.setHeight(height);
// 输出对象的面积
cout << "Total area: " << Rect.getArea() << endl;
return 0;
}继承2
创建一个父类(基类) class shape,该类的构造函数有参,负责给width和height传值。其中有1个公开方法是getarea(),还有三个受保护的变量,width,height,area。方法getarea是用来输出area的值
再创建一个衍生类class Rectangle,该类继承父类class Shape,也拥有构造函数,负责给父类构造函数传参,该类中有一个公开的方法getarea是用来计算矩形,宽乘高,但是不打印面积的。
请再创建一个衍生类class Triangle,该类继承父类class Shape,有构造函数,负责直接给width和height变量传参,该类中有一个公开的方法getarea,用来计算三角形的面积,不打印。
请在主函数中在堆区创建两个对象,一个是rectangle类对象,一个是triangle类对象,分别输入宽和高,并分别输出面积。

#include <iostream>
#include <memory>
using namespace std;
// 基类
class Shape
{
public:
Shape(int w, int h)
{
width = w;
height = h;
}
void getarea()
{
cout << "面积是:" << area << endl;
}
protected:
int width;
int height;
int area;
};
// 派生类
class Rectangle : public Shape
{
public:
Rectangle(int w,int h) : Shape(w,h)
{
}
void getarea()
{
area = (width * height);
}
};
class Triangle : public Shape
{
public:
Triangle(int w,int h) : Shape(w,h)
{
}
void getarea()
{
area = (width * height / 2);
}
};
int main(void)
{
int width, height;
cout << "输入Width:";
cin >> width;
cout << "输入Height:";
cin >> height;
// Rectangle a(width, height);
Rectangle* p_Rect = new Rectangle(width, height); //两种在堆区开内存的方法
auto p_Tria = std::make_shared<Triangle>(width, height); //更推荐这种
// 计算对象面积
p_Rect->getarea();
p_Tria->getarea();
// 输出对象的面积
p_Rect->Shape::getarea();
p_Tria->Shape::getarea();
delete p_Rect; //注意第一种方式要释放内存
return 0;
}多态
(禁止使用智能指针)创建一个基类class Person,该类有构造函数,功能为打印“基类构造函数运行调用”,有一个公开的整形指针变量per_,该变量指向堆区整形地址。还有析构函数,功能为打印“基类析构函数调用”并打印per_的值,并最后释放per_。
然后创建一个派生类class Student,该类有构造函数,功能为打印“派生类构造函数运行调用”,有一个公开的整形指针变量stu_,该变量指向堆区整形地址。还有析构函数,功能为打印“派生类析构函数调用”并打印stu_的值,并最后释放stu_。
请用Person *ptr = new Student在堆区创建一个对象。然后并释放堆区内存,不要有任何内存泄露。

#include <iostream>
using namespace std;
class Person {
public:
Person()
{
cout << "基类构造函数调用!" << endl;
}
virtual ~Person()
{
cout << "基类析构函数: " << per_ << endl;
delete per_;
}
int* per_ = new int;
};
class Student :public Person {
public:
Student()
{
cout << "派生类构造函数调用!" << endl;
}
~Student()
{
cout << "派生类析构函数: " << stu_ << endl;
delete stu_;
}
int* stu_ = new int;
};
int main()
{
Person* ptr = new Student;
delete ptr;
return 0;
}类模板
创建一个MyArray类模板,该模板的功能是在堆区创建一个不定长数组,通过构造函数规定数组的长度,通过析构函数释放数组的内存。有两个私有变量,arr和index,分别表示数组0号元素的地址和数组元素的序号。还应有两个方法,一个方法用来给对应序号的数组元素赋值,另一个方法用来取出对应序号数组元素的值。
请在主函数中用智能指针创建一个该类模板,来创建一个int16_t的不定长数组,并给序号为0的数组元素赋值 并 打印序号为0的数组元素的值。

#include <iostream>
#include <memory>
using namespace std;
template <class T>
class MyArray {
private:
T* arr;
int size;
public:
MyArray(int size) {
this->size = size;
arr = new T[size];
}
~MyArray() {
delete []arr;
}
void set(int index, T value) {
arr[index] = value;
}
T get(int index) {
return arr[index];
}
};
int main()
{
int N;
cout << "请输入数组的长度N:";
cin >> N;
auto parr = std::make_shared<MyArray<int16_t>>(N);
int arr_index;
cout << "请输入要赋值的元素的序号:";
cin >> arr_index;
int16_t arr_value;
cout << "请输入对应的值:";
cin >> arr_value;
parr->set(arr_index,arr_value);
cout << "请输入要获取的数组元素的序号:";
cin >>arr_index;
auto temp = parr->get(arr_index);
cout << "0号元素的值是:" << temp << endl;
return 0;
}综合
①请定义一个叫stru_lib的库(stru_lib.cpp和stru_lib.h)。
②stru_lib库内有一个命名空间叫ns_demo。
③ns_demo命名空间中使用typedef声明定义了一个结构体类型别名叫stu。stu该结构体成员变量有name(学生姓名),age年龄,gpa(平均学分绩点)。
④ns_demo命名空间中还有两个函数分别是scan_student_info和print_student_info。
scan_student_info函数的返回值为void,用于给stu类型的结构体变量的所有成员变量赋值。
print_student_info函数用于打印stu类型的结构体变量的所有成员变量。
⑤请在main.cpp的主函数中在堆区创建n个stu类型的结构体变量(n由键盘输入),然后给这n个stu类型的变量都赋值,并打印。

main.cpp
#include <iostream>
#include "stru_lib.h"
using std::cout;
using std::cin;
using std::endl;
int main()
{
int n;
cout << "请输入一共有多少个学生信息,n = ";
cin >> n;
//在堆区开辟n个不定长结构体数组
ns_demo::stu* student_arr = new ns_demo::stu[n];
//在栈区开辟5个结构体数组
//ns_demo::stu students[5];
for (int i = 0; i < n; i++)
{
cout << "请输入第" << i + 1 << "个学生的信息:";
ns_demo::scan_student_info(&student_arr[i]);
//&student_arr[i]等同于(student_arr + i)
}
for (int i = 0; i < n; i++)
{
cout << "当前输出第" << i + 1 << "个学生的信息:\n";
ns_demo::print_student_info(student_arr + i);
//student_arr + i等同于&student_arr[i]
}
delete []student_arr;
return 0;
}stru_lib.cpp
#include "stru_lib.h"
using std::cout;
using std::cin;
using std::endl;
void ns_demo::scan_student_info(stu* ps)
{
cout << "请输入该同学的名字:";
cin >> ps->name;
cout << "请输入该同学的年龄:";
cin >> ps->age;
cout << "请输入该同学的平均学分绩点:";
cin >> ps->gpa;
}
void ns_demo::print_student_info(stu* ps)
{
cout << "该同学的名字为:" << ps->name << endl;
cout << "该同学的年龄为:" << ps->age << endl;
cout << "该同学的平均学分绩点为:" << ps->gpa << endl;
}stru_lib.h
#ifndef __STRU_LIB_H_
#define __STRU_LIB_H_
#include <iostream>
#include <string>
namespace ns_demo
{
typedef struct
{
std::string name;
short age;
float gpa;
}stu;
void scan_student_info(stu* ps);
void print_student_info(stu* ps);
}
#endif现代C++之基础
要求:
定义基类
BaseCalculator,成员函数:
void do_calculation(int x, int y);这个函数里面会调用一个储存在该类里的私有的回调函数(
std::function<int(int,int)>),并打印回调结果。该类里的所有成员函数不准直接出现两个数据相加的功能。
该基类里可能不止一个成员函数,这算是一个提示。
里面所有的打印请使用现代C++里的std::print或者std::println。
如果编译器支持标准库模块化的话,可以选择使用modules。(标准库模块化在C++26将全面支持,而在C++20,C++23中仅MSVC编译器支持比较好)
定义派生类
AddCalculator,继承BaseCalculator,在这个类里实现能让两个数据相加的功能。main()里,创建AddCalculator对象,调用基类的do_calculation(10, 20),打印结果。
这题至少两种写法,尽量可以写出2种写法。

方法一:采用bind
import std.io; // 代替 #include <iostream>
import std.functional; // 代替 #include <functional>
import std.print; // 代替 #include <print>
class BaseCalculator
{
public:
// 绑定回调函数
void set_callback(std::function<int(int,int)> cb)
{
callback_ = std::move(cb);
}
// 调用回调并打印结果
void do_calculation(int x, int y)
{
if(callback_)
{
int result = callback_(x, y);
std::println("Calculation result: {}", result);
}
}
private:
std::function<int(int,int)> callback_;
};
class AddCalculator : public BaseCalculator
{
public:
AddCalculator()
{
// 绑定成员函数 add,传入 this
set_callback(std::bind(&AddCalculator::add, this, std::placeholders::_1, std::placeholders::_2));
}
int add(int a, int b)
{
return a + b;
}
};
int main()
{
AddCalculator calc;
calc.do_calculation(10, 20); // 输出 Calculation result: 30
std::println("Press Enter to continue...");
std::cin.get();
return 0;
}

方法二:采用lambda表达式
import std.io; // 代替 #include <iostream>
import std.functional; // 代替 #include <functional>
import std.print; // 代替 #include <print>
class BaseCalculator
{
public:
void set_callback(std::function<int(int,int)> cb)
{
callback_ = std::move(cb);
}
void do_calculation(int x, int y)
{
if(callback_)
{
int result = callback_(x, y);
std::println("Calculation result: {}", result); // 自动换行
}
}
private:
std::function<int(int,int)> callback_;
};
class AddCalculator : public BaseCalculator
{
public:
AddCalculator()
{
// 用lambda捕获this
set_callback([this](int a, int b)
{
return a + b;
});
}
};
int main()
{
AddCalculator calc;
calc.do_calculation(10, 20); // 输出 Calculation result: 30
std::println("Press Enter to continue..."); // 自动换行
std::cin.get();
return 0;
}



