C++基础教程
——
作业及参考答案全部汇总文档
节7指针高级阶段作业

最新版本V2.0
王道C++团队
COPYRIGHT ⓒ 2021-2024. 王道版权所有

基础题篇

Gn!

下面都是一些基础的语法、概念编程练习题。

实现动态拼接字符串

Gn!

标准库函数strcat会将一个字符串追加到另一个字符串的末尾。

现在我们编写一个函数把两个字符串拼接起来,返回拼接的结果,但要求不改变其中任何一个字符串。其函数声明如下:

形参prefix表示前缀,suffix表示后缀,拼接的结果是prefix + suffix

比如:my_strcat("abc", "d"),拼接的结果是"abcd"。

思路:

  1. 在堆上分配内存空间,用于存储结果字符串。

  2. 将prefix和suffix两个字符串的字符信息复制进去。

参考代码如下:

参考代码:

这个问题非常简单,是一个基础的动态内存分配问题。参考代码如下:

以上。

手动实现动态数组Vector

Gn!

手动实现动态数组Vector,基于以下结构体定义和函数声明:

注意:

你应该将上述代码放在头文件中,并且自己添加头文件保护语法。

提交作业时,你应该提交头文件,实现Vector的源文件,测试源文件三个文件的代码

参考代码如下:

参考代码:

头文件加上保护语法,代码如下:

实现源文件代码:

测试用例代码:

以上。

二级指针基础练习题

Gn!

在main函数中定义两个局部变量:

请实现以下两个函数,用于完成局部变量a和b的交换:

这两个函数都应该可以实现交换a和b的值。

参考代码如下:

参考代码如下:

以上。

二级指针/单链表练习题

Gn!

基于以下链表结点结构体类型的定义:

在main函数中定义一个head头指针等于NULL代表此时单链表为空:

利用二级指针语法实现以下函数:

注:尾插法会稍微麻烦一些,可以放在最后实现。

参考代码如下:

参考代码:

参考代码如下:

以上。

qsort函数基础语法练习

Gn!

给你下面一个Student,学生结构体类型的定义:

假设你有一个学生结构体对象数组,如下所示:

你的任务是使用qsort函数对这个结构体数组进行排序:

  1. 规则1:将全体结构体对象,按照学生成绩从高到低进行排序。

  2. 规则2:先将全体结构体对象,按照学生成绩从低到高进行排序,如果成绩一致,则那么按照名字的字典顺序进行排序。

最后,你还需要实现一个函数用于打印整个学生数组:

参考代码如下:

参考代码如下:

可以直接用上面题目中给出的数据,不需要自己编数据了:

以上。

扩展题篇

Gn!

以下题目都属于扩展题。

扩展:动态字符串Vector

Gn!

你已经手动实现了一个自己的Vector,很好,这很酷。那么请思考和完成以下扩展的题目。

现在请你回答第一个问题:

原本的动态数组用于存储int类型元素,是int类型动态数组。现在我希望你能把它变成字符串动态数组,应该怎么改代码吗?

如果仅在原本代码的基础上修改ElementType的类型,那么请你思考第二个问题:

此时Vector虽然能存字符串了,但只能存什么字符串呢?

把以上问题都考虑清楚后,请完成以下测试工作:

使用push_back函数向动态字符串数组中循环添加100个字符串元素,这些字符串依次是:

"0"

"01"

"012"

"0123"

...... "01234567890"

"012345678901"

"0123456789012"

....

添加完成后,请遍历打印这个动态字符串数组。请将这段测试动态字符串数组Vector的代码贴在答案里。

Vector的其它实现代码不需要贴进来。

注意,实现这个需求时,不需要考虑字符串的生命周期问题。

参考回答如下:

参考代码:

前两个问题的答案:

  1. 只需要把ElementType的类型从int改为char *就可以了。

  2. 如果只是改变ElementType的类型,那么从最佳实践出发:

    1. 这个Vector最好存储字面值字符串、全局变量等静态存储期限的字符。因为不用考虑它们的生命周期问题,它们在整个程序运行期间都生效。

    2. 如果存储局部变量字符串,那么这个Vector将不能跨函数使用。

    3. 如果存堆字符串,那么这个Vector需要管理它存储的字符串的生命周期,这就比较麻烦了。

但对于我们下面的这个需求而言:由于需要动态构建字符串,所以不可能使用字符串字面值,局部变量/全局变量字符串也不可用,所以比较好是实现就是使用堆字符串。

参考代码如下:

以上。

扩展:错误处理宏函数

Gn!

规范的代码应该对内存分配函数malloc、calloc、realloc的返回值做判NULL处理。因为这些函数的返回值是NULL时意味着内存分配失败,函数出错,需要做错误处理。

后续的学习中,我们还会学习很多这样的函数,需要对它们的返回值做错误处理。

如果每次都需要将错误处理的结构都重新写一遍,那确实很折磨。为了更好的复用代码,简化操作,我们建议大家把这个结构用宏函数定义出来。

可以基于以下结构定义宏函数:

提示,为了更好的复用性,这个宏函数最好有三个参数:

1.函数返回值。错误处理是依据函数返回值进行的,所以需要函数返回值作为参数。也就是上述结构中的p

2.函数返回值的错误标志。当返回值是这个错误标志时,做错误处理。上述代码结构中就是NULL

3.msg。错误处理时打印的报错信息。也就是"calloc failed in main."这一段。

这个宏函数的实现不唯一,也不可能做到一个宏函数统一处理所有的情况,大家可以自己想一想写一下,也可以直接参考我给的实现。

最后,你可以将这个宏函数放到你的代码模板中,这样就更方便了。

参考实现如下:

参考代码实现:

以上。

扩展:动态内存分配以及qsort函数

Gn!

(扩展题,可以放到最后做)

编写一个C语言程序,完成以下任务:

首先,从键盘录入一个整数,表示接下来要录入的字符串的数量。

紧接着根据这个数量,从键盘连续录入字符串,每次都会将一整行键盘录入成一个字符串

这些被录入的字符串需要存入一个字符串数组,然后将该字符串数组按照以下两种规则排序遍历打印:

1.按照字符串的长度,从长到短排序

2.先按照字符串的长度从短到长排序,长度一致的字符串按照字典顺序排序。

程序的执行图,大致如下:

扩展题3-图

注意:

使用fgets读一整行字符串的话,不要忘记去除字符串中的换行符。

假设每个字符串的长度都不会超过1024。

参考代码如下:

参考代码如下:

以上。

扩展:动态拼接字符串数组以及qsort函数

Gn!

首先给定以下字符数组:

请你先利用qsort函数将此字符串数组,按照逆字典顺序排序。然后将这个字符串数组中的每一个字符串,按照从前到后的顺序,拼接组装成一个新字符串,并且在拼接时删除每个子字符串的第一个字符。

这样你将得到Linux之父Linus Torvalds的名言:“Talk is cheap, show me the code.”

要求使用动态分配内存来存储结果字符串,函数声明如下:

参考代码如下:

参考代码:

以上。

 

 

The End