《C++ Primer》第12章 12.2节习题答案

《C++ Primer》第12章 动态内存

12.2节 动态数组 习题答案

练习12.23:编写一个程序,连接两个字符串字面常量,将结果保存在一个动态分配的char数组中。重写这个程序,连接两个标准库string对象。

【出题思路】

本题练习使用动态数组。

【解答】

用new char[xx]即可分配用来保存结果的char数组,其中xx应该足以保存结果字符串。由于C风格字符串以'\0'结尾,因此xx应不小于字符数加1。对字符串字面常量(即字符数组),可以使用strcpy将第一个字符串拷贝到动态数组中,然后用strcat将第二个字符串连接到动态数组中。对两个string对象,使用+运算即可简单实现连接。然后用c_str获取连接结果(临时string对象)的内存地址,用strcpy拷贝到动态数组即可。最终,不要忘记释放动态数组。

#include <iostream>
#include <cstring>

using std::cout;
using std::endl;
using std::string;

int main()
{
    const char *c1 = "Hello ";
    const char *c2 = "World";
    //字符串所需空间=字符数+1
    char *r = new char[strlen(c1) + strlen(c2) + 1];
    strcpy(r, c1);//拷贝第一个字符串常量
    strcat(r, c2);//连接第二个字符串常量
    cout << "r=====" << r << endl;

    string s1 = "hello ";
    string s2 = "world";
    strcpy(r, (s1 + s2).c_str());
    cout << "r=====" << r << endl;
    //释放动态数组
    delete []r;
    return 0;
}

运行结果:

 练习12.24:编写一个程序,从标准输入读取一个字符串,存入一个动态分配的字符数组中。描述你的程序如何处理变长输入。测试你的程序,输入一个超出你分配的数组长度的字符串。

【出题思路】

本题继续练习使用动态数组。

【解答】

我们处理变长输入的方法是,根据动态分配的字符数组的大小确定字符串长度阈值,当读取的字符数超出阈值时,停止读取,即采取了截断的方式。还可采取其他处理方式,如抛出异常等。另外,为了能读取空格等空白符,程序中用到了get操作来读取字符。

#include <iostream>
#include <cstring>

using namespace std;

int main()
{
    char c;
    //分配20个字符的动态数组,因此最多存放19个字符
    char *arr = new char[20];
    int len = 0;
    while(cin.get(c))
    {
        if(isspace(c))//字格符,制表符等空白符
            break;
        arr[len++] = c;//存入动态数组
        if(len == 19)
        {
            cout << "达到数线容量上限" << endl;
            break;
        }

    }
    arr[len] = '\0';
    cout <<"len = " << len << " arr=======" << arr;
    //释放动态数组
    delete []arr;

    return 0;
}

运行结果:

 练习12.25:给定下面的new表达式,你应该如何释放pa?

int *pa = new int[10]

【出题思路】

理解释放动态数组的特殊方式。

【解答】

delete []pa;

练习12.26:用allocator重写第427页中的程序。

【出题思路】

本题练习使用allocator。

【解答】

首先,定义一个allocator<string> alloc。然后,用alloc的allocate而不是new操作来分配内存。这样,只会分配裸内存,而不会初始化string对象。接下来,用construct操作从读取的string对象来初始化动态数组中的string。随后动态数组的使用就和往常一样了。使用完毕后,记住与内存分配和对象构造一样,对象析构(使用destroy操作)和内存释放(deallocate操作)也是分开的。

#include <iostream>
#include <string>
#include <memory>

using namespace std;

int main()
{
    allocator<string> alloc;
    //分配100个未初始化的string
    auto const p = alloc.allocate(100);
    string s;
    string *q = p;                      //q指向第一个string
    while(cin >> s && q != p + 100)
    {
        alloc.construct(q++, s);        //用s初始化*q
    }
    const size_t size = q - p;          //记住读了多少个string
    cout << "size = " << size << endl;
    cout << endl;
    //使用数组
    for(size_t i = 0; i < size; i++)
        cout << p[i] << "\t";

    while (q != p) {
        alloc.destroy(--q);
    }
    alloc.deallocate(p, 100);

    cout << "hello world" << endl;
    return 0;
}

运行结果:

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值