📄 习题4.16 .txt
字号:
习题4.16
下列程序段实现什么功能?
int i = 42, j = 1024;
int *p1 = &i, *p2 = &j;
*p2 = *p1 * * p2;
*p1 *= *p1;
【解答】
该程序段使得i被赋值为42的平方,j被赋值为42与1024的乘积。
习题4.17
已知p1和p2指向同一个数组中的元素,下面语句实现什么功能?
p1 += p2 – p1;
当p1和p2具有什么值时这个语句是非法的?
【解答】
此语句使得p1也指向p2原来所指向的元素。原则上说,只要p1和p2的类型相同,则该语句始终是合法的。只有当p1和p2不是同类型指针时,该语句才不合法(不能进行-操作)。
但是,如果p1和p2不是指向同一个数组中的元素,则这个语句的执行结果可能是错误的。因为-操作的结果类型ptrdiff_t只能保证足以存放同一数组中两个指针之间的差距。如果p1和p2不是指向同一个数组中的元素,则-操作的结果有可能超出ptrdiff_t类型的表示范围而产生溢出,从而该语句的执行结果不能保证p1指向p2原来所指向的元素(甚至不能保证p1为有效指针)。
习题4.18
编写程序,使用指针把一个int型数组的所有元素设置为0。
【解答】
// 使用指针把一个int型数组的所有元素设置为0
int main()
{
const size_t arr_size = 8;
int int_arr[arr_size] = { 0, 1, 2, 3, 4, 5, 6, 7 };
// pbegin指向第一个元素,pend指向最后一个元素的下一内存位置
for (int *pbegin = int_arr, *pend = int_arr + arr_size;
pbegin != pend; ++pbegin)
*pbegin = 0; // 当前元素置0
return 0;
}
习题4.19
解释下列5个定义的含义,指出其中哪些定义是非法的:
(a) int i;
(b) const int ic;
(c) const int *pic;
(d) int *const cpi;
(e) const int *const cpic;
【解答】
(a) 合法:定义了int型对象i。
(b) 非法:定义const对象时必须进行初始化,但ic没有初始化。
(c) 合法:定义了指向int型const对象的指针pic。
(d) 非法:因为cpi被定义为指向int型对象的const指针,但该指针没有初始化。
(e) 非法:因为cpic被定义为指向int型const对象的const指针,但该指针没有初始化。
习题4.20
下列哪些初始化是合法的?为什么?
(a) int i = -1;
(b) const int ic = i ;
(c) const int *pic = ⁣
(d) int *const cpi = ⁣
(e) const int *const cpic = ⁣
【解答】
(a) 合法:定义了一个int型对象i,并用int型字面值-1对其进行初始化。
(b) 合法:定义了一个int型const对象ic,并用int型对象对其进行初始化。
(c) 合法:定义了一个指向int型const对象的指针pic,并用ic的地址对其进行初始化。
(d) 不合法:cpi是一个指向int型对象的const指针,不能用const int型对象ic的地址对其进行初始化。
(e) 合法:定义了一个指向int型const对象的const指针cpic,并用ic的地址对其进行初始化。
习题4.21
根据上述定义,下列哪些赋值运算是合法的?为什么?
(a) i = ic; (b) pic = ⁣
(c) cpi = pic; (d) pic = cpic;
(e) cpic = ⁣ (f) ic = *cpic;
【解答】
(a)、(b)、(d)合法。
(c)、(e)、(f)均不合法,因为cpi、cpic和ic都是const变量(常量),常量不能被赋值。
习题4.22
解释下列两个while循环的差别:
const char *cp = "hello";
int cnt;
while (cp) { ++cnt; ++cp; }
while (*cp) { ++cnt; ++cp; }
【解答】
两个while循环的差别为:前者的循环结束条件是cp为0值(即指针cp为0值);后者的循环结束条件是cp所指向的字符为0值(即cp所指向的字符为字符串结束符null(即'\0'))。因此后者能正确地计算出字符串"hello"中有效字符的数目(放在cnt中),而前者的执行是不确定的。
注意,题目中的代码还有一个小问题,即cnt没有初始化为0值。
习题4.23
下列程序实现什么功能?
const char ca[] = {'h', 'e', 'l', 'l', 'o'};
const char *cp = ca ;
while (*cp) {
cout << *cp << endl;
++cp;
}
【解答】
该程序段从数组ca的起始地址(即字符'h'的存储地址)开始,输出一段内存中存放的字符,每行输出一个字符,直至存放0值(null)的字节为止。(注意,输出的内容一般来说要多于5个字符,因为字符数组ca中没有null结束符。)
习题4.24
解释strcpy和strncpy的差别在哪里,各自的优缺点是什么?
【解答】
strcpy和strncpy的差别在于:前者复制整个指定的字符串,后者只复制指定字符串中指定数目的字符。
strcpy比较简单,而使用strncpy可以适当地控制复制字符的数目,因此比strcpy更为安全。
习题4.25
编写程序比较两个string类型的字符串,然后编写另一个程序比较两个C风格字符串的值。
【解答】
比较两个string类型的字符串的程序如下:
//比较两个string 类型的字符串
#include <iostream>
#include <string>
using namespace std;
int main()
{
string str1, str2;
//输入两个字符串
cout << "Enter two strings:" << endl;
cin >> str1 >> str2;
//比较两个字符串
if (str1 > str2)
cout << "\"" << str1 << "\"" << " is bigger than "
<< "\"" << str2 << "\"" << endl;
else if (str1 < str2)
cout << "\"" << str2 << "\"" << " is bigger than "
<< "\"" << str1 << "\"" << endl;
else
cout << "They are equal" << endl;
return 0;
}
比较两个C风格字符串的程序如下:
//比较两个C风格字符串的值
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
//char *str1 = "string1", *str2 = "string2";
const int str_size = 80;
char *str1, *str2;
//为两个字符串分配内存
str1 = new char[str_size];
str2 = new char[str_size];
if (str1 == NULL || str2 == NULL) {
cout << "No enough memory!" << endl;
return -1;
}
//输入两个字符串
cout << "Enter two strings:" << endl;
cin >> str1 >> str2;
//比较两个字符串
int result;
result = strcmp(str1, str2);
if (result > 0)
cout << "\"" << str1 << "\"" << " is bigger than "
<< "\"" << str2 << "\"" << endl;
else if (result < 0)
cout << "\"" << str2 << "\"" << " is bigger than "
<< "\"" << str1 << "\"" << endl;
else
cout << "They are equal" << endl;
//释放字符串所占用的内存
delete [] str1 ;
delete [] str2 ;
return 0;
}
注意,此程序中使用了内存的动态分配与释放(见4.3.1节)。如果不用内存的动态分配与释放,可将主函数中第2、3两行代码、有关内存分配与释放的代码以及输入字符串的代码注释掉,再将主函数中第一行代码
//char *str1 = "string1", *str2 = "string2";
前的双斜线去掉即可。
习题4.26
编写程序从标准输入设备读入一个string类型的字符串。考虑如何编程实现从标准输入设备读入一个C风格字符串。
【解答】
从标准输入设备读入一个string类型字符串的程序段:
string str;
cin >> str;
从标准输入设备读入一个C风格字符串可如下实现:
const int str_size = 80;
char str[str_size];
cin >> str;
习题4.27
假设有下面的new表达式,请问如何释放pa?
int *pa = new int[10];
【解答】
用语句delete [] pa;释放pa所指向的数组空间。
习题4.28
编写程序由从标准输入设备读入的元素数据建立一个int型vector对象,然后动态创建一个与该vector对象大小一致的数组,把vector对象的所有元素复制给新数组。
【解答】
// 从标准输入设备读入的元素数据建立一个int型vector对象,
// 然后动态创建一个与该vector对象大小一致的数组,
// 把vector对象的所有元素复制给新数组
#include <iostream>
#include <vector>
using namespace std;
int main()
{
vector<int> ivec;
int ival;
//读入元素数据并建立vector
cout << "Enter numbers:(Ctrl+Z to end)" << endl;
while (cin >> ival)
ivec.push_back(ival);
//动态创建数组
int *pia = new int[ivec.size()];
//复制元素
int *tp = pia;
for (vector<int>::iterator iter = ivec.begin();
iter != ivec.end(); ++iter, ++tp)
*tp = *iter;
//释放动态数组的内存
delete [] pia;
return 0;
}
习题4.29
对本节第5条框中的两段程序:
(a) 解释这两段程序实现的功能。
(b) 平均来说,使用string类型的程序执行速度要比用C风格字符串的快很多,在我们用了5年的PC机上其平均执行速度分别是:
user 0.47 # string class
user 2.55 # C-style character string
你预计的也一样吗?请说明原因。
【解答】
(a) 这两段程序的功能是:执行一个循环次数为1000000的循环,在该循环的循环体中:创建一个新字符串,将一个已存在的字符串复制给新字符串,然后比较两个字符串,最后释放新字符串。
(b) 使用C风格字符串的程序需要自己管理内存的分配和释放,而使用string类型的程序由系统自动进行内存的分配和释放,因此比使用C风格字符串的程序要简短,执行速度也要快一些。
习题4.30
编写程序连接两个C风格字符串字面值,把结果存储在一个C风格字符串中。然后再编写程序连接两个string类型字符串,这两个string类型字符串与前面的C风格字符串字面值具有相同的内容。
【解答】
连接两个C风格字符串字面值的程序如下:
// 连接两个C风格字符串字面值,
// 把结果存储在一个C风格字符串中
#include <cstring>
int main()
{
const char *cp1 = "Mary and Linda ";
const char *cp2 = "are firends.";
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -