C++的作用域、变量作用域、生命周期和变量分类介绍

这篇具有很好参考价值的文章主要介绍了C++的作用域、变量作用域、生命周期和变量分类介绍。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C++的作用域、变量作用域、生命周期和变量分类介绍

C++ 中的作用域(scope)指的是变量、函数或其他标识符的可见和可访问的范围。

变量作用域(Variable Scope)是指变量的生命周期和可见性,也就是变量在程序中的哪些部分可以使用。按照作用域(Scope)变量可分类为全局变量和局部变量。

还可按照生命周期(Lifetime)进行分类变量可分类为静态变量(Static Variables)和成员变量(Member Variables)。

C++的作用域(scope)

C++中的作用域(scope)是指变量、函数和其他标识符的可见性和有效性范围。作用域规定了在程序中的哪些位置可以访问或引用某个标识符。参见Scope - cppreference.com

C++中有以下几种作用域:块作用域(Block Scope)、函数参数作用域(Function parameter scope)、命名空间作用域(Namespace Scope)、类作用域(Class Scope)、枚举常量作用域(Enum Constant Scope)、模板形参作用域(Template parameter scope)。

  1. 块作用域(Block Scope):代码块内部声明的变量拥有块作用域,只在该代码块内可见,包括循环、条件语句等。
  2. 函数参数作用域(Function Parameter Scope):函数参数也拥有自己的作用域,仅在函数内部有效,允许使用相同名称的局部变量隐藏函数参数。
  3. 命名空间作用域(Namespace Scope):命名空间中定义的标识符拥有命名空间作用域,可以在整个命名空间范围内访问。
  4. 类作用域(Class Scope):类成员(包括变量、函数等)拥有类作用域,可以在类内部访问,并通过对象或指针进行访问。
  5. 枚举常量作用域(Enum Constant Scope):枚举类型中的常量拥有常量作用域,只能在枚举类型内部访问。
  6. 模板形参作用域(Template Parameter Scope):模板类或函数中的模板形参拥有自己的作用域,只在模板定义内有效。

在C++中,作用域(Scope)和变量的作用域(Variable Scope)并不完全相同,尽管它们之间有密切关联。

作用域(Scope)是指标识符(如变量、函数等)在程序中可见和有效的范围。作用域规定了在哪些位置可以访问或引用某个标识符。作用域涵盖了整个程序,从全局范围到更小的范围(如代码块内部、函数内部等)。

变量的作用域(Variable Scope)则是指在程序中某个位置声明的变量可见和有效的范围。变量的作用域是作用域的一种应用,它决定了在何处可以使用该变量以及该变量的生命周期。

因此,作用域是一个更广泛的概念,可以包括各种标识符(如函数、类、命名空间等),而变量的作用域则专门指的是变量在程序中的可见性和有效性范围。

C++中变量的作用域(Variable Scope)

在C++中,变量的作用域可以通过其声明的位置来确定。在不同的作用域内,变量的可见性和有效范围会有所不同。下面是几种常见的变量作用域。

★全局作用域(Global scope):全局作用域表示变量在整个程序中都可见。在任何函数或代码块之外声明的变量都具有全局作用域。这些变量在程序开始执行时创建,在程序结束时销毁。例如:

#include <iostream>
int x = 10; // 全局变量

int main() {
    std::cout << x << std::endl; // 输出:10
    return 0;
}

在上面的示例中,变量x在main函数中被访问,因为它具有全局作用域。

★函数作用域(Function scope):函数作用域表示变量仅在函数内可见。变量在函数内部声明,只能在同一函数内访问。函数作用域的变量在函数执行时创建,在函数结束时销毁。例如:

#include <iostream>

void printNumber() {
    int num = 5; // 函数作用域中的变量
    std::cout << num << std::endl; // 输出:5
}

int main() {
    printNumber();
    // std::cout << num << std::endl; // 错误:变量num不在作用域内
    return 0;
}

在上面的示例中,变量num仅在printNumber函数内部可见。

★代码块作用域(Block scope):代码块作用域表示变量仅在代码块内部可见。变量在任何代码块(例如if语句、循环等)内部声明,只能在同一代码块内或嵌套在此代码块内的其他代码块中访问。块作用域可以嵌套,内部代码块可以访问外部代码块中声明的变量,但反之则不行。例如:

#include <iostream>

int main() {
    if (true) { // 代码块作用域
        int num = 5; // 代码块作用域中的变量
        std::cout << num << std::endl; // 输出:5
        {
            std::cout << num << std::endl; // 输出:5,嵌套代码块中仍然可见
        }
    }
    // std::cout << num << std::endl; // 错误:变量num不在作用域内
    return 0;
}

在上面的示例中,变量num仅在if语句所在的代码块中可见。

★函数参数作用域(Function parameter scope):函数参数也具有自己的作用域,它们在函数内部有效。函数参数作用域指的是这些参数在整个函数内部可见。例如:

#include <iostream>

void printNumber(int num) { // 函数参数作用域中的变量
    std::cout << num << std::endl; // 输出由传入的参数值决定
}

int main() {
    printNumber(10); // 输出:10
    return 0;
}

在上面的示例中,函数参数num在整个printNumber函数内部可见。

注意,变量的作用域是通过声明位置来确定的,因此相同的变量名可以在不同的作用域中被使用。这样,它们代表的是不同的变量。当在内部作用域中声明与外部作用域中相同名称的变量时,内部作用域内的变量会隐藏外部作用域中的同名变量。例如:

#include <iostream>

int x = 5; // 全局变量

void printNumber() {
    int x = 10; // 局部变量,隐藏了全局变量x
    std::cout << x << std::endl; // 输出:10
}

int main() {
    std::cout << x << std::endl; // 输出:5,全局变量x
    printNumber();
    return 0;
}

在上面的示例中,函数printNumber内部声明的局部变量x隐藏了全局变量x,所以在函数内部输出的x值为10,而在main函数中输出的x值为5。

★类作用域(Class Scope):在类内部声明的变量具有类作用域,可以被类中的所有成员函数访问。类作用域的变量在对象创建时创建,在对象销毁时销毁。例如:

#include <iostream>

class MyClass {
public:
    int x; // 类作用域中的变量

    void printX() {
        std::cout << "类作用域中的变量:" << x << std::endl;
    }
};

int main() {
    MyClass obj;
    obj.x = 10; // 修改类作用域中的变量
    obj.printX(); // 输出类作用域中的变量

    return 0;
}

运行输出

类作用域中的变量:10

生命周期(Lifetime)

生命周期(Lifetime)指的是变量或对象存在的时间段。它开始于变量或对象的创建时刻,结束于其被销毁的时刻。

对于变量,生命周期包括了变量的创建、初始化、使用和销毁这几个阶段。在变量的创建阶段,内存空间被分配给该变量,并根据定义的类型进行初始化。在变量的使用阶段,可以对变量进行读取、修改等操作。最后,在变量的作用域结束或者显式释放内存时,变量会被销毁,其占用的内存空间被释放。

对于对象,生命周期也类似。对象的生命周期包括了对象的构造、使用和析构这几个阶段。在对象的构造阶段,会调用构造函数来初始化对象的成员变量。在对象的使用阶段,可以通过对象来调用其成员函数进行各种操作。最后,在对象不再被使用或者超出其作用域时,会调用析构函数来清理对象所占用的资源。

C++提供了灵活的方式来管理对象和变量的生命周期,如手动创建和销毁对象。

由程序员使用 new 运算符分配的变量被称为动态分配的变量。在C++中,new 运算符用于在堆内存(heap)上动态地分配内存空间,并返回指向该内存空间的指针。

与静态分配的变量(例如在栈上分配的局部变量)不同,动态分配的变量的生存期不受其作用域的限制。它们会一直存在,直到显式释放或删除。

通过new运算符分配的变量需要手动释放内存,以避免内存泄漏。使用delete运算符来释放动态分配的变量,以便将内存归还给系统。

以下是一个使用new和delete进行动态内存分配和释放的示例:

int* dynamicVariable = new int; // 动态分配一个整型变量

// 使用 dynamicVariable 进行操作

delete dynamicVariable; // 释放内存

请注意,动态分配的变量需要我们手动管理其生命周期,确保在不再需要时及时释放内存,以避免内存泄漏和资源浪费。

变量分类

按照作用域(Scope)和生命周期(Lifetime)的不同,可以将变量进行分类。

全局变量和局部变量是按照作用域进行划分的,全局变量(Global Variables)的作用域是整个程序,局部变量(Local Variables)的作用域是在其所属函数或语句块中。

静态变量和成员变量是按照生命周期进行划分的,静态变量(Static Variables)的声明周期是程序的整个运行期间,成员变量(Member Variables)的生命周期与其所属对象的生命周期相关联。静态变量在函数内部或类内部声明,在多次函数调用之间保持其值的持久性。成员变量是类内部声明的变量,每个类对象都有一份独立的拷贝。

全局变量(Global Variables)、局部变量(Local Variables

按照作用域(Scope)变量可分类为全局变量和局部变量。

全局变量(Global Variables)是在任何函数外部声明的变量,它们具有全局作用域,可以在整个程序中访问。全局变量在程序开始执行时创建,在程序结束时销毁。

而局部变量(Local Variables)是在函数内部声明的变量,它们具有函数作用域或块作用域,只能在其所属的函数或代码块内部访问。局部变量在其所属的函数或代码块执行时创建,在函数调用结束或代码块执行完毕后被销毁。

全局变量和局部变量不同点:

作用域不同:全局变量在整个程序范围内可见,而局部变量仅在其所属的函数或代码块内可见。

存储位置不同:全局变量存储在静态存储区,局部变量通常存储在栈上。

生命周期不同:全局变量在程序运行期间一直存在,而局部变量在其所属的函数或代码块执行期间存在。

需要注意的是,全局变量的使用应谨慎,因为它们对整个程序状态具有持久性影响,并且可能导致命名冲突。为了避免这些问题,应尽量将变量的作用域限制在其必要的范围内,只在需要时使用全局变量。

C++中全局变量、局部变量和变量的作用域的关系

在C++中,全局变量、局部变量和变量的作用域之间存在着一定的关系。以下是它们之间的关系:

全局变量:全局变量(Global Variables)是在任何函数外部声明的变量,具有全局作用域,可以在整个程序中访问。它们在程序开始执行时创建,在程序结束时销毁。全局变量可以被程序中的任何函数使用,包括主函数(main)以及其他自定义函数。全局变量对程序中的所有函数都是可见和可访问的。

局部变量:局部变量(Local Variables)是在函数内部声明的变量,具有函数作用域或块作用域,只能在其所属的函数或代码块内部访问。局部变量在其所属的函数或代码块执行时创建,在函数调用结束或代码块执行完毕后被销毁。局部变量的作用域限定在声明它们的函数或代码块内部,超出该范围就无法访问。

注意事项:

在同一个作用域内,变量名必须是唯一的,否则会引发命名冲突。

当全局变量和局部变量具有相同的名称时,在函数内部访问该名称时,局部变量将优先被使用。

在嵌套的作用域内可以有同名的变量。内层作用域中的变量将覆盖外层作用域中的变量。在内层作用域中,同名的变量将引用内层作用域中的变量。当离开内层作用域时,外层作用域中的变量将再次可见。

在函数内部可以通过作用域解析操作符(::)来访问全局变量,以区分同名的局部变量。

下面示例展示了C++中全局变量和局部变量的使用:

#include <iostream>

// 全局变量
int globalVariable = 10;

void func() {
    // 局部变量
    int localVariable = 5;
    
    // 打印全局变量和局部变量
    std::cout << "全局变量 globalVariable 的值: " << globalVariable << std::endl;
    std::cout << "局部变量 localVariable 的值: " << localVariable << std::endl;
}

int main() {
    func();
    
    // 这里无法访问局部变量 localVariable
    std::cout << "全局变量 globalVariable 的值: " << globalVariable << std::endl;
    
    return 0;
}

输出示例:

全局变量 globalVariable 的值: 10
局部变量 localVariable 的值: 5
全局变量 globalVariable 的值: 10

静态变量(Static Variables)和成员变量(Member Variables

按照生命周期(Lifetime)进行分类变量可分类为静态变量(Static Variables)和成员变量(Member Variables)。

静态变量(Static Variables)是在函数内部或类内部声明的变量,具有静态存储持续性。这意味着它们在每次函数调用或类实例化时都保持其值,并且在多次调用间不会被重新初始化。

在 C++ 中,使用 static 关键字可以声明静态变量。静态变量与普通变量的区别在于其生命周期和作用域。普通变量在函数执行完毕后被销毁,而静态变量在整个程序运行期间都存在,只会被销毁一次。静态变量的作用域也不同,静态变量在声明它的文件中全局可见,但在其他文件中不可见。而普通变量的作用域仅限于声明它的作用域内。

例如:

#include<iostream> 
using namespace std;
void func() {
    static int count = 0;
    count++;
    cout << "Count: " << count << endl;
}

int main() {
    func(); // 输出:Count: 1
    func(); // 输出:Count: 2
    func(); // 输出:Count: 3
    return 0;
}

在上面的例子中,变量count被声明为静态变量,它在每次调用func函数时保持其值,实现了计数的功能。

成员变量(Member Variables)是定义在类中的变量,用于描述类的属性和状态。成员变量可以在整个类中被访问和使用。通常,每个对象拥有自己的一组成员变量,它们的值相互独立。

在C++中,成员变量的定义通常放在类的声明中,并且没有具体的赋值。在类的对象创建时,每个成员变量将被赋予默认值,例如整数类型的成员变量将被赋值为0,字符类型的成员变量将被赋值为空字符。

例如:

示例中,Rectangle 类有两个成员变量 width 和 height。我们创建了一个名为 rect 的对象,并使用点运算符(.)设置成员变量的值。然后通过点运算符访问成员变量的值,并计算矩形的面积。

需要注意的是,成员变量的访问权限可以根据类中的访问说明符进行控制。例如,如果将成员变量定义为 private,则只能在类的内部访问和修改这些变量的值。

在类内部声明的静态变量是类静态成员变量

在类内部声明的静态成员变量在每个类对象之间都有一份独立的拷贝,它在所有该类对象之间共享。例如:

#include<iostream> 
using namespace std;

class MyClass {
public:
    static int count; // 类静态成员变量声明
    
    MyClass() {
        count++;
    }
};

int MyClass::count = 0; // 在类外部初始化静态成员变量

int main() {
    MyClass obj1;
    cout << "Count: " << obj1.count << endl; // 输出:Count: 1
    
    MyClass obj2;
    cout << "Count: " << obj2.count << endl; // 输出:Count: 2
    
    return 0;
}

在上面的例子中,静态成员变量count被声明为类MyClass的一部分,因此它与类的每个对象实例相独立。每次创建一个新的MyClass对象时,count的值增加一次。通过类名和作用域解析操作符::访问静态成员变量。

在C++中,上面介绍的这些常见的变量类型之外,还有:

形参变量(Parameter Variables):函数的参数也是一种变量,在函数内部使用,参数变量的作用域仅限于函数内部,离开函数后其分配的存储空间会自动被释放——形参在函数退出后被销毁。

外部变量(extern variable):外部变量是指在一个文件中声明,在其他文件中定义和使用的变量。在 C++ 中,使用 extern 关键字声明外部变量。

等等。

小结

C++ 中的作用域指的是变量、函数或其他标识符的可见和可访问的范围。

变量作用域是指变量的生命周期和可见性,也就是变量在程序中的哪些部分可以使用。

全局变量和局部变量按照作用域(Scope)进行分类,全局变量的作用域是整个程序,局部变量的作用域是在其所属函数或语句块中。

静态变量和成员变量按照生命周期(Lifetime)进行分类,静态变量的生命周期是整个程序运行期间,成员变量的生命周期与所属对象相关联。文章来源地址https://www.toymoban.com/news/detail-642742.html

到了这里,关于C++的作用域、变量作用域、生命周期和变量分类介绍的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 44-js return返回值,全局作用域,局部作用域,隐式作用域,变量的生命周期,delete释放内存

    1. return 返回值:函数执行后剩下结果就是返回值。 2.作用域 查找变量的时候,会从当前作用域开始查找,如果当前作用域查找不到,逐层(外层)向上查找 2.1全局作用域 2.2局部作用域 

    2024年02月02日
    浏览(52)
  • 【C语言趣味教程】(4) 变量:代码注释 | 变量的声明 | 初始化与赋值 | 作用域与生命周期 | 局部变量与全局变量

      🔗 《C语言趣味教程》👈 猛戳订阅!!! 0x00 引入:注释的作用 \\\"程序员最讨厌两种人:一种是不写注释的人,一种是让我写注释的人。\\\" 相信大家对注释早已有所耳闻,对于注释,C 语言有两种注释风格,我们下面会逐个讲解。   但在这之前,我们先来了解了解注释的作

    2024年02月15日
    浏览(49)
  • DevOps 在改进软件开发生命周期中的作用

          软件开发是一个复杂多变的领域,需要不断地投入、迭代和协作。在当今激烈的市场竞争中,对可靠、及时和高质量解决方案的需求空前高涨。DevOps 是一种革命性的方法,是应对这些挑战的基础。DevOps 不仅仅是一种方法,它还将软件开发和 IT 运营无缝整合在一起,

    2024年02月19日
    浏览(40)
  • MyBatis:生命周期、作用域、结果集映射 ResultMap、日志、分页、使用注解开发、Lombok

    理解不同 作用域 和 生命周期 类别是至关重要的,因为错误的使用会导致非常严重的 并发问题 。 SqlSessionFactoryBuilder 一旦创建了 SqlSessionFactory,就不再需要它了; 最佳作用域 是方法作用域(也就是局部方法变量)。 SqlSessionFactory :相当于 数据库连接池 一旦被创建就应该在

    2024年02月02日
    浏览(56)
  • 【Spring学习】Bean对象的作用域和生命周期,了解了这些你就真正熟悉spring框架了.

    前言: 大家好,我是 良辰丫 ,我们已经学会了Spring的存取,今天我们将一起来学习Bean对象的作用域和生命周期.💌💌💌 🧑个人主页:良辰针不戳 📖所属专栏:javaEE进阶篇之框架学习 🍎励志语句:生活也许会让我们遍体鳞伤,但最终这些伤口会成为我们一辈子的财富。 💦期

    2024年02月07日
    浏览(63)
  • 微信小程序——生命周期,生命周期的分类,页面生命周期,生命周期函数的分类,应用的生命周期函数,页面的生命周期函数,wxs脚本概述

    生命周期( Life Cycle )是指一个对象从创建-运行-销毁的整个阶段,强调的是一个时间段。 例如: .张三出生,表示这个人生命周期的开始 .张三离世,表示这个人生命周期的结束 .中间张三的一生,就是张三的生命周期 我们可以把每个小程序运行的过程,也概括为生命周

    2024年02月01日
    浏览(63)
  • Bean 作用域和生命周期

    Spring 容器是用来存储和读取 Bean 的 , 因此 Bean 是 Spring 中最核心的操作资源. 编写代码过程中 , bean 对象如果有多个属性 , 创建 Getter , Setter, 构造方法 等方法 , 会产生大量冗长的代码. 那么为了使代码更加简洁 , 我们可以使用 Lombok 框架 , 只需要一行注释 , 就可以避免大量冗长

    2024年02月05日
    浏览(79)
  • Bean作用域和生命周期

    hi,今天为大家带啦Bean的作用域和生命周期的相关知识 Bean的作用域和我们之前学过的不一样,我们之前学的作用域是一个范围,而现在指的是 Bean在Spring框架中的某种行为模式,也就是一个动作. 这样干巴巴的说看我可能无法理解,我们来举个例子 创建一个公共类的一个公共对象

    2024年02月15日
    浏览(53)
  • Spring的作用域与生命周期

    lombok插件可以提供给我们一些注释,这些注释可以很好的帮助我们消除Java代码中大量冗余的代码,可以使得我们的Java类可以看起来非常的干净整洁 1.安装lombok插件 2.pom.xml导入依赖 3.基本使用 我们创建一个简单的User实体类 如果我们手动的在类中加入setter+getter,toString等等,如

    2023年04月24日
    浏览(35)
  • Bean的作用域和生命周期

    目录 1.作⽤域定义 1.1Bean的6个作用域 1.singleton:单例作用域 2.prototype:多例作用域 3.request:请求作用域 4.session:会话作用域 5.application:全局作用域 6.websocket:HTTP WebSocket作用域 单例作⽤域(singleton) VS 全局作⽤域(application) 1.2设置作用域 1.直接设置值@Scope(\\\"potptype\\\") 2.用枚举设置:@Scop

    2024年02月02日
    浏览(89)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包