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

这一章是C++的基石,虽然内容比较基础,但极其重要,很多概念会贯穿整个C++学习过程。

2.1 基本内置类型

C++定义了一组基本算术类型:

整数类型

#include <iostream>

int main()
{
    bool flag = true;        // 布尔类型:true 或 false,1字节
    char ch = 'A';           // 字符类型,1字节
    wchar_t wch = L'中';     // 宽字符,用于扩展字符集
    short s = 100;           // 短整型,通常2字节
    int i = 1000;            // 整型,通常4字节
    long l = 100000L;        // 长整型,通常4或8字节
    long long ll = 1000000LL;// 长长长整型,通常8字节
    
    std::cout << "bool: " << flag << std::endl;
    std::cout << "char: " << ch << std::endl;
    std::cout << "int: " << i << std::endl;
    
    return 0;
}

浮点类型

#include <iostream>

int main()
{
    float f = 3.14f;         // 单精度浮点数,通常4字节
    double d = 3.1415926;    // 双精度浮点数,通常8字节
    long double ld = 3.141592653589793238L; // 扩展精度浮点数
    
    std::cout << "float: " << f << std::endl;
    std::cout << "double: " << d << std::endl;
    std::cout << "long double: " << ld << std::endl;
    
    return 0;
}

2.2 类型转换

隐式类型转换

#include <iostream>

int main()
{
    // 布尔转换:非零为true,零为false
    bool b = 3;          // b = true
    bool b2 = 0;         // b2 = false
    
    // 浮点转整数:截断小数部分
    int i = 3.14;        // i = 3
    
    // 整数转浮点:添加小数部分
    double d = 3;        // d = 3.0
    
    // 无符号整数溢出:取模
    unsigned char c = -1; // c = 255 (因为-1 mod 256 = 255)
    
    std::cout << "bool b: " << b << std::endl;
    std::cout << "int i from 3.14: " << i << std::endl;
    std::cout << "unsigned char c from -1: " << (int)c << std::endl;
    
    return 0;
}

显式类型转换

#include <iostream>

int main()
{
    int i = 10;
    double d = 3.14;
    
    // C风格强制转换
    int truncated = (int)d;           // truncated = 3
    
    // 函数风格强制转换
    int truncated2 = int(d);          // truncated2 = 3
    
    // static_cast(C++推荐方式)
    double result = static_cast<double>(i) / 4;  // result = 2.5
    
    std::cout << "truncated: " << truncated << std::endl;
    std::cout << "result: " << result << std::endl;
    
    return 0;
}

2.3 变量声明和定义

#include <iostream>

// 声明(在头文件中常见)
extern int global_var;    // 声明global_var,定义在其他文件

// 定义(分配存储空间)
int global_var = 100;     // 定义global_var

int main()
{
    // 定义并初始化变量
    int units_sold = 0;
    int units_sold2 = {0};    // 列表初始化(C++11)
    int units_sold3{0};       // 列表初始化(C++11)
    int units_sold4(0);       // 直接初始化
    
    // 默认初始化
    std::string empty_str;    // 空字符串
    int local_var;            // 未初始化!值不确定
    
    std::cout << "global_var: " << global_var << std::endl;
    std::cout << "empty_str: '" << empty_str << "'" << std::endl;
    
    // 注意:局部内置类型变量不会自动初始化!
    // std::cout << local_var << std::endl; // 危险!值不确定
    
    return 0;
}

2.4 复合类型

引用(Reference)

#include <iostream>

int main()
{
    int value = 42;
    int &ref = value;        // ref是value的引用(别名)
    
    std::cout << "value: " << value << std::endl;    // 42
    std::cout << "ref: " << ref << std::endl;        // 42
    
    ref = 100;               // 通过引用修改原变量
    std::cout << "value after change: " << value << std::endl;  // 100
    
    // 引用必须在定义时初始化
    // int &ref2;           // 错误!引用必须初始化
    
    // 引用一旦绑定就不能重新绑定到其他对象
    int another = 200;
    // &ref = another;      // 错误!不能重新绑定
    
    return 0;
}

指针(Pointer)

#include <iostream>

int main()
{
    int value = 42;
    int *ptr = &value;       // ptr指向value(存储value的地址)
    
    std::cout << "value: " << value << std::endl;        // 42
    std::cout << "ptr: " << ptr << std::endl;            // 地址值
    std::cout << "*ptr: " << *ptr << std::endl;          // 42(解引用)
    
    *ptr = 100;              // 通过指针修改原变量
    std::cout << "value after change: " << value << std::endl;  // 100
    
    // 指针可以重新指向其他对象
    int another = 200;
    ptr = &another;          // ptr现在指向another
    std::cout << "*ptr after reassign: " << *ptr << std::endl;  // 200
    
    // 空指针的几种表示方法
    int *p1 = nullptr;       // C++11推荐(最安全)
    int *p2 = 0;             // 传统方式
    int *p3 = NULL;          // C传统方式(在cstdlib中定义)
    
    return 0;
}

2.5 const限定符

基本const用法

#include <iostream>

int main()
{
    const int bufSize = 512;    // 定义常量
    // bufSize = 1024;          // 错误!不能修改const变量
    
    const int i = get_size();   // 运行时初始化
    const int j = 42;           // 编译时初始化
    const int k;                // 错误!const变量必须初始化
    
    // const对象默认只在文件内有效
    // 如果想在多个文件间共享const对象,需要在定义和声明前都加extern
    return 0;
}

const与引用(常量引用)

#include <iostream>

int main()
{
    int i = 42;
    const int &r1 = i;        // 正确:允许将const int&绑定到普通int上
    const int &r2 = 42;       // 正确:常量引用可以绑定到字面值
    const int &r3 = r1 * 2;   // 正确:常量引用可以绑定到表达式结果
    
    // int &r4 = 42;          // 错误:普通引用不能绑定到字面值
    
    std::cout << "r1: " << r1 << std::endl;
    std::cout << "r2: " << r2 << std::endl;
    std::cout << "r3: " << r3 << std::endl;
    
    return 0;
}

const与指针

#include <iostream>

int main()
{
    int value = 42;
    int another = 100;
    
    // 指向常量的指针(pointer to const)
    const int *ptr1 = &value;  // ptr1指向一个常量
    // *ptr1 = 50;             // 错误!不能通过ptr1修改value
    ptr1 = &another;           // 正确!ptr1可以指向其他对象
    
    // 常量指针(const pointer)
    int *const ptr2 = &value;  // ptr2本身是常量
    *ptr2 = 50;                // 正确!可以通过ptr2修改value
    // ptr2 = &another;        // 错误!ptr2不能指向其他对象
    
    // 指向常量的常量指针
    const int *const ptr3 = &value;  // ptr3本身是常量,指向的对象也是常量
    // *ptr3 = 50;             // 错误!
    // ptr3 = &another;        // 错误!
    
    std::cout << "value: " << value << std::endl;  // 50
    
    return 0;
}

2.6 类型别名与auto

类型别名

#include <iostream>

// 使用typedef创建类型别名
typedef double wages;         // wages是double的别名
typedef wages base, *p;       // base是double的别名,p是double*的别名

// 使用using创建类型别名(C++11)
using salary = double;        // salary是double的别名

int main()
{
    wages hourly = 25.5;      // 相当于 double hourly = 25.5;
    salary monthly = 5000.0;  // 相当于 double monthly = 5000.0;
    
    std::cout << "时薪: " << hourly << std::endl;
    std::cout << "月薪: " << monthly << std::endl;
    
    return 0;
}

auto类型说明符(C++11)

#include <iostream>
#include <typeinfo>

int main()
{
    int i = 42;
    const int ci = i;
    
    // auto让编译器自动推断类型
    auto a = i;               // a是int
    auto b = ci;              // b是int(顶层const被忽略)
    auto c = &i;              // c是int*
    auto d = &ci;             // d是const int*(底层const保留)
    
    // 引用和auto
    auto &e = ci;             // e是const int&
    // auto &f = 42;          // 错误!不能为非常量引用绑定字面值
    const auto &g = 42;       // 正确!可以为常量引用绑定字面值
    
    std::cout << "type of a: " << typeid(a).name() << std::endl;
    std::cout << "type of d: " << typeid(d).name() << std::endl;
    
    return 0;
}

📝 第二章关键要点总结

  1. 内置类型选择

    • 算术运算:用intdouble
    • 明确知道不可能为负:用unsigned
    • 字符:用char
    • 布尔:用bool
  2. 引用vs指针

    • 引用:别名,必须初始化,不能重新绑定
    • 指针:存储地址,可以重新指向,可以为空
  3. const用法

    • const int*:指向常量的指针(底层const)
    • int* const:常量指针(顶层const)
    • const int&:常量引用
  4. 初始化

    • 局部内置类型变量不会自动初始化
    • 类类型变量有默认初始化
    • 推荐使用列表初始化{}

这一章的概念非常重要,特别是指针、引用和const,它们会在整个C++学习中反复出现。如果有任何不清楚的地方,建议多写代码实验!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值