• 第2章 变量和基本类型读书笔记


    2.1.1 算数类型

    类型 int、long、long long 和 short 的区别是什么?无符号类型和带符号类型的区别是什么?float 和 double的区别是什么?

    C++ 规定 short 和 int 至少16位,long 至少32位,long long 至少64位。 带符号类型能够表示正数、负数和 0 ,而无符号类型只能够表示 0 和正整数。

    2.1.2 类型准换

    读写程序结果

    unsigned u = 10, u2 = 42;
    std::cout << u2 - u << std::endl;
    > 这里是引用
    
    std::cout << u - u2 << std::endl;
    int i = 10, i2 = 42;
    std::cout << i2 - i << std::endl;
    std::cout << i - i2 << std::endl;
    std::cout << i - u << std::endl;
    std::cout << u - i << std::endl;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    32
    4294967264
    32
    -32
    0
    0
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2.1.3 字面值常量

    指出下述字面值的数据类型并说明每一组内几种字面值的区别:

    (a) ‘a’, L’a’, “a”, L"a"
    (b) 10, 10u, 10L, 10uL, 012, 0xC
    © 3.14, 3.14f, 3.14L
    (d) 10, 10u, 10., 10e-2

    (a): 字符字面值,宽字符字面值,字符串字面值,宽字符串字面值。
    (b): 十进制整型,十进制无符号整型,十进制长整型,十进制无符号长整型,八进制整型,十六进制整型。
    ( c): double, float, long double
    (d): 十进制整型,十进制无符号整型,double, double

    下面两组定义是否有区别,如果有,请叙述之:

    int month = 9, day = 7;
    int month = 09, day = 07;
    
    • 1
    • 2

    第一行定义的是十进制整型。 第二行定义的是八进制整型,但是 month 变量无效,因为八进制没有 9 。

    下述字面值表示何种含义?它们各自的数据类型是什么?
    (a) “Who goes with F\145rgus?\012”
    (b) 3.14e1L
    © 1024f
    (d) 3.14L

    (a): Who goes with Fergus?(换行),string 类型
    (b): long double
    ©: 无效,因为后缀 f 只能用于浮点字面量,而 1024 是整型。
    (d): long double

    2.2.1 变量定义

    解释下列定义的含义,对于非法的定义,请说明错在何处并将其改正。
    (a) std::cin >> int input_value;
    (b) int i = { 3.14 };
    © double salary = wage = 9999.99;
    (d) int i = 3.14;

    (a): 应该先定义再使用。
    int input_value = 0;
    std::cin >> input_value;
    (b): 用列表初始化内置类型的变量时,如果存在丢失信息的风险,则编译器将报错。
    double i = { 3.14 };
    ©: 在这里 wage 是未定义的,应该在此之前将其定义。
    double wage;
    double salary = wage = 9999.99;
    (d): 不报错,但是小数部分会被截断。

    下列变量的初值分别是什么?
    std::string global_str;
    int global_int;
    int main()
    {
    int local_int;
    std::string local_str;
    }
    这里是引用

    global_int 是全局变量,所以初值为 0 。 local_int 是局部变量并且没有初始化,它的初值是未定义的。 global_str 和 local_str 是 string 类的对象,该对象定义了默认的初始化方式,即初始化为空字符串。

    2.2.2 变量声明和定义的关系

    指出下面的语句是声明还是定义:
    (a) extern int ix = 1024;
    (b) int iy;
    © extern int iz;

    (a): 定义
    (b): 定义
    ©: 声明

    2.2.3 标识符

    请指出下面的名字中哪些是非法的?
    (a) int double = 3.14;
    (b) int _;
    (c ) int catch-22;
    (d) int 1_or_2 = 1;
    (e) double Double = 3.14;

    (a), ©, (d) 非法。

    2.3.1 引用

    下面的哪个定义是不合法的?为什么?
    (a) int ival = 1.01;
    (b) int &rval1 = 1.01;
    (c ) int &rval2 = ival;
    (d) int &rval3;

    (b) 和 (d) 不合法,(b) 引用必须绑定在对象上,(d) 引用必须初始化。

    考察下面的所有赋值然后回答:哪些赋值是不合法的?为什么?哪些赋值是合法的?它们执行了哪些操作?
    int i = 0, &r1 = i; double d = 0, &r2 = d;
    (a) r2 = 3.14159;
    (b) r2 = r1;
    © i = r2;
    (d) r1 = d;

    (a): 合法。给 d 赋值为 3.14159。
    (b): 合法。会执行自动转换(int->double)。
    ©: 合法。会发生小数截取。
    (d): 合法。会发生小数截取。

    执行下面的代码段将输出什么结果?
    int i, &ri = i;
    i = 5; ri = 10;
    std::cout << i << " " << ri << std::endl;

    10, 10

    2.3.2 指针

    说明指针和引用的主要区别

    1.引用是另一个对象的别名,而指针本身就是一个对象。
    2.引用必须初始化,并且一旦定义了引用就无法再绑定到其他对象。而指针无须在定义时赋初值,也可以重新赋值让其指向其他对象。

    请叙述下面这段代码的作用。
    int i = 42;
    int *p1 = &i;
    *p1 = *p1 * *p1;

    让指针 pi 指向 i,然后将 i 的值重新赋值为 42 * 42 (1764)。

    请解释下述定义。在这些定义中有非法的吗?如果有,为什么?
    int i = 0;
    (a) double* dp = &i;
    (b) int *ip = i;
    © int *p = &i;

    (a): 非法。不能将一个指向 double 的指针指向 int
    (b): 非法。不能将 int 变量赋给指针。
    (c ): 合法。

    假设 p 是一个 int 型指针,请说明下述代码的含义。
    if (p ) // …
    if (*p) // …

    if § // … 判断 p 是不是一个空指针, if (*p) // … 判断 p 所指向的对象的值是不是为 0

    给定指针 p,你能知道它是否指向了一个合法的对象吗?如果能,叙述判断的思路;如果不能,也请说明原因。

    不能,因为首先要确定这个指针是不是合法的,才能判断它所指向的对象是不是合法的。

    在下面这段代码中为什么 p 合法而 lp 非法?
    int i = 42;
    void *p = &i;
    long *lp = &i;

    void * 是从 C语言那里继承过来的,可以指向任何类型的对象。而其他指针类型必须要与所指对象严格匹配。

    2.3.3 理解复合类型的声明

    说明下列变量的类型和值。
    (a) int* ip, i, &r = i;
    (b) int i, ip = 0;
    © int
    ip, ip2;

    (a): ip 是一个指向 int 的指针, i 是一个 int, r 是 i 的引用。
    (b): i 是 int , ip 是一个空指针。
    ©: ip 是一个指向 int 的指针, ip2 是一个 int。

    2.4 const限定符

    下面哪些语句是合法的?如果不合法,请说明为什么?

    const int buf; // 不合法, const 对象必须初始化
    int cnt = 0; // 合法
    const int sz = cnt; // 合法
    ++cnt; ++sz; // 不合法, const 对象不能被改变

    2.4.1 const的引用

    下面的哪些初始化是合法的?请说明原因。

    int i = -1, &r = 0; // 不合法, r 必须引用一个对象
    int *const p2 = &i2; // 合法
    const int i = -1, &r = 0; // 合法
    const int *const p3 = &i2; // 合法
    const int *p1 = &i2; // 合法
    const int &const r2; // 不合法, r2 是引用,引用没有顶层 const
    const int i2 = i, &r = i; // 合法

    说明下面的这些定义是什么意思,挑出其中不合法的。

    int i, *const cp; // 不合法, const 指针必须初始化
    int *p1, *const p2; // 不合法, const 指针必须初始化
    const int ic, &r = ic; // 不合法, const int 必须初始化
    const int *const p3; // 不合法, const 指针必须初始化
    const int *p; // 合法. 一个指针,指向 const int

    假设已有上一个练习中定义的那些变量,则下面的哪些语句是合法的?请说明原因。

    i = ic; // 合法, 常量赋值给普通变量
    p1 = p3; // 不合法, p3 是const指针不能赋值给普通指针
    p1 = ⁣ // 不合法, 普通指针不能指向常量
    p3 = ⁣ // 合法, p3 是常量指针且指向常量
    p2 = p1; // 合法, 可以将普通指针赋值给常量指针
    ic = *p3; // 合法, 对 p3 取值后是一个 int 然后赋值给 ic

    2.4.3 顶层const

    对于下面的这些语句,请说明对象被声明成了顶层const还是底层const?

    const int v2 = 0; int v1 = v2;
    int *p1 = &v1, &r1 = v1;
    const int *p2 = &v2, *const p3 = &i, &r2 = v2;
    v2 是顶层const,p2 是底层const,p3 既是顶层const又是底层const,r2 是底层const。

    假设已有上一个练习中所做的那些声明,则下面的哪些语句是合法的?请说明顶层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.4.4 constexpr和常量表达式

    下面的代码是否合法?如果非法,请设法将其修改正确。
    int null = 0, *p = null;

    非法.
    把int变量直接赋给指针是错误的操作,即使int变量的值恰好等于0也不行.
    int null = 0, *p = 0;

    2.5.2 类型别名

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

    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,所以不能被赋值

    判断下列定义推断出的类型是什么,然后编写程序进行验证。
    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.5.3 decltype类型指示符

    关于下面的代码,请指出每一个变量的类型以及程序结束时它们各自的值。
    int a = 3, b = 4;
    decltype(a) c = a;
    decltype((b)) d = a;
    ++c;
    ++d;

    c 是 int 类型,值为 4。d 是 int & 类型,绑定到 a,a 的值为 4 。

    赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型。也就是说,如果 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。

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

    decltype 处理顶层const和引用的方式与 auto不同,decltype会将顶层const和引用保留起来。
    int i = 0, &r = i;
    //相同
    auto a = i;
    decltype(i) b = i;
    //不同 d 是一个 int&
    auto c = r;
    decltype® d = r;

  • 相关阅读:
    Django03_Django基本配置
    “花式提涨薪,结果被套路”,不懂怎么跟老板提加薪?这个方法真的很好用
    剑指 Offer 40. 最小的k个数【查找排序】
    零基础 从 yolo8 入门计算机视觉超简单:物体识别、图像分类、轨迹追踪、姿势识别
    Qt excel 操作使用说明
    01准备阶段 Latex相关软件安装
    JAVA毕业设计家教信息管理系统计算机源码+lw文档+系统+调试部署+数据库
    关于阿里java开发规范中枚举类型字段必须有注释的思考
    第四种Web语言:WebAssembly
    学习-Java数组之foreach遍历数组之正负数数量统计
  • 原文地址:https://blog.csdn.net/L_H_L/article/details/126091953