菜鸟教程 -- 学的不仅是技术,更是梦想!

C++ 教程
C++ 教程 C++ 简介 C++ 环境设置 C++ 基本语法 C++ 注释 C++ 数据类型 C++ 变量类型 C++ 变量作用域 C++ 常量 C++ 修饰符类型 C++ 存储类 C++ 运算符 C++ 循环 C++ 判断 C++ 函数 C++ 数字 C++ 数组 C++ 字符串 C++ 指针 C++ 引用 C++ 日期 & 时间 C++ 基本的输入输出 C++ 结构体(struct) C++ vector 容器 C++ 数据结构

C++ 面向对象

C++ 类 & 对象 C++ 继承 C++ 重载运算符和重载函数 C++ 多态 C++ 数据抽象 C++ 数据封装 C++ 接口(抽象类)

C++ 高级教程

C++ 文件和流 C++ 异常处理 C++ 动态内存 C++ 命名空间 C++ 模板 C++ 预处理器 C++ 信号处理 C++ 多线程 C++ Web 编程

C++ 资源库

C++ STL 教程 C++ 导入标准库 C++ 标准库 C++ 有用的资源 C++ 实例 C++ 测验 C++ <iostream> C++ <fstream> C++ <sstream> C++ <iomanip> C++ <array> C++ <vector> C++ <list> C++ <forward_list> C++ <deque> C++ <stack> C++ <queue> C++ <priority_queue> C++ <set> C++ <unordered_set> C++ <map> C++ <unordered_map> C++ <bitset> C++ <algorithm> C++ <iterator> C++ <functional> C++ <numeric> C++ <complex> C++ <valarray> C++ <cmath> C++ <string> C++ <regex> C++ <ctime> C++ <chrono> C++ <thread> C++ <mutex> C++ <condition_variable> C++ <future> C++ <atomic> C++ <type_traits> C++ <typeinfo> C++ <exception> C++ <stdexcept> C++ <cstdio> C++ <cstdint> C++ <memory> C++ <new> C++ <utility> C++ <random> C++ <locale> C++ <codecvt> C++ <cassert> C++ <cwchar> C++ <climits> C++ <cfloat> C++ <cstdlib> C++ <numbers> C++ OpenCV
(追記) (追記ここまで)

C++ 变量作用域

一般来说有三个地方可以定义变量:

  • 在函数或一个代码块内部声明的变量,称为局部变量

  • 在函数参数的定义中声明的变量,称为形式参数

  • 在所有函数外部声明的变量,称为全局变量

作用域是程序的一个区域,变量的作用域可以分为以下几种:

  • 局部作用域:在函数内部声明的变量具有局部作用域,它们只能在函数内部访问。局部变量在函数每次被调用时被创建,在函数执行完后被销毁。

  • 全局作用域:在所有函数和代码块之外声明的变量具有全局作用域,它们可以被程序中的任何函数访问。全局变量在程序开始时被创建,在程序结束时被销毁。

  • 块作用域:在代码块内部声明的变量具有块作用域,它们只能在代码块内部访问。块作用域变量在代码块每次被执行时被创建,在代码块执行完后被销毁。

  • 类作用域:在类内部声明的变量具有类作用域,它们可以被类的所有成员函数访问。类作用域变量的生命周期与类的生命周期相同。

注意:如果在内部作用域中声明的变量与外部作用域中的变量同名,则内部作用域中的变量将覆盖外部作用域中的变量。

局部变量

在函数或一个代码块内部声明的变量,称为局部变量。它们只能被函数内部或者代码块内部的语句使用。下面的实例使用了局部变量:

实例

#include<iostream>usingnamespacestd; intmain(){// 局部变量声明inta, b; intc; // 实际初始化a = 10; b = 20; c = a + b; cout << c; return0; }

全局变量

在所有函数外部定义的变量(通常是在程序的头部),称为全局变量。全局变量的值在程序的整个生命周期内都是有效的。

全局变量可以被任何函数访问。也就是说,全局变量一旦声明,在整个程序中都是可用的。下面的实例使用了全局变量和局部变量:

实例

#include<iostream>usingnamespacestd; // 全局变量声明intg; intmain(){// 局部变量声明inta, b; // 实际初始化a = 10; b = 20; g = a + b; cout << g; return0; }

在程序中,局部变量和全局变量的名称可以相同,但是在函数内,局部变量的值会覆盖全局变量的值。下面是一个实例:

实例

#include<iostream>usingnamespacestd; // 全局变量声明intg = 20; intmain(){// 局部变量声明intg = 10; cout << g; return0; }

当上面的代码被编译和执行时,它会产生下列结果:

10

初始化局部变量和全局变量

当局部变量被定义时,系统不会对其初始化,您必须自行对其初始化。定义全局变量时,系统会自动初始化为下列值:

数据类型初始化默认值
int 0
char '0円'
float 0
double 0
pointer NULL

正确地初始化变量是一个良好的编程习惯,否则有时候程序可能会产生意想不到的结果。


块作用域指的是在代码块内部声明的变量:

实例

#include <iostream>

int main() {
int a = 10;
{
int a = 20; // 块作用域变量
std::cout << "块变量: " << a << std::endl;
}
std::cout << "外部变量: " << a << std::endl;
return 0;
}

以上实例中,内部的代码块中声明了一个名为 a 的变量,它与外部作用域中的变量 a 同名。内部作用域中的变量 a 将覆盖外部作用域中的变量 a,在内部作用域中访问 a 时输出的是20,而在外部作用域中访问 a 时输出的是 10。

当上面的代码被编译和执行时,它会产生下列结果:

块变量: 20
外部变量: 10

类作用域

类作用域指的是在类内部声明的变量:

实例

#include <iostream>

class MyClass {
public:
static int class_var; // 类作用域变量
};

int MyClass::class_var = 30;

int main() {
std::cout << "类变量: " << MyClass::class_var << std::endl;
return 0;
}

以上实例中,MyClass 类中声明了一个名为 class_var 的类作用域变量。可以使用类名和作用域解析运算符 :: 来访问这个变量。在 main() 函数中访问 class_var 时输出的是 30。

类变量: 30
AI 思考中...

13 篇笔记 写笔记

  1. #0

    felix

    tri***[email protected]

    202

    在程序中,局部变量和全局变量的名称可以相同。

    但是在函数内的局部变量与全局变量是两个独立的变量,互不影响。

    下述代码中,全局变量定义了一个int g=99,局部变量定义了一个int g=10,由于这两个g所在的作用域不同,所以各自独立。

    #include <iostream>
    using namespace std;
    // 全局变量声明
    int g = 99;
    // 函数声明
    int func();
    int main()
    {
     // 局部变量声明
     int g = 10;
     //cout << g;
     int kk = func();
     cout << kk;
     return 0;
    }
    // 函数定义
    int func()
    {
     return g;
    }
    

    felix

    tri***[email protected]

    9年前 (2017年06月16日)
  2. #0

    一只迷途的羔羊

    985***[email protected]

    163

    在一个函数体内可以存在重名的变量,前提是它们的作用域不同。

    #include <iostream>
    using namespace std;
    int main()
    {
     int b = 2;
     {
     int b = 1;
     cout << "b = " << b << endl;
     }
     cout << "b = " << b << endl;
    }

    输出为:

    b = 1
    b = 2

    当变量间出现重名的情况下,作用域小的屏蔽作用域大的,所以上面第一个 cout 输出 b 的值为 1,但由于在块里面申请的变量作用域只限于当前块,所以离开这个块后变量会自动释放,所以第二个 cout 输出 b 的值为 2。

    一只迷途的羔羊

    985***[email protected]

    9年前 (2017年08月15日)
  3. #0

    一只待宰的羔羊

    758***[email protected]

    94

    全局变量的值可以在局部函数内重新赋值。

    #include <iostream>
    using namespace std;
    // 全局变量声明
    int g = 20;
    int fun1(int a,int b){
     g=a+b;
     cout<<"被改变的全局变量为:"<<g<<endl;
     return 0;
    }
    int fun2(){
     cout<<"此时的全局变量为:"<<g<<endl;
     return 0;
    }
    int main(){
     fun2();
     fun1(10,20);
     fun2();
     return 0;
    }

    一只待宰的羔羊

    758***[email protected]

    9年前 (2017年09月23日)
  4. #0

    xiaolin

    129***[email protected]

    113

    全局变量从定义处开始至程序结束起作用,即全局变量存在有效作用域。

    #include<iostream>
    using namespace std;
    int main()
    {
     cout<<"a= "<<a<<endl; //编译不通过,a是未知字符
     return 0;
    }
    int a=10; //全局变量从此处定义

    若要想让 main 函数也使用全局变量 a,可以用 extern 对全局变量进行声明,就可以合法使用了。

    #include<iostream>
    using namespace std;
    int main()
    {
     extern int a;
     cout<<"a= "<<a<<endl; //合法,输出10
     return 0;
    }
    int a=10; //全局变量从此处定义

    xiaolin

    129***[email protected]

    8年前 (2018年02月28日)
  5. #0

    RealRookie

    105***[email protected]

    196

    静态变量

    存储在静态数据区的变量会在程序刚开始运行时就完成初始化,也是唯一的一次初始化。共有两种变量存储在静态存储区:全局变量和 static 变量,只不过和全局变量比起来,static 可以控制变量的可见范围,说到底 static 还是用来隐藏的。虽然这种用法不常见。

    PS:如果作为 static 局部变量在函数内定义,它的生存期为整个源程序,但是其作用域仍与自动变量相同,只能在定义该变量的函数内使用该变量。退出该函数后, 尽管该变量还继续存在,但不能使用它。

    #include <iostream>
    using namespace std;
    int count = 1; //全局变量
    int fun()
    {
     static int count = 10; // 在第一次进入这个函数的时候,变量 count 被初始化为 10!并接着自减 1,以后每次进入该函数,count 的值是上一次函数运行之后的值
     return count--; // 就不会被再次初始化了,仅进行自减 1 的操作;在 static 发明前,要达到同样的功能,则只能使用全局变量
    }
     
    //int count = 1; //全局变量
     
    int main()
    {
     cout<<"global "<<"local staic"<<endl;
     for(; count <= 10; ++count)
     cout<<count<<" "<<fun()<<endl;
     return 0;
    }

    并且,由此可见全局变量和局部静态变量 count 的作用域是不同的。

    RealRookie

    105***[email protected]

    8年前 (2018年06月18日)
  6. #0

    117***[email protected]

    139

    全局变量和和局部变量同名时,可通过域名在函数中引用到全局变量,不加域名解析则引用局部变量

    #include<iostream>
    using namespace std;
    int a = 10;
    int main()
    {
     int a = 20;
     cout << ::a << endl; // 10
     cout << a << endl; // 20
     return 0;
    }

    117***[email protected]

    8年前 (2018年09月04日)
  7. #0

    C++ 全局变量、局部变量、静态全局变量、静态局部变量的区别

    C++ 变量根据定义的位置的不同的生命周期,具有不同的作用域,作用域可分为 6 种:全局作用域,局部作用域,语句作用域,类作用域,命名空间作用域和文件作用域

    从作用域看:

    全局变量具有全局作用域。全局变量只需在一个源文件中定义,就可以作用于所有的源文件。当然,其他不包含全局变量定义的源文件需要用extern 关键字再次声明这个全局变量。

    静态局部变量具有局部作用域,它只被初始化一次,自从第一次被初始化直到程序运行结束都一直存在,它和全局变量的区别在于全局变量对所有的函数都是可见的,而静态局部变量只对定义自己的函数体始终可见。

    局部变量也只有局部作用域,它是自动对象(auto),它在程序运行期间不是一直存在,而是只在函数执行期间存在,函数的一次调用执行结束后,变量被撤销,其所占用的内存也被收回。

    静态全局变量也具有全局作用域,它与全局变量的区别在于如果程序包含多个文件的话,它作用于定义它的文件里,不能作用到其它文件里,即被static关键字修饰过的变量具有文件作用域。这样即使两个不同的源文件都定义了相同名字的静态全局变量,它们也是不同的变量。

    从分配内存空间看:

    全局变量,静态局部变量,静态全局变量都在静态存储区分配空间,而局部变量在栈里分配空间。

    全局变量本身就是静态存储方式, 静态全局变量当然也是静态存储方式。这两者在存储方式上并无不同。这两者的区别虽在于非静态全局变量的作用域是整个源程序,当一个源程序由多个源文件组成时,非静态的全局变量在各个源文件中都是有效的。 而静态全局变量则限制了其作用域, 即只在定义该变量的源文件内有效,在同一源程序的其它源文件中不能使用它。由于静态全局变量的作用域局限于一个源文件内,只能为该源文件内的函数公用,因此可以避免在其它源文件中引起错误。

    • 1)、静态变量会被放在程序的静态数据存储区(数据段)(全局可见)中,这样可以在下一次调用的时候还可以保持原来的赋值。这一点是它与堆栈变量和堆变量的区别。
    • 2)、变量用static告知编译器,自己仅仅在变量的作用范围内可见。这一点是它与全局变量的区别。

    从以上分析可以看出, 把局部变量改变为静态变量后是改变了它的存储方式即改变了它的生存期。把全局变量改变为静态变量后是改变了它的作用域,限制了它的使用范围。因此static 这个说明符在不同的地方所起的作用是不同的。应予以注意。

    Tips:

    • A、若全局变量仅在单个C文件中访问,则可以将这个变量修改为静态全局变量,以降低模块间的耦合度;
    • B、若全局变量仅由单个函数访问,则可以将这个变量改为该函数的静态局部变量,以降低模块间的耦合度;
    • C、设计和使用访问动态全局变量、静态全局变量、静态局部变量的函数时,需要考虑重入问题,因为他们都放在静态数据存储区,全局可见;
    • D、如果我们需要一个可重入的函数,那么,我们一定要避免函数中使用static变量(这样的函数被称为:带"内部存储器"功能的的函数)
    • E、函数中必须要使用static变量情况:比如当某函数的返回值为指针类型时,则必须是static的局部变量的地址作为返回值,若为auto类型,则返回为错指针。

    -----------------------------------------------------------------------------------------------------------

    static 全局变量:改变作用范围,不改变存储位置

    static 局部变量:改变存储位置,不改变作用范围

    静态函数 :在函数的返回类型前加上static关键字,函数即被定义为静态函数。静态函数与普通函数不同,它只能在声明它的文件当中可见,不能被其它文件使用。

    如果在一个源文件中定义的函数,只能被本文件中的函数调用,而不能被同一程序其它文件中的函数调用,这种函数也称为内部函数。定义一个内部函数,只需在函数类型前再加一个"static"关键字即可。

    %fs 8年前 (2018年10月18日)
  8. #0

    114***[email protected]

    59

    在 VS2013 环境,对全局变量的引用以及重新赋值,直接用全局变量名会出现:count 变量不明确的问题

    在变量名前加上 :: 符号即可。

    #include <iostream>
    using namespace std;
    int count = 10; //全局变量初始化
    int main()
    {
     ::count = 1; //全局变量重新赋值
     for (;::count <= 10; ++::count)
     {
     cout <<"全局变量count="<< ::count << endl;
     }
     return 0;
    }

    114***[email protected]

    8年前 (2019年01月05日)
  9. #0

    tgdzsjh

    tgd***[email protected]

    17

    全局变量和局部变量作用域不同,static 关键字可限定引用范围:

    #include <stdio.h>
    int s32Test; // 定义全局变量,系统默认初始化0
    static void Fun(); // 声明只限定在被当前文件调用的函数
    static void Fun()
    {
     int s32Test = 1; // 局部变量,如果不初始化,会是一个随机数值
     //与全局变量名相同,会屏蔽全局变量调用,s32Test = 1
     printf("This is Fun(),s32Test = %d!", s32Test); 
    }
    int main()
    {
     Fun();
     return 0;
    }

    tgdzsjh

    tgd***[email protected]

    7年前 (2019年03月14日)
  10. #0

    字符 '0' 和 '0円' 及整数 0 的区别

    字符型变量用于存储一个单一字符,在 C 语言中用 char 表示,其中每个字符变量都会占用 1 个字节(8 位二进制数)。

    整型 int 在内存中占用空间为四个字节(32位二进制数)。

    字符 '0':char c = '0'; 它的 ASCII 码实际上是 48,内存中存放表示:00110000。

    字符 '0円': ASCII 码为 0,表示一个字符串结束的标志。这是转义字符(整体视为一个字符)。由于内存中存储字符,依然是存储的是对应字符集的字符编码,所以内存中的表现形式为 00000000。

    整数 0 : 内存中表示为 00000000 00000000 00000000 00000000,虽然都是 0,但是跟上面字符 '0円' 存储占用长度是不一样的。

    信耐恒 7年前 (2019年11月11日)
  11. #0

    VALUE

    phj***[email protected]

    34

    函数体里面对全局变量的修改会改变全局变量的值:

    #include <iostream>
    #include<limits>
    using namespace std;
    int c=0;
    float area(float a,float b);// 声明函数
    int main()
    {
     
     float length,width;
     length=10.0;
     width=5.0;
     c=10;
     cout << c <<endl;
     float areas=area(length,width);// 调用函数
     
     cout << areas <<endl;
     return 0;
    }
    // 定义函数
    float area(float a,float b){
     cout << c <<endl;
     return a*b;
    }

    VALUE

    phj***[email protected]

    6年前 (2020年12月18日)
  12. #0

    爱情神话

    314***[email protected]

    12

    变量的初始化就是在定义变量的时候,直接对变量进行赋值操作。

    初始化的方式一般有如下两种:

    1、直接对变量进行赋予常量数值进行初始化。

    2、通过同类型变量进行初始化。

    // 以下属于第1种初始化方式
    int a1=5; // 整型变量的初始化
    int b1[]={1,2,3,4}; // 整型数组的初始化
    char str1[]="abcd"; // 字符数组的初始化
    // 以下属于第2种初始化方式
    int a2 = a1; // 整型变量的初始化
    int b2[4] = b1; // 整型数组的初始化
    char str2[4] = str1;// 字符数组的初始化
    char *p = str1; // 字符指针的初始化

    爱情神话

    314***[email protected]

    3年前 (2023年03月11日)
  13. #0

    菜鸟n号

    129***[email protected]

    13

    MyClass::class_var 中的 :: 是作用域解析运算符,用于访问类的静态成员。而 std::cout 中的 :: 用于指定 coutstd 命名空间中的对象。这两者虽然在使用语法上看起来相似,但它们代表的含义和用途完全不同。

    菜鸟n号

    129***[email protected]

    2年前 (2024年09月23日)

点我分享笔记

  • 昵称 (必填)
  • 邮箱 (必填)
  • 引用地址

AltStyle によって変換されたページ (->オリジナル) /