[toc]
第一章:
一、基础题
请说出C++语言的优点,缺点,和主要用途?(涉及知识点:1-4节 C++特点, 1-5 C++作用)
优点:
- 强大的抽象封装能力:这让C++语言具备了强大的开发工程能力,在封装的同时C++最大程度的保留了高性能;
- 高性能:运行快,快并且占用资源少一直是C++语言的追求;
- 低功耗:特别适合在各种微型的嵌入式设备中运行高效的程序;
缺点:
- 语法相对复杂,细节比较多,学习曲线比较陡;
- 需要一些好的规范和范式,否则代码很难维护;
二、提高题
- 请参考课程演示代码”CPPDemo1”中的C++面向对象方式,思考C面向过程方式中如何实现trace功能在开关打开状态下写入到文件中,并想想这两种方式各自的优缺点?(涉及知识点:1-3节 C++vsC,面向对象vs面向过程)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| #include <stdio.h> static bool trigger; void turnOn() { trigger = true; } void turnOff() { trigger = false; } void write(char *s,int n) { FILE *fp = fopen("test.txt","a+"); if(trigger) { fwrite(s,1,n,fp); } fclose(fp); } int main() { turnOn(); write("First",5); turnOff(); write("Second",6); }
|
c语言需要用全局变量和全局函数来实现,在稍微大一些的项目中,将会产生难以维护,难以扩展,难以阅读的问题,而C++封装对象的方式就可以解决这些问题。
c语言在内存方面占用更小。在微型项目中编写更加方便。
第二章
一、基础题
- 下面标识符是合法的有哪些(BEF ) (涉及知识点: 2-5 标识符与关键字)
A.float
B.ipad
C.1button
D. A#BC
E.my_button
F. button_1_ok
- 请给一个退出按钮命一个好变量名( C)(涉及知识点: 2-5 标识符)
A. 1button
B. button1
C.buttonQuit
D.button_tuichu
- 下面整数常量合法的是( D)(涉及知识点: 2-6 常量)
A.078
B.03UU
C.0x9AHX
D.0xFFAA00
二、提高题
下面程序输出结果是 (8)(涉及知识点: 2-6 常量的宏定义)
1 2 3 4 5 6 7 8 9
| #define MA(x) x*(x-1) void main() { int a=1, b=2; cout << MA(1+a+b) << endl; }
|
第三章:
一、填空
cout <<sizeof(char) << endl;
cout << sizeof(short) << endl;
cout << sizeof(int) << endl;
cout << sizeof(float) << endl;
cout << sizeof(double) << endl;
<!--2-->
typedef struct{
short Sunday = 0;
short Monday = 1;
short Tuesday = 2;
short Wednesday = 3;
short Thursday = 4;
short Friday = 5;
short Saturday = 6;
} Week;
Week w;
cout << sizeof(w.Sunday);
cout << sizeof(w) << endl;
<!--3-->
分别写出bool 、int、 float、与“零值”比较,表达式返回值等于1的代码片段;
1 2 3 4 5 6 7 8 9 10 11
| #设变量为flag
bool: if(flag) int: if(flag == 0) double: const double EPSINON = 0.00001; if ((flag >= - EPSINON) && (flag <= EPSINON)) char *: if (flag == NULL)
|
第四五六章:
一、程序运行题
- 请说出下列问号处的结果:
1 2 3 4 5 6 7 8 9 10 11 12
| char str[] = “Hello” ; char *p = str ; int n = 10; //请计算 sizeof (str ) = ? sizeof ( p ) = ? sizeof ( n ) = ? void Func ( char str[100]) { //请计算 sizeof( str ) = ? }
|
答:
sizeof (str ) = 6
sizeof ( p ) = 4
sizeof ( n ) = 4
void Func ( char str[100])
{
sizeof( str ) = 4
}
void GetMemory(char *p)
{
p = new char[100];
}
void Test(void)
{
char *str = NULL;
GetMemory(str);
strcpy(str, "hello world");
printf(str);
}
1 2 3 4 5
| 问运行Test 函数会有什么样的结果? **答:程序崩溃。因为GetMemory 并不能传递动态内存, Test 函数中的 str 一直都是 NULL。strcpy(str, "hello world");将使程序崩溃。**
3.
|
char *GetMemory(void)
{
char p[] = "hello world";
return p;
}
void Test(void)
{
char *str = NULL;
str = GetMemory();
printf(str);
}
1 2 3 4
| 请问运行Test 函数会有什么样的结果? **答:可能是乱码;因为GetMemory 返回的是指向“栈内存”的指针,该指针的地址不是 NULL,但其原现的内容已经被清除,新内容不可知。**
4.
|
void GetMemory2(char **p, int num)
{
*p = new char[num];
}
void Test(void)
{
char *str = NULL;
GetMemory2(&str, 100);
strcpy(str, "hello");
printf(str);
}
1 2 3 4 5
| 请问运行Test 函数会有什么样的结果? **答:能够输出hello,但内存泄漏 **
5.
|
# include <string.h>
void Test(void)
{
char *str = new char[100];
strcpy(str, "hello");
delete[ ] str;
if (str != NULL)
{
strcpy(str,"world");
printf(str);
}
}
1 2 3 4 5
| 请问运行Test 函数会有什么样的结果? **答:篡改动态内存区的内容,后果难以预料,非常危险。因为 delete[ ]str;之后,str成为野指针(需要str = NULL;)if(str != NULL)语句不起作用。**
## 二、编程题 1. char *strcpy(char *strDest, const char *strSrc)不调用C++/C 的字符串库函数,请编写函数 strcpy;
|
char *strcpy(char *strDest, const char *strSrc);
{
assert((strDest!=NULL) && (strSrc !=NULL));
char *address = strDest;
while( (*strDest++ = * strSrc++) != ‘\0’ )
;
return address ;
}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| # 第七章:
## 一、编程题 编写自定义类String 的构造函数、析构函数和赋值函数。 已知类String 的原型为: class String { public: String(const char *str = NULL); // 普通构造函数 String(const String &other); // 拷贝构造函数 String(String&& other); // 移动构造函数 ~String(void); // 析构函数 String& operator= (const String& other); // 赋值函数 String& operator=(String&& rhs)noexcept; // 移动赋值运算符 private: char *m_data; // 用于保存字符串 }; 请编写String 的上述几个函数。
|
// String 的析构函数
String::~String(void)
{
if (m_data != NULL)
{
delete[] m_data;
}
}
// String 的普通构造函数
String::String(const char *str)
{
if (str == NULL)
{
m_data = new char[1];
if (m_data != NULL)
{
*m_data = ‘\0’;
}
else
{
exit(-1); // new有可能失败,失败后返回错误退出, 最好能有日志
}
}
else
{
int length = strlen(str);
m_data = new char[length + 1];
if (m_data != NULL)
{
*m_data = ‘\0’;
}
else
{
exit(-1); // new有可能失败,失败后返回错误退出, 最好能有日志
}
strcpy(m_data, str);
}
}
// 拷贝构造函数
String::String(const String &other)
{
int length = strlen(other.m_data);
m_data = new char[length + 1];
if (m_data != NULL)
{
*m_data = ‘\0’;
}
else
{
exit(-1); // new有可能失败,失败后返回错误退出, 最好能有日志
}
strcpy(m_data, other.m_data);
}
String::String(String&& other)
{
if (other.m_data != NULL)
{
m_data=other.m_data;
other.m_data = NULL;
}
}
// 赋值函数
String& String::operator= (const String &other)
{
// 检查自赋值
if (this == &other)
return *this;
// 释放原有的内存资源
delete[] m_data;
// 分配新的内存资源,并复制内容
int length = strlen(other.m_data);
m_data = new char[length + 1];
if (m_data != NULL)
{
*m_data = ‘\0’;
}
else
{
exit(-1); // new有可能失败,失败后返回错误退出, 最好能有日志
}
strcpy(m_data, other.m_data);
// 返回本对象的引用
return *this;
}
String& String::operator=(String&& rhs)noexcept
{
if (this != &rhs)
{
delete[] m_data;
m_data = rhs.m_data;
rhs.m_data = NULL;
}
return *this;
}
```