《C++ Primer》5th 课后练习 第二章 变量和基本类型 31~40

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接: https://blog.csdn.net/qq_40758751/article/details/101633685

练习2.31 假设已有上一个练习中所做的那些声明,则下面的哪些语句是合法的?请说明顶层const和底层const在每个例子中有何体现。

r1 = v2; // 合法, 顶层const在拷贝时不受影响
p1 = p2; // 不合法, p2 是底层const,如果要拷贝必须要求 p1 也是底层const
p2 = p1; // 合法, int* 可以转换成const int*
p1 = p3; // 不合法, p3 是一个底层const,p1 不是
p2 = p3; // 合法, p2 和 p3 都是底层const,拷贝时忽略掉顶层const

练习2.32 下面的代码是否合法?如果非法,请设法将其修改正确。

int null = 0, *p = null;

非法,(error C2440: “初始化”: 无法从“int”转换为“int *”)可改为

int null = 0, *p = nullptr;

练习2.33 利用本节定义的变量,判断下列语句的运行结果。

a=42; // a 是 int
b=42; // b 是一个 int,(ci的顶层const在拷贝时被忽略掉了)
c=42; // c 也是一个int
d=42; // d 是一个 int *,所以语句非法
e=42; // e 是一个 const int *, 所以语句非法
g=42; // g 是一个 const int 的引用,引用都是底层const,所以不能被赋值

练习2.34 基于上一个练习中的变量和语句编写一段程序,输出赋值前后变量的内容,你刚才的推断正确吗?如果不对,请反复研读本节的示例直到你明白错在何处为止。

#include <iostream>

int main()
{
    int i = 0, &r = i;
    auto a = r;   // a是一个整数(r是i的别名,而i是以一个整数)

    const int ci = i, &cr = ci;
    auto b = ci; // b是一个整数(ci的顶层const特性被忽略掉了)
    auto c = cr; // c是一个整数(cr是ci的别名,ci本身是一个顶层const)
    auto d = &i; // d是一个整型指针(整数的地址就是指向整数的指针)
    auto e = &ci; // e是一个指向整数常量的指针(对常量对象去地址是一种底层const)

    const auto f = ci; // ci的推演类型是int,f是const int
    auto &g = ci; // g是一个整型常量引用,绑定到ci

    std::cout << a << std::endl;
    std::cout << b << std::endl;
    std::cout << c << std::endl;
    std::cout << d << std::endl;
    std::cout << e << std::endl;
    std::cout << f << std::endl;
    std::cout << g << std::endl;
    std::cout << "--------------" << std::endl;
    a = 42; b = 42; c = 42; //d = 42; e = 42; g = 42;

    std::cout << a << std::endl;
    std::cout << b << std::endl;
    std::cout << c << std::endl;
    std::cout << d << std::endl;
    std::cout << e << std::endl;
    std::cout << f << std::endl;
    std::cout << g << std::endl;

    return 0;
}

练习2.35 判断下列定义推断出的类型是什么,然后编写程序进行验证。

const int i = 42;
auto j = i; const auto &k = i; auto *p = &i; 
const auto j2 = i, &k2 = i;

j的类型是int,k为const int型引用,p为const int型指针,j2为const int型,k2为const int型引用。

练习2.36 关于下面的代码,请指出每一个变量的类型以及程序结束时它们各自的值。

int a = 3, b = 4;
decltype(a) c = a;
decltype((b)) d = a;
++c;
++d;

c为int型,d为int &。都为4。

练习2.37 赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型。也就是说,如果 i 是 int,则表达式 i=x 的类型是 int&。根据这一特点,请指出下面的代码中每一个变量的类型和值。

int a = 3, b = 4;
decltype(a) c = a;
decltype(a = b) d = a;

c为int型,值为3;d为int &型,绑定到对象a上。

练习2.38 说明由decltype 指定类型和由auto指定类型有何区别。请举一个例子,decltype指定的类型与auto指定的类型一样;再举一个例子,decltype指定的类型与auto指定的类型不一样。

主要的区别有两点:

1:如果使用引用类型,auto会识别为其所指对象的类型,decltype则会识别为引用的类型。

2:decltype(())双括号的差别。

decltype 处理顶层const和引用的方式与 auto不同,decltype会将顶层const和引用保留起来。

int i = 0, &r = i;
// same
auto a = i;
decltype(i) b = i;
// different
auto c = r;
decltype(r) d = i;

练习2.39 编译下面的程序观察其运行结果,注意,如果忘记写类定义体后面的分号会发生什么情况?记录下相关的信息,以后可能会有用。

struct Foo{/*此处为空*/} //注意:没有分号
int main()
{
	return 0;
}

[Error] expected ‘;’ after struct definition

练习2.40 根据自己的理解写出 Sales_data 类,最好与书中的例子有所区别。

struct Sales_data{
    std::string bookNo;
    std::string bookName;
    int num;
    double price = 0.0;
};

猜你喜欢

转载自blog.csdn.net/qq_40758751/article/details/101633685