上一篇文章介绍到了变量的作用域 <= 传送门,接着之前的继续。
变量作用域
局部变量
只能被函数内部或者代码块内部的语句使用。
全局变量
全局变量的值在程序的整个生命周期内都是有效的,可以被在程序的任意位置被访问。
注意:在程序中,函数内与全局变量同名的局部变量的值会覆盖全局变量的值。
定义全局变量时,系统会自动初始化为下列值,而定义局部变量系统不会自动初始化:
据类型 | 初始化默认值 |
---|---|
int | 0 |
char | '\0' |
float | 0 |
double | 0 |
pointer | NULL |
常量
常量是固定值,在程序执行期间不会改变。这些固定的值,又叫做字面量。常量可以是任何的基本数据类型,可分为整型数字、浮点数字、字符、字符串和布尔值。
整数常量
整数常量可以是十进制、八进制或十六进制的常量。前缀指定进制:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。
整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意,但是不能重复。
浮点常量
浮点常量由整数部分、小数点、小数部分或小数部分和指数部分组成。也就是说可以使用小数形式或者指数形式来表示浮点常量。
小数形式:由数字0~9和小数点组成。分为整数和小数两部分,可以是纯小数,小数点不能省略。
例如:100.5,-1.0,.123,5.,0.0、3.14159等。
指数形式:必须由尾数(十进制小数)、符号E 或 e 及指数(十进制整数)三部分组成。
例如:123.0E-1,1.23E3,4.89e-4 314159E-5L
布尔常量
布尔常量共有两个,它们都是标准的 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 . . . | 一个或多个数字的十六进制数 |
字符串常量
字符串字面值或常量是括在双引号 "" 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。
可以使用反斜杠“ \ ”做分隔符,把一个很长的字符串常量进行分行,下面这三种形式所显示的字符串是相同的(字符串双引号可以直接连接):
"hello, dear"
"hello, \
dear"
"hello, " "d" "ear"
常量的定义(常量定义为大写字母形式)
在 C++ 中,有两种简单的定义常量的方式:
- 使用 #define 预处理器。
- 使用 const 关键字。
#define 预处理器
下面是使用 #define 预处理器定义常量的形式:
#define identifier value
//#define WIDTH 5
const 关键字
使用 const 前缀声明指定类型的常量,如下所示:
const type variable = value;
//const int WIDTH = 5;
存储类
存储类定义 C++ 程序中变量/函数的范围(可见性)和生命周期。C++ 程序中可用的存储类:
- auto
- register
- static
- extern
- mutable
- thread_local (C++11)
auto 存储类
自 C++ 11 以来,auto 关键字用于两种情况:
1. 声明变量时根据初始化表达式自动推断该变量的类型
2. 声明函数时函数返回值的占位符。
从 C++ 17 开始,auto 关键字不再是 C++ 存储类说明符。根据初始化表达式自动推断被声明的变量的类型,如:
auto f=3.14; //double
auto s("hello"); //const char*
auto z = new auto(9); // int*
auto x1 = 5, x2 = 5.0, x3='r';//错误,auto后面必须是初始化为同一类型
register 存储类
register 存储类用于定义存储在寄存器中而不是 RAM 中的局部变量。这意味着变量的最大尺寸等于寄存器的大小(通常是一个字),且不能对它应用一元的 '&' 运算符(因为它没有内存位置)。寄存器只用于需要快速访问的变量,比如计数器。还应注意的是,定义 'register' 并不意味着变量将被存储在寄存器中,它意味着变量可能存储在寄存器中,这取决于硬件和实现的限制。从 C++ 17 开始,且 register 关键字被弃用。定义方式:
{
register int miles;
}
static 存储类
static 存储类指示编译器在程序的生命周期内保持局部变量的存在,而不需要在每次它进入和离开作用域时进行创建和销毁。因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值(下一次调用函数时静态局部变量的值是上一次调用结束的值)。
static 修饰符也可以应用于全局变量。当 static 修饰全局变量时,会使变量的作用域限制在声明它的文件内。
#include <iostream>
using namespace std;
void func(void); //函数声明
static int count = 10; //全局静态变量声明定义和初始化
int main()
{
while(count--)
{
func();
}
return 0;
}
// 函数定义
void func( void )
{
static int i = 5; // 局部静态变量的声明定义和初始化
i++;
cout << "变量 i 为 " << i ;
cout << " , 变量 count 为 " << count <<endl;
}
extern 存储类
extern 存储类用于提供一个全局变量的引用,这种全局变量对所有的程序文件都是可见的。extern 修饰符通常用于当有两个或多个文件共享相同的全局变量或函数的时候,如下:
第一个文件:main.cpp:
#include <iostream>
int count ;
extern void write_extern();
int main()
{
count = 5;
write_extern();
}
第二个文件:support.cpp:
#include <iostream>
extern int count;
void write_extern(void)
{
cout << "Count is " << count << endl;
}
这样一来, 也就是当前文件如果要访问一个其他文件中的定义的变量或者调用其他文件定义的函数,当前文件就需要用extern来声明此变量或者函数。
mutable 存储类
mutable 说明符仅适用于类的对象,它允许对象的成员替代常量。也就是说,mutable 成员可以通过 const 成员函数修改。
thread_local 存储类
使用 thread_local 说明符声明的变量仅可被它所处的线程所访问。 变量在创建线程时创建,并在销毁线程时销毁。 每个线程都有其自己的变量副本。thread_local 说明符可以与 static 或 extern 合并。
可以将 thread_local 仅应用于数据声明和定义,但thread_local 不能用于函数声明或定义。
运算符
算术运算符
运算符 | 描述 |
+ | 把两个操作数相加 |
- | 从第一个操作数中减去第二个操作数 |
* | 把两个操作数相乘 |
/ | 分子除以分母 |
% | 取模运算符,整除后的余数 |
++ | 整数值增加 1,前缀形式先自增再进行表达式运算,后缀形式相反 |
-- | 整数值减少 1,前缀形式先自增再进行表达式运算,后缀形式相反 |
关系运算符
运算符 | 描述 |
== | 检查两个操作数的值是否相等,如果相等则条件为真。 |
!= | 检查两个操作数的值是否相等,如果不相等则条件为真。 |
> | 检查左操作数的值是否大于右操作数的值,如果是则条件为真。 |
< | 检查左操作数的值是否小于右操作数的值,如果是则条件为真。 |
>= | 检查左操作数的值是否大于或等于右操作数的值,如果是则条件为真。 |
<= | 检查左操作数的值是否小于或等于右操作数的值,如果是则条件为真。 |
逻辑运算符
运算符 | 描述 |
&& | 称为逻辑与运算符。如果两个操作数都非零,则条件为真。 |
|| | 称为逻辑或运算符。如果两个操作数中有任意一个非零,则条件为真。 |
! | 称为逻辑非运算符。用来逆转操作数的逻辑状态。如果条件为真则逻辑非运算符将使其为假。 |
位运算符
运算符 | 描述 |
& | 同为1,为1,否则为0 |
| | 同为0,为0,否则为1 |
^ | 相同为0,不同为1 |
~ | 取反运算,1变0,0变1 |
<< | 左移指定位数 |
>> | 右移指定位数 |
赋值运算符
运算符 | 描述 |
= | 把右边操作数的值赋给左边操作数 |
+= | 把右边操作数加上左边操作数的结果赋值给左边操作数 |
-= | 把左边操作数减去右边操作数的结果赋值给左边操作数 |
*= | 把右边操作数乘以左边操作数的结果赋值给左边操作数 |
/= | 把左边操作数除以右边操作数的结果赋值给左边操作数 |
%= | 求两个操作数的模赋值给左边操作数 |
<<= | 把左边操作数左移右边操作数位后赋值给左边操作数 |
>>= | 把左边操作数右移右边操作数位后赋值给左边操作数 |
&= | 把左边操作数按位与赋值给左边操作数 |
^= | 把左边操作数按位异或赋值给左边操作数 |
|= | 把左边操作数按位或赋值给左边操作数 |