火龙信奥
  • 首页
  • 课程
  • 题库
  • 打卡
    • 代码对战
    • 快速对战
  • 题单
  • 团队
  • 荣誉墙
  • 商城
  • 登录 / 注册

第6章 作用域

作者: 作者的头像   huolong , 时间:2025-09-02 16:14:57 , 所有人可见, 阅读  4

冬季学期 2024/2025

课程名称:编程导论(Einführung in die Programmierung)
章节:第6章 作用域(Gültigkeitsbereiche)
主讲人:Dr.-Ing. Alexander Krause
单位:多特蒙德工业大学 系统软件应用信息学12组
联系方式:eidp-problems@ls12.cs.tu-dortmund.de
课程官网: https://sys.cs.tu-dortmund.de/de/lehre/ws24/eidp/


第6章:作用域(Gültigkeitsbereiche)

学习目标

  • 理解局部变量与全局变量的作用域
  • 掌握变量遮蔽(Verdeckung)机制
  • 了解静态变量的生命周期
  • 熟悉命名空间(namespace)的使用与目的

1. 变量作用域基础

局部变量(Lokale Variablen)

  • 在函数或代码块 {} 内定义
  • 存储在栈内存(Stapelspeicher)
  • 作用域仅限于定义它的块
  • 块结束时变量失效

全局变量(Globale Variablen)

  • 在所有函数之外定义(通常在 main() 前)
  • 存储在静态内存(statischer Speicher)
  • 生命周期贯穿整个程序运行
  • 原则上处处可见,但可被同名局部变量遮蔽

2. 变量遮蔽与作用域层级

示例1:全局与局部变量同名

int x = 10;  // 全局变量

int main() {
    cout << x << endl;     // 输出: 10
    int x = 5;             // 局部变量,遮蔽全局变量
    cout << x << endl;     // 输出: 5
    cout << ::x << endl;   // 使用 :: 访问全局变量,输出: 10
    return 0;
}
:: 是作用域解析运算符(scope resolution operator),用于访问被遮蔽的全局变量。

示例2:嵌套代码块中的作用域
Cpp
深色版本
int k = -1;  // 全局变量

int main() {
    cout << "k global: " << k << endl;  // 输出: -1
    int k = 0;
    cout << "k main: " << k << endl;    // 输出: 0

    {
        int k = 1;
        cout << "k block1: " << k << endl;  // 输出: 1

        {
            int k = 2;
            cout << "k block2: " << k << endl;  // 输出: 2
        }

        cout << "k block1: " << k << endl;  // 输出: 1
    }

    cout << "k main: " << k << endl;       // 输出: 0
    cout << "k global: " << ::k << endl;   // 输出: -1
    return 0;
}

变量遮蔽规则:内层块中的同名变量会遮蔽外层变量,但外层变量仍存在。

  1. 循环变量的作用域 示例3:for 循环变量 Cpp
int main() {
    int i;
    for (i = 0; i < 100; ++i) {
        cout << i << endl;
    }
    cout << i << endl;  // ✅ 合法:i 在循环后仍存在

    for (int j = 0; j < 100; ++j) {
        cout << j << endl;
    }
    // cout << j << endl;  // ❌ 错误:j 作用域已结束
    return 0;
}

建议:

若循环变量后续还需使用,应在循环外声明 若仅用于循环,应在循环头中声明 4. 静态变量(Statische Variablen) 静态局部变量(Statische lokale Variablen) 使用 static 关键字声明 作用域:仅在定义它的函数/块内可见 生命周期:从首次初始化到程序结束,存储在静态内存 仅初始化一次 示例:计数器函数 Cpp

int countCalls() {
    static int ctr = 0;  // 仅在第一次调用时初始化
    return ++ctr;
}

int main() {
    for (int i = 0; i < 10; ++i)
        cout << countCalls() << endl;
    // 输出: 1 2 3 4 5 6 7 8 9 10
    return 0;
}

静态局部变量在函数多次调用间保持其值。

静态全局变量(Statische globale Variablen) 在文件级别使用 static 声明 作用域:仅限于定义它的源文件 其他文件无法通过 extern 访问 示例: Cpp

// 文件 Global.cpp
int global = 1;              // 全局,其他文件可见
static int globalS = 2;      // 静态全局,仅本文件可见

// 文件 Haupt.cpp
extern int global;           // ✅ 合法:可访问
// extern int globalS;       // ❌ 错误:static 变量不可 extern
注意:C++ 中静态全局变量已过时(deprecated),不建议使用。
  1. 命名空间(Namespaces) 目的:避免命名冲突 当多个开发者定义同名函数时,会发生冲突:

Cpp

// 开发者 A
void print(int n, double a[]) {
    // 正序输出
}

// 开发者 B
void print(int n, double a[]) {
    // 逆序输出
}
// ❌ 编译错误:重复定义
解决方案:命名空间
Cpp
深色版本
namespace A {
    void print(int n, double a[]) {
        // 正序输出
    }
}

namespace B {
    void print(int n, double a[]) {
        // 逆序输出
    }
}

int main() {
    double a[] = {1.1, 2.2, 3.3};
    A::print(3, a);  // 调用 A 的 print
    B::print(3, a);  // 调用 B 的 print
    return 0;
}

命名空间的使用 using namespace std;:使 std 中所有名称可见(如 cout, endl) 更安全的方式:using std::cout;,仅导入特定名称 支持嵌套命名空间:using namespace std::chrono; 建议:避免在头文件中使用 using namespace,以防污染全局命名空间。

  1. 总结 概念 关键点 局部变量 作用域在块内,栈存储,块结束即销毁 全局变量 全局可见,静态存储,程序结束销毁,易被遮蔽 作用域解析 :: 可访问被遮蔽的全局变量 静态局部变量 作用域局部,生命周期全局,仅初始化一次 静态全局变量 已过时,不建议使用 命名空间 避免命名冲突,推荐使用 using std::xxx 而非 using namespace std 最佳实践:尽量避免使用全局变量,优先使用局部变量和命名空间管理代码。

举例说明:

ttt.cpp

namespace A {
    void print(int n, double a[]) {
        // 正序输出
    }
    int global = 20;
}
#include<bits/stdc++.h>
#include "ttt.cpp"
using namespace std;


extern int global;

extern void print(int n, double a[]);

int main(){
    cout << A::global ; //必须加A::
    return 0;
}

—— 本文来自火龙信奥(义乌睿码科技):义乌青少年信息学奥赛与编程教育平台,专注 CSP-J/S、NOIP、GESP 竞赛培训,线上线下融合教学,助力编程升学。网址:hlcoding.com

©2026加盟我们 | 关于我们 | ACM课程 | 常见问题 | 成果墙 | 评测记录 | 浙ICP备2021013995号
在线画图 | OI WIki | 打字练习
火龙信奥
请输入登录信息


请完成安全验证
验证码底图 滑块
向右拖动滑块完成验证
请输入用户名 / 绑定的手机号码



请输入注册信息(手机号验证码注册)





验证码5分钟有效,60秒内不可重复获取,每日最多3次

微信登录

微信登录二维码

正在生成二维码...

账号已过期,请续期。
去续期

绑定手机号

📱

为了更好地保护您的账号安全,享受完整的平台服务

请您尽快绑定手机号码