侯捷 C++ 课程学习笔记:C++变量定义与数据类型

C++变量定义与数据类型

目录

C++变量定义与数据类型

前言

本篇目标

重难点说明

(一)教学重点

(二)教学难点

注意事项

学习正文

基本数据类型——整数类型

基本数据类型——浮点类型

存储位数和内存占用

精度和有效数字

取值范围

内存和性能

基础数据类型——字符类型

基础数据类型——布尔类型

变量定义与初始化

变量的命名规则

初始化方式

变量的作用域和生命周期

作用域(Scope)

生命周期(Lifetime)

变量的生命周期和作用域的关系

常量

const 关键字

constexpr 常量表达式

练习题

单选题-5

多选题-3

判断题-2

代码题-1

C++的优势对比于python的维度点说明


前言

本系列文章目的在于将C++的基础内容完全夯实,最终目的是为后期的深度学习在算法上有一定的铺垫,前期在学习数学的过程中也会有很大的帮助,相对于python来说C++有自身的优势,文末会有 C++的优势对比于python的维度点说明,所以我这里先写了C++的用法说明,后续会有Python的,各自有各自的优势,我们要根据具体的需求来分析使用哪种语言更为方便,其它的语言暂时不在考虑范畴之内,我们的目标是AI深度学习。

前置环境与代码结构文章:

1、C++环境理解与配置(MinGW)

2、C++的Visual Studio Code运行环境配置

3、头文件与类的声明

整体文章目录:入门 C++ 课程目录

本篇目标

  1. 掌握 C++ 中基本数据类型(整数、浮点、字符、布尔)的定义和使用。
  2. 理解不同数据类型的取值范围和存储大小。
  3. 掌握变量的命名规则和不同的初始化方式。
  4. 让了解变量的作用域和生命周期。
  5. 引导学会使用 const 关键字和 constexpr 定义常量。

重难点说明

(一)教学重点

  1. 基本数据类型的定义和使用。
  2. 变量的命名规则和初始化方式。
  3. const 和 constexpr 定义常量的方法。

(二)教学难点

  1. 理解不同数据类型的取值范围和存储大小。
  2. 区分变量的作用域和生命周期。

注意事项

1、编码格式异常

修正后效果:

学习正文

基本数据类型——整数类型

常见的整数类型:int、short、long、long long,它们在系统中的存储大小和取值范围如下:

类型最小值最大值
short-32768 (即 -2^1532767 (即 2^15 - 1
int-2147483648 (即 -2^312147483647 (即 2^31 - 1
long-2147483648 (即 -2^312147483647 (即 2^31 - 1
在 64 位系统中,通常为 -2^63 到 2^63 - 1
long long-9223372036854775808 (即 -2^639223372036854775807 (即 2^63 - 1

long long 是一种有符号的整数类型,它用于表示比 int 和 long 更大范围的整数值。在 C99 标准中引入了 long long 类型,随后 C++ 标准也采纳了这一类型。

#include <iostream>
#include <climits>

int main() {
    std::cout << "short 类型的最小值: " << SHRT_MIN << std::endl;
    std::cout << "short 类型的最大值: " << SHRT_MAX << std::endl;
    std::cout << "int 类型的最小值: " << INT_MIN << std::endl;
    std::cout << "int 类型的最大值: " << INT_MAX << std::endl;
    std::cout << "long 类型的最小值: " << LONG_MIN << std::endl;
    std::cout << "long 类型的最大值: " << LONG_MAX << std::endl;
    std::cout << "long long 类型的最小值: " << LLONG_MIN << std::endl;
    std::cout << "long long 类型的最大值: " << LLONG_MAX << std::endl;

    return 0;
}

基本数据类型——浮点类型

float 和 double 类型表述小数的类型,分为单精度与双精度,float 类型需要在数字后面加 f 或 F。

存储位数和内存占用
  • 单精度(float):float 类型通常占用 32 位(4 字节)的内存空间。这 32 位被划分为不同的部分,用于存储浮点数的符号、指数和尾数。
  • 双精度(double):double 类型一般占用 64 位(8 字节)的内存空间。相较于 float,它有更多的位数来存储浮点数的各个部分,从而能够表示更精确和更大范围的数值。
精度和有效数字
  • 单精度(float:float 类型大约能提供 6 - 7 位的有效数字。有效数字是指从左边第一个非零数字起,到精确到的位数止,所有的数字都叫做这个数的有效数字。例如,当你用 float 存储一个小数时,在大约 6 - 7 位之后的数字可能就不准确了。
  • 双精度(double:double 类型大约能提供 15 - 16 位的有效数字。由于它使用了更多的位数来存储尾数,所以能够表示更精确的小数,适用于对精度要求较高的计算,如科学计算、金融计算等。
取值范围
  • 单精度(float:float 类型的取值范围大约是 ±3.4×10^38,能表示的数值范围相对较小。
  • 双精度(double:double 类型的取值范围大约是 ±1.8×10^308,其取值范围比 float 大得多,可以表示非常大或非常小的数值。
内存和性能
  • 单精度(float:由于 float 只占用 4 字节的内存,相比 double 更节省内存空间。在处理大量浮点数数据时,使用 float 可以减少内存的使用量。而且在一些对性能要求较高、对精度要求不是特别苛刻的场景下,float 的计算速度可能会更快,因为它处理的数据量相对较小。
  • 双精度(double:double 占用 8 字节的内存,会消耗更多的内存资源。不过,现代计算机的处理器通常对 double 类型的计算也有很好的支持,在大多数情况下,double 的计算性能并不会比 float 差太多,除非在内存受限或对性能要求极高的场景下。

示例代码:

#include <iostream>
#include <iomanip>

int main() {
    float f = 3.14159265358979323846f;
    double d = 3.14159265358979323846;

    std::cout << std::setprecision(20);
    std::cout << "float value: " << f << std::endl;
    std::cout << "double value: " << d << std::endl;

    return 0;
}

基础数据类型——字符类型

char 类型用于存储单个字符,字符在计算机中的存储方式(ASCII 码)。

#include <iostream>

int main() {
    char ch = 'A';
    std::cout << "字符变量 ch 的值: " << ch << std::endl;
    std::cout << "字符 'A' 的 ASCII 码值: " << static_cast<int>(ch) << std::endl;

    return 0;
}

注:中文在C++中无法直接转换成ASCII码。

基础数据类型——布尔类型

bool 类型,只有两个值:true 和 false,用于逻辑判断。

#include <iostream>

int main() {
    bool isTrue = true;
    bool isFalse = false;

    std::cout << "布尔变量 isTrue 的值: " << isTrue << std::endl;
    std::cout << "布尔变量 isFalse 的值: " << isFalse << std::endl;

    return 0;
}

变量定义与初始化

变量的命名规则

只能由字母、数字和下划线组成,且不能以数字开头,不能使用 C++ 关键字。

// 合法的变量名
int age;
double price_1;
// 不合法的变量名
// int 123abc;  // 以数字开头
// int for;     // 使用了关键字
初始化方式
  • 直接初始化
    #include <iostream>
    
    int main() {
        int num(10);  // 直接初始化
        std::cout << "直接初始化的变量 num 的值: " << num << std::endl;
        return 0;
    }
  • 拷贝初始化
#include <iostream>

int main() {
    int num = 20;  // 拷贝初始化
    std::cout << "拷贝初始化的变量 num 的值: " << num << std::endl;
    return 0;
}

变量的作用域和生命周期

在C++中,变量的作用域(Scope)和生命周期(Lifetime)是两个重要的概念,它们决定了变量的可见性和存储时间。

作用域(Scope)

作用域是指变量可以被访问和使用的区域或范围。C++中的作用域可以分为以下几种:

  1. 全局作用域(Global Scope):全局变量定义在函数外部,整个程序都可以访问。
  2. 局部作用域(Local Scope):局部变量定义在函数内部,只能在该函数内访问。
  3. 块作用域(Block Scope):块变量定义在一个块(如if语句、循环语句等)内部,只能在该块内访问。
  4. 命名空间作用域(Namespace Scope):命名空间变量定义在一个命名空间内部,只能在该命名空间内访问。
生命周期(Lifetime)

生命周期是指变量从创建到销毁的时间段。C++中的生命周期可以分为以下几种:

  1. 静态存储期(Static Storage Duration):全局变量和静态局部变量的生命周期从程序开始到程序结束。
  2. 自动存储期(Automatic Storage Duration):局部变量的生命周期从变量定义到函数返回。
  3. 动态存储期(Dynamic Storage Duration):通过new运算符分配的内存的生命周期从分配到delete运算符释放。
  4. 线程存储期(Thread Storage Duration):线程局部变量的生命周期从线程开始到线程结束。
变量的生命周期和作用域的关系

变量的生命周期和作用域是相关的,但不是完全相同的。变量的生命周期决定了变量的存储时间,而作用域决定了变量的可见性。

  • 全局变量的生命周期是静态存储期,作用域是全局作用域。
  • 局部变量的生命周期是自动存储期,作用域是局部作用域。
  • 静态局部变量的生命周期是静态存储期,作用域是局部作用域。

以下是一个例子:

int globalVar = 10; // 全局变量,静态存储期,全局作用域

void func() {
    int localVar = 20; // 局部变量,自动存储期,局部作用域
    static int staticLocalVar = 30; // 静态局部变量,静态存储期,局部作用域
}

在这个例子中,globalVar的生命周期是静态存储期,作用域是全局作用域。localVar的生命周期是自动存储期,作用域是局部作用域。staticLocalVar的生命周期是静态存储期,作用域是局部作用域。

常量

const 关键字

const 关键字用于定义常量,常量一旦初始化后,其值不能再被修改。

#include <iostream>

int main() {
    const int MAX_VALUE = 100;
    MAX_VALUE = 200;  // 错误,常量的值不能修改
    std::cout << "常量 MAX_VALUE 的值: " << MAX_VALUE << std::endl;
    return 0;
}

 错误效果会直接显示出来。

constexpr 常量表达式

constexpr 用于在编译时计算常量表达式的值,提高程序的性能。

#include <iostream>

constexpr int square(int x) {
    return x * x;
}

int main() {
    constexpr int result = square(5);
    std::cout << "编译时计算的常量表达式结果: " << result << std::endl;
    return 0;
}

练习题

单选题-5

  1. 以下哪种类型不属于 C++ 的基本数据类型?
    A. int
    B. array
    C. char
    D. bool
    答案:B。array 不是基本数据类型,它是 C++ 标准库中的容器类型,intcharbool 属于基本数据类型。

  2. 已知 int a(5);,这种变量初始化方式是?
    A. 直接初始化
    B. 拷贝初始化
    C. 列表初始化
    D. 默认初始化
    答案:A。int a(5); 是直接初始化的语法形式,拷贝初始化是 int a = 5; 这种形式。

  3. 下面关于 const 常量的说法,正确的是?
    A. const 常量的值可以在程序运行过程中修改
    B. const 常量必须在定义时进行初始化
    C. const 常量可以不指定数据类型
    D. 以上说法都不对
    答案:B。const 常量一旦定义其值不能修改,且必须在定义时初始化,定义时必须指定数据类型。

  4. 若要表示一个单精度浮点数,应该使用的类型是?
    A. double
    B. float
    C. long double
    D. int
    答案:B。float 是单精度浮点数类型,double 是双精度浮点数类型,long double 精度更高,int 是整数类型。

  5. 下面哪个变量名是合法的 C++ 变量名?
    A. 2num
    B. for
    C. my_variable
    D. class
    答案:C。变量名不能以数字开头,for 和 class 是 C++ 关键字,不能作为变量名,my_variable 符合变量命名规则。

多选题-3

  1. 以下哪些属于 C++ 中整数类型?
    A. int
    B. short
    C. long
    D. float
    答案:ABC。float 是浮点类型,intshortlong 属于整数类型。

  2. 关于变量的作用域,以下说法正确的是?
    A. 全局变量的作用域是整个程序
    B. 局部变量的作用域从定义处开始,到所在代码块结束
    C. 局部变量在函数调用结束后就会销毁
    D. 全局变量在程序运行期间一直存在
    答案:ABCD。全局变量作用于整个程序,程序运行期间一直存在;局部变量作用于所在代码块,函数调用结束后销毁。

  3. 以下可以用来定义常量的有?
    A. const
    B. constexpr
    C. define(预处理指令)
    D. volatile
    答案:ABC。const 和 constexpr 是 C++ 中定义常量的方式,#define 是预处理指令也可定义常量,volatile 用于告诉编译器该变量可能会意外改变,不是定义常量的。

判断题-2

  1. bool 类型变量只有 true 和 false 两个值,在输出时 true 显示为 1,false 显示为 0。( )
    答案:正确。C++ 中 bool 类型确实只有这两个值,输出时通常按此规则显示。

  2. 变量在定义时可以不进行初始化,使用未初始化的变量不会有任何问题。( )
    答案:错误。使用未初始化的变量会导致未定义行为,可能得到不可预期的结果。

代码题-1

编写一个 C++ 程序来模拟一个简单的员工信息管理系统。该系统需要完成以下任务:

  1. 定义不同类型的变量来存储员工的相关信息,包括员工的姓名(使用 std::string 类型)、年龄(使用 int 类型)、工资(使用 double 类型)以及是否为正式员工(使用 bool 类型)。
  2. 从用户处获取这些员工信息,并将其存储到相应的变量中。
  3. 输出员工的所有信息,格式为:
    员工姓名: [姓名]
    员工年龄: [年龄]
    员工工资: [工资]
    是否为正式员工: [是/否]

    输入示例

    张三
    25
    5000.5
    1

    输出示例

    员工姓名: 张三
    员工年龄: 25
    员工工资: 5000.5
    是否为正式员工: 是

    示例代码:

注:在C++中,#include <limits> 是一个预处理指令,用于包含标准库头文件 <limits>。这个头文件定义了一些模板类和函数,用于查询数值类型的特性,例如最大值、最小值、精度等。

#include <iostream>
#include <string>
#include <limits> // 添加这一行

int main() {
    // 定义变量存储员工信息
    std::string employeeName;
    int employeeAge;
    double employeeSalary;
    bool isFullTime;

    // 从用户处获取员工信息
    std::cout << "请输入员工姓名: ";
    std::getline(std::cin, employeeName); 

    std::cout << "请输入员工年龄: ";
    std::cin >> employeeAge;
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 清除输入缓冲区中的换行符

    std::cout << "请输入员工工资: ";
    std::cin >> employeeSalary;
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); // 清除输入缓冲区中的换行符

    std::cout << "请输入员工是否为正式员工 (1 表示是, 0 表示否): ";
    std::cin >> isFullTime;

    // 输出员工信息
    std::cout << "员工姓名: " << employeeName << std::endl;
    std::cout << "员工年龄: " << employeeAge << std::endl;
    std::cout << "员工工资: " << employeeSalary << std::endl;
    std::cout << "是否为正式员工: " << (isFullTime ? "是" : "否") << std::endl;

    return 0;
}

操作示例结果:

C++的优势对比于python的维度点说明

对比维度C++ 优势Python 情况
性能效率1. 执行速度快:编译型语言,将代码编译为机器码,处理大量数据、复杂算法时效率高,能充分利用硬件资源。
2. 内存管理精细:允许程序员直接管理内存,精确控制分配和释放,优化内存使用,适合对内存要求苛刻的系统。
1. 执行速度慢:解释型语言,代码逐行解释执行,在处理大规模数据和复杂计算时性能较差。
2. 内存管理自动化:Python 有自动的垃圾回收机制,虽然方便但可能导致内存使用不够精细,在内存紧张的场景下可能出现问题。
底层控制能力1. 硬件访问能力强:可直接访问计算机硬件资源,如寄存器、内存地址等,便于与底层硬件高效交互,适用于驱动程序、嵌入式系统开发。
2. 系统级编程优势:在操作系统、编译器、数据库管理系统等系统软件开发中,能与底层系统更好交互,实现资源精细管理和控制,提升系统性能和稳定性。
底层控制能力弱:Python 主要用于高层级的应用开发,对底层硬件的直接访问能力有限,在系统级编程方面不够灵活和高效。
语言特性1. 强类型语言:编译时进行严格类型检查,有助于发现早期错误,提高代码稳定性和可靠性,减少运行时类型不匹配错误。
2. 支持多种编程范式:支持面向对象、泛型、函数式等多种编程范式,开发者可根据问题和需求灵活选择。
1. 动态类型语言:类型检查在运行时进行,虽然编写代码更灵活,但可能在运行时出现类型相关的错误,代码的稳定性和可维护性相对较弱。
2. 编程范式相对有限:主要以面向对象和函数式编程为主,泛型编程的支持不如 C++ 强大。
可移植性1. 跨平台能力:编写的代码可在不同操作系统上编译运行,只要有相应编译器和运行时环境,适合开发跨平台应用。
2. 库的可移植性:许多开源库和框架(如 Boost、Qt)具有良好可移植性,可在不同平台使用,减少跨平台开发工作量。
1. 跨平台性依赖解释器:Python 代码的跨平台性依赖于 Python 解释器,虽然大多数情况下能在不同操作系统上运行,但在一些涉及底层系统调用的场景下可能会有兼容性问题。
2. 部分库存在兼容性问题:虽然 Python 有丰富的库,但部分库在不同平台上的表现和兼容性可能存在差异。
生态系统和工具链1. 成熟的开发工具:有 Visual Studio、CLion、Eclipse 等成熟开发工具和集成开发环境,提供强大代码编辑、调试、性能分析等功能,提高开发效率。
2. 丰富的库资源:拥有大量专业级库,如用于数学计算的 LAPACK、图形处理的 OpenGL、网络编程的 ACE 等,为专业领域开发提供支持。
1. 开发工具相对简单:Python 的开发工具(如 PyCharm、VS Code 等)功能相对侧重于代码编辑和基本调试,在一些复杂的性能分析和底层调试方面不如 C++ 的开发工具强大。
2. 库更侧重于高层应用:Python 的库主要用于数据分析、机器学习、Web 开发等高层应用场景,在底层系统编程和高性能计算方面的专业库相对较少。
安全性和稳定性1. 资源管理安全:通过智能指针等机制,一定程度上保证资源安全管理,避免内存泄漏和悬空指针问题,提升程序稳定性和安全性。
2. 代码审查严格:语法相对复杂,在大型项目中严格的代码审查和规范可确保代码质量和安全性,减少潜在漏洞和风险。
1. 资源管理自动化存在隐患:自动垃圾回收机制可能导致一些资源管理问题,例如循环引用可能会造成内存泄漏,虽然 Python 有解决方案,但增加了复杂性。
2. 代码灵活性带来风险:动态类型和简洁的语法使得代码编写容易,但也可能导致代码的可读性和可维护性下降,增加了出现安全漏洞的风险。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值