北京大学程序设计MOOC作业详解-01-C到C++
标签: 北京大学程序设计MOOC作业详解-01-C到C++ JavaScript博客 51CTO博客
2023-07-14 18:24:15 84浏览
北京大学程序设计MOOC作业详解-01-C到C++
选择题部分
第一题:
第一题分析:
A选项:引用必须引用变量,不能是变量表达式,因此 int& r = n * 5;
不对。
B选项:常引用的定义是,不能通过常引用改变被引用变量的值,因此 r=7;
不对。
C选项:为了变量值的可靠性,常引用/指针不能赋值给引用/指针,但反过来可以,因此C不对。
该题选D。
第二题:
第二题分析:
要注意引用和指针的一个区别:指针是变量,可以先指向A再指向B;而引用并非变量,只是别名,一旦指向一个变量A,那就只能作为A的别名,不能再成为B的别名。
因此,r是指向a的引用,r=b的操作只能获得b的值,而不能成为b的别名,而最后r=7也是一种赋值,仍然是a的别名,因此a的值是7。
第三题:
第三题分析:
A选项:常引用所引用的变量,其值不能“通过修改常引用”导致被修改,但是完全可以自行修改,或者被其他非常量引用/指针修改,因此错误。
B选项:可参照前面的分析,知道B正确。
C选项:引用指向某一变量,就不能再指向其他变量。但是指针可以,指针本身是一种数据类型,是一种变量(指针变量)有自己的地址,因此可以随便赋值(指向)。
D选项:1+1=3不成立,错误。
该题选B。
第四题:
第四题分析:
new是动态内存分配的关键字,new T表示分配的对象是一个T类型的指针,即T*,而new int则是返回int*。这里和malloc不同,malloc必须强制类型转换,否则返回类型是void*。
该题选B。
第五题:
第五题分析:
要注意,new T用delete释放内存;new T[SIZE]用delete[]释放内存。然后,类型必须对应,new T/new T[SIZE]只能返回T*的指针变量。因此,该题选A。
第六题:
第六题分析:
重载函数:函数的参数个数或者类型不同,即参数列表不同,返回值类型不同并不构成重载。缺省值函数只能缺省最后(最右边)的参数,实参默认是前面的参数。因此,本题选D。
第七-八题,均是swap,一起分析:
用指针完成交换两个结构体变量
void swap1(Student* stu1, Student* stu2) {
Student temp = *stu1;
*stu1 = *stu2;
*stu2 = temp;
}
需要注意的是:这里传入的实参是Student变量的地址,即:
Student stu1, stu2;// 省略构造函数
swap1(&stu1, &stu2);
用二级指针交换两个结构体指针变量
void swap2(Student** stu1, Student** stu2) {
Student* temp = *stu1;
*stu1 = *stu2;
*stu2 = temp;
}
需要注意的是:这里传入的实参是Student指针变量的地址,即:
Student *stu1, *stu2;// 省略构造函数
swap2(&stu1, &stu2);
用引用交换两个结构体变量
void swap3(Student& stu1, Student& stu2) {
Student temp = stu1;
stu1 = stu2;
stu2 = temp;
}
需要注意的是:这里传入的实参是Student指针变量,即:
Student stu1, stu2;// 省略构造函数
swap2(stu1, stu2);
用指针的引用交换两个结构体指针变量
void swap4(Student*& stu1, Student*& stu2) {
Student* temp = *stu1;
*stu1 = *stu2;
*stu2 = temp;
}
需要注意的是:这里传入的实参是Student指针变量,即:
Student *stu1, *stu2;// 省略构造函数
swap2(stu1, stu2);
简单应用:用指针编写交换两个字符串的函数
#include <iostream>
using namespace std;
void swap(char** str1, char** str2) {
char* temp = *str1;
*str1 = *str2;
*str2 = temp;
}
int main() {
char* s1 = (char*)"hello";
char* s2 = (char*)"world";
cout << s1 << endl << s2 << endl;
swap(&s1, &s2);
cout << s1 << endl << s2 << endl;
return 0;
}
升级应用:用模板编写交换任意类型的交换函数
template<class T>
void swap(T* val1, T* val2) {
T temp = *val1;
*val1 = *val2;
*val2 = temp;
}
需要注意的是:这里传入的实参是任意类型变量的地址,即:
Student *stu1, *stu2;// 省略构造函数
Student stu3, stu4;
swap2(&stu1, &stu2);
swap2(&stu3, &stu4);
第九题:
第九题分析:
注意到,一个数组a,访问数组元素a[i]既可以当右值给别的变量赋值,即:val = a[i];
,也可以当左值被赋值,即:a[i]=val;
。这是为什么呢?是因为,下标运算符返回的是一个引用类型。
这是因为:引用是变量的别名,而非引用的返回是变量的拷贝。不考虑编译器优化的情况下,函数返回操作,会经过一次拷贝。
既然是拷贝,那么就是一个临时的变量了,临时变量在调用结束后会释放,因此无法做到赋值功能。因此,为了实现赋值,我们应该编写返回类型的引用。除了赋值,还有别的地方需要返回类型的引用吗?有:如果需要连续调用,则必须返回引用,比如连续设置成员变量:
class A {
private:
int x, y, z;
public:
A& setX(int x_) { x = x_; return *this; }
A& setY(int y_) { y = y_; return *this; }
A& setZ(int z_) { z = z_; return *this; }
}
这是可以这样赋值:A obj_a; obj_a.setX(1).setY(2).setZ(3);
,这是因为:set函数返回的是引用,即*this对象本身,因此继续调用set函数,仍然是作用在this指向的对象上的。
言归正传,本题的正确代码填空是:int&
第十题
第十题分析
这个题,需要填写一个指针数组的初始化。什么是指针数组?指针数组首先是一个数组,其次数组内的元素是指针。
然后看题目,可以知道数组内的指针,是用new int[]
分配内存的,因为有二维数组。但同时,也有一维数组,这里需要分析下:
a[0] = nullptr;
a[1] = nullptr;
a[2] = new int;
a[3] = new int[6];
为什么这么做呢?因为:if(!a[0]){}
告诉我们,a[0]必须是空(0),a[1]无所谓,默认设为空也可以。a[2]并非数组,但是可以赋值,因此需要内存分配,即用new int完成。a[3]能访问到下标为5的元素,那么空间至少开到6,因为下标默认从0开始,所以用new int[6]完成。
好博客就要一起分享哦!分享海报
此处可发布评论
评论(0)展开评论
展开评论