C++ Primer 第二章 变量和基本类型

使用作用域操作符获取全局变量的值

#include <iostream>
// 该程序仅用于说明:函数内部不宜定义与全局变量同名的新变量
int reused = 42;
int main() {

    int unique = 0;
    // 输出#1:使用全局变量reused;输出 42 0
    std::cout << reused << ' ' << unique << std::endl;
    int reused = 0;
    // 输出#2:使用局部变量reused; 输出 0 0
    std::cout << reused << ' ' << unique << std::endl;
    // 输出#3:显式地访问全局变量reused; 输出 42 0
    std::cout << ::reused << ' ' << unique << std::endl;
    return 0;
}

引用

  • 引用并非对象,相反的,它只是为一个已经存在的对象所起的另外一个名字 使用 '&'
#include <iostream>

int main() {

    int i = 1024, i2 = 2048; // i 和 i2 都是int
    int &r = i, r2 = i2;     // r 是一个引用,与 i 绑定在一起,r2 是int
    int i3 = 1024, &ri = i3; // i3 是 int ,ri 是一个引用,与 i3 绑定在一起
    int &r3 = i3, &r4 = i2;  // r3 和 r4 都是引用

    std::cout << i << std::endl
              << i2 << std::endl
              << i3 << std::endl
              << r << std::endl
              << r2 << std::endl
              << ri << std::endl
              << r3 << std::endl
              << r4 << std::endl;

    return 0;
}

// 输出
// 1024
// 2048
// 1024
// 1024
// 2048
// 1024
// 1024
// 2048

空指针

nullptr、0、NULL
NULL 在 #include <cstdlib> 中

只要指针拥有一个合法值,就能将它用在条件表达式中,如果指针的值是0,条件取false, 否则取true。
指针也可以用相等操作符( == ) 和不相等操作符( != )来比较。

void*指针

void* 可以存放任意对象的地址。
它可以:和别的指针比较、作为函数的输入输出或者赋给另外一个 void* 指针。

double obj = 3.14, *pd = &pbj;
                    // 正确:void* 能存放任意类型对象的地址
void *pv = &obj;   // pbj 可以是任意类型的对象
pv = pd;            // pv 可以存放任意类型的指针

声明符中修饰符的个数没有限制

#include <iostream>

int main() {

    int ival = 1024;
    int *pi = &ival;
    int **ppi = &pi;

    std::cout << ival << std::endl
              << *pi << std::endl
              << **ppi << std::endl;

    // 输出:
    // 1024
    // 1024
    // 1024

    return 0;
}

指向指针的引用

    int i = 42; 
    int *p;         // p 是一个 int 型指针
    int *&r = p;    // r 是一个对指针 p 的引用

    r = &i;         // r 引用了一个指针,因此给 r 赋值 &i 就是令 p 指向 i
    *r = 0;         // 解引用 r 得到 i,也就是 p 指向的对象,将 i 的值改为 0

类型别名

两种方法

// 关键字 typedef
typedef double wages; // wages 是 double 的同义词
typedef wages base, *p; // base 是 double 的同义词, p 是 double* 的同义词

// 别名声明
using SI = Sales_item; // SI 是 Sales_item 的同义词

wages hourly, weekly; // 等价于 double hourly, weekly;
SI item; // 等价于 Sales_item item;
注意
typedef char *pstring;
const pstring cstr = 0; // cstr 是指向 char 的常量指针
const pstring *ps; // ps 是一个指针, 它的对象是指向 char 的常量指针

// const 是对给定类型的修饰 pstring 是指向 char 的指针,
// 因此 const pstring 就是指向 char 的常量指针,而非指向常量字符的指针

const char *cstr = 0; // 是对 const pstring cstr 的错误理解
// 声明语句中用到 pstring 时,其基本数据类型时指针 而非 const char

decltype

作用:选择并返回操作数的数据类型
decltype(f()) sum = x; // sum 的类型就是函数 f 的返回类型

// decltype 的结果可以是引用类型
int i = 42, *p = &i, &r = i;
decltype(r + 0) b; // 正确: 加法的结果是 int, 因此 b 是一个(未初始化的)int
decltype(*p) c; // 错误:c 是 int& 必须初始化

/*
decltype((variabel)) (注意是双层括号)的结果永远是引用,而 decltype(variable) 结果只有当 variable 本身就是
一个引用时才是引用。
*/

decltype((i)) d; // 错误:d 是 int& 必须初始化
decltype(i) e; // 正确:e 是一个(未初始化的)int
赋值是会产生引用的一类典型表达式,引用的类型就是左值的类型。也就是说,如果 i 是 int,则表达式 i = x 的类型是 int&。

自定义数据结构

在主函数完成Sales_data的操作

#include <iostream>
#include <string>
#include "Sales_data.h"

int main() {

    Sales_data data1, data2;

    double price = 0; // 书的单价,用于计算销售收入
    // 读入第一笔交易:ISBN、销售数量、单价
    std::cin >> data1.bookNo >> data1.units_sold >> price;
    // 计算销售输入
    data1.revenue = data1.units_sold * price;

    // 读入第二笔交易
    std::cin >> data2.bookNo >> data2.units_sold >> price;
    data2.revenue = data2.units_sold * price;

    if (data1.bookNo == data2.bookNo) {
        unsigned totalCnt = data1.units_sold + data2.units_sold;
        double totalRevenue = data1.revenue + data2.revenue;
        // 输出:ISBN、总销售量、总销售额、平均价格
        std::cout << data1.bookNo << ' ' << totalCnt << ' ' << totalRevenue << ' ';
        if (totalCnt != 0) {
            std::cout << totalRevenue / totalCnt << std::endl;
        } else {
            std::cout << "(no sales)" << std::endl;
        }
        return 0; // 标识成功
    } else { // 两笔交易的ISBN不一样
        std::cerr << "Data must refer to the same ISBN" << std::endl;
        return -1; // 标识失败
    }

    return 0;
}

编写自己的头文件

头文件保护符
  • #define 指令把一个名字设定为预处理变量
  • #ifdef 当且仅当变量已定义时为真
  • #ifndef 当且仅当变量未定义时为真
  • 一旦检查结果为真,则执行后续操作直至遇到 #endif 指令为止
#ifndef SALES_DATA_H
#define SALES_DATA_H
#include <iostream>
#include <string>

struct Sales_data {
    std::string bookNo;
    unsigned units_sold = 0;
    double revenue = 0.0;
};
#endif
posted @ 2022-12-29 21:20  HuiPuKui  阅读(54)  评论(1)    收藏  举报