北京大学程序设计MOOC作业详解-01-C到C++

北京大学程序设计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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值