C++学习笔记(四)

本文介绍了C++中的变量作用域,包括局部、全局、块和类作用域,以及变量初始化和覆盖规则。同时,讨论了C++中的常量,包括不同类型的常量和定义常量的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++ 变量作用域

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

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

局部变量。

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

形式参数。

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

全局变量。

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

  • 局部作用域

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

  • 全局作用域

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

  • 块作用域

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

  • 类作用域

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

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

局部变量

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

实例

#include iostream>

using namespace std;

int main ()

{

// 局部变量声明

int a, b;

int c;

// 实际初始化

a = 10;

b = 20;

c = a + b;

cout c;

return 0;

}

全局变量

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

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

实例

#include iostream>

using namespace std;

// 全局变量声明

int g;

int main ()

{

// 局部变量声明

int a, b;

// 实际初始化

a = 10;

b = 20;

g = a + b;

cout g;

return 0;

}

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

实例

#include iostream>

using namespace std;

// 全局变量声明

int g = 20;

int main ()

{

// 局部变量声明

int g = 10;

cout g;

return 0;

}

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

10

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

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

数据类型

初始化默认值

int

0

char

'\0'

float

0

double

0

pointer

NULL

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


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

实例#include

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

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

C++ 常量

常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。

常量可以是任何的基本数据类型,可分为整型数字、浮点数字、字符、字符串和布尔值。

常量就像是常规的变量,只不过常量的值在定义后不能进行修改。

整数常量

整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。

整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。

下面列举几个整数常量的实例:

212 // 合法的

215u // 合法的

0xFeeL // 合法的

078 // 非法的:8 不是八进制的数字

032UU // 非法的:不能重复后缀

以下是各种类型的整数常量的实例:

85 // 十进制

0213 // 八进制

0x4b // 十六进制

30 // 整数

30u // 无符号整数

30l // 长整数

30ul // 无符号长整数

浮点常量

浮点常量由整数部分、小数点、小数部分和指数部分组成。您可以使用小数形式或者指数形式来表示浮点常量。

当使用小数形式表示时,必须包含整数部分、小数部分,或同时包含两者。当使用指数形式表示时, 必须包含小数点、指数,或同时包含两者。带符号的指数是用 e 或 E 引入的。

下面列举几个浮点常量的实例:

3.14159 // 合法的

314159E-5L // 合法的

510E // 非法的:不完整的指数

210f // 非法的:没有小数或指数

.e55 // 非法的:缺少整数或分数

布尔常量

布尔常量共有两个,它们都是标准的 C++ 关键字:

  • true 值代表真。
  • false 值代表假。

我们不应把 true 的值看成 1,把 false 的值看成 0。

字符常量

字符常量是括在单引号中。如果常量以 L(仅当大写时)开头,则表示它是一个宽字符常量(例如 L'x'),此时它必须存储在 wchar_t 类型的变量中。否则,它就是一个窄字符常量(例如 'x'),此时它可以存储在 char 类型的简单变量中。

字符常量可以是一个普通的字符(例如 'x')、一个转义序列(例如 '\t'),或一个通用的字符(例如 '\u02C0')。

在 C++ 中,有一些特定的字符,当它们前面有反斜杠时,它们就具有特殊的含义,被用来表示如换行符(\n)或制表符(\t)等。下表列出了一些这样的转义序列码:

转义序列

含义

\\

\ 字符

\'

' 字符

\"

" 字符

\?

? 字符

\a

警报铃声

\b

退格键

\f

换页符

\n

换行符

\r

回车

\t

水平制表符

\v

垂直制表符

\ooo

一到三位的八进制数

\xhh . . .

一个或多个数字的十六进制数

下面的实例显示了一些转义序列字符:

实例

#include iostream>

using namespace std;

int main()

{

cout "Hello\tWorld\n\n";

return 0;

}

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

Hello World

字符串常量

字符串字面值或常量是括在双引号 "" 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。

您可以使用 \ 做分隔符,把一个很长的字符串常量进行分行。

下面的实例显示了一些字符串常量:

实例#include

#include

using namespace std;

int main() {

    string greeting = "hello, runoob";

    cout  greeting;

    cout  "\n";     // 换行符

    string greeting2 = "hello, \                       runoob";

    cout  greeting2;

    return 0;

}

hello, runoob hello, runoob

定义常量

在 C++ 中,有两种简单的定义常量的方式:

  • 使用 #define 预处理器。
  • 使用 const 关键字。

#define 预处理器

下面是使用 #define 预处理器定义常量的形式:

#define identifier value

具体请看下面的实例:

实例

#include iostream>

using namespace std;

#define LENGTH 10

#define WIDTH 5

#define NEWLINE '\n'

int main()

{

int area;

area = LENGTH * WIDTH;

cout area;

cout NEWLINE;

return 0;

}

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

50

const 关键字

您可以使用 const 前缀声明指定类型的常量,如下所示:

const type variable = value;

具体请看下面的实例:

实例

#include iostream>

using namespace std;

int main()

{

const int LENGTH = 10;

const int WIDTH = 5;

const char NEWLINE = '\n';

int area;

area = LENGTH * WIDTH;

cout area;

cout NEWLINE;

return 0;

}

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

50

请注意,把常量定义为大写字母形式,是一个很好的编程实践。

C++ 修饰符类型

C++ 允许在 char、int 和 double 数据类型前放置修饰符。

修饰符是用于改变变量类型的行为的关键字,它更能满足各种情境的需求。

下面列出了数据类型修饰符:

  • signed:表示变量可以存储负数。对于整型变量来说,signed 可以省略,因为整型变量默认为有符号类型。
  • unsigned:表示变量不能存储负数。对于整型变量来说,unsigned 可以将变量范围扩大一倍。
  • short:表示变量的范围比 int 更小。short int 可以缩写为 short。
  • long:表示变量的范围比 int 更大。long int 可以缩写为 long。
  • long long:表示变量的范围比 long 更大。C++11 中新增的数据类型修饰符。
  • float:表示单精度浮点数。
  • double:表示双精度浮点数。
  • bool:表示布尔类型,只有 true 和 false 两个值。
  • char:表示字符类型。
  • wchar_t:表示宽字符类型,可以存储 Unicode 字符。

修饰符 signed、unsigned、long 和 short 可应用于整型,signed 和 unsigned 可应用于字符型,long 可应用于双精度型。

这些修饰符也可以组合使用,修饰符 signed 和 unsigned 也可以作为 long 或 short 修饰符的前缀。例如:unsigned long int。

C++ 允许使用速记符号来声明无符号短整数或无符号长整数。您可以不写 int,只写单词 unsigned、short 或 long,int 是隐含的。例如,下面的两个语句都声明了无符号整型变量。

signed int num1 = -10; // 定义有符号整型变量 num1,初始值为 -10 unsigned int num2 = 20; // 定义无符号整型变量 num2,初始值为 20 short int num1 = 10; // 定义短整型变量 num1,初始值为 10 long int num2 = 100000; // 定义长整型变量 num2,初始值为 100000 long long int num1 = 10000000000; // 定义长长整型变量 num1,初始值为 10000000000 float num1 = 3.14f; // 定义单精度浮点数变量 num1,初始值为 3.14 double num2 = 2.71828; // 定义双精度浮点数变量 num2,初始值为 2.71828 bool flag = true; // 定义布尔类型变量 flag,初始值为 true char ch1 = 'a'; // 定义字符类型变量 ch1,初始值为 'a' wchar_t ch2 = L'你'; // 定义宽字符类型变量 ch2,初始值为 '你'

为了理解 C++ 解释有符号整数和无符号整数修饰符之间的差别,我们来运行一下下面这个短程序:

实例

#include iostream>

using namespace std;

/*

* 这个程序演示了有符号整数和无符号整数之间的差别

*/

int main()

{

short int i; // 有符号短整数

short unsigned int j; // 无符号短整数

j = 50000;

i = j;

cout i " " j;

return 0;

}

当上面的程序运行时,会输出下列结果:

-15536 50000

上述结果中,无符号短整数 50,000 的位模式被解释为有符号短整数 -15,536。

C++ 中的类型限定符

类型限定符提供了变量的额外信息,用于在定义变量或函数时改变它们的默认行为的关键字。

限定符

含义

const

const

定义常量,表示该变量的值不能被修改。。

volatile

修饰符

volatile

告诉该变量的值可能会被程序以外的因素改变,如硬件或其他线程。。

restrict

restrict

修饰的指针是唯一一种访问它所指向的对象的方式。只有 C99 增加了新的类型限定符 restrict。

mutable

表示类中的成员变量可以在 const 成员函数中被修改。

static

用于定义静态变量,表示该变量的作用域仅限于当前文件或当前函数内,不会被其他文件或函数访问。

register

用于定义寄存器变量,表示该变量被频繁使用,可以存储在CPU的寄存器中,以提高程序的运行效率。

const 实例

const int NUM = 10; // 定义常量 NUM,其值不可修改 const int* ptr = # // 定义指向常量的指针,指针所指的值不可修改 int const* ptr2 = # // 和上面一行等价

volatile 实例

volatile int num = 20; // 定义变量 num,其值可能会在未知的时间被改变

mutable 实例

class Example { public: int get_value() const { return value_; // const 关键字表示该成员函数不会修改对象中的数据成员 } void set_value(int value) const { value_ = value; // mutable 关键字允许在 const 成员函数中修改成员变量 } private: mutable int value_; };

static 实例

void example_function() { static int count = 0; // static 关键字使变量 count 存储在程序生命周期内都存在 count++; }

register 实例

void example_function(register int num) { // register 关键字建议编译器将变量 num 存储在寄存器中 // 以提高程序执行速度 // 但是实际上是否会存储在寄存器中由编译器决定 }

转自菜鸟教程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黄晓魚

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值