C++基础
1. 基本变量类型
类型 | 关键字 |
---|---|
布尔型 | bool(1bit) |
字符型 | char(1字节) |
整数型 | short(2字节)、int(4字节)、long(4字节)、long long(8字节) |
浮点型 | float(4字节)、double(8字节)、long double(12字节) |
有符号和无符号signed、unsigned进行变量修饰。有符号就是变量有正负,无符号就是没有负数(可以表示更多的正数)
2. typedef声明
typedef int zhengshu;//给已有的类型取一个别名
3. 枚举类型
如果一个变量只有几种可能的值,可以定义为枚举(enumeration)类型。所谓"枚举"是指将变量的值一一列举出来,变量的值只能在列举出来的值的范围内。(有点类似用来列举常量的意思)
enum color{
red, //0 每个标志符都有一个整型常数,默认数字从0开始
blue=4, //4 显示赋值为4
black //5 在上一个的基础上自动+1
} c;
c = blue; //输出c的值 是4,
//如果要输出string,需要类似一个映射规则,if或者map实现
const char* ToString(color c)
{
switch (c) {
case red: return "Red";
case blue: return "Blue";
case black: return "Black";
default: return "";
}
}
4. 变量作用域
作用域是程序的一个区域,表示变量可以被引用的范围。一般来说有三个地方可以定义变量:
-
在函数或一个代码块内部声明的变量,称为局部变量。(只能在该函数内去使用这个变量)
-
在函数参数的定义中声明的变量,称为形式参数。
-
在所有函数外部声明的变量,称为全局变量。(作用域是整个源程序,都可以使用)
全局变量有默认的初始化值,局部变量必须初始化后才能使用。
5. 变量的生命周期
生命周期就是这个变量可以被引用的时间段。不同生命周期的变量,在程序内存中的分布位置是不一样的。一个程序的内存分为代码区、全局数据区、堆区、栈区。不同的内存区域,对应不同的生命周期。
- 代码区:存放程序的代码,即程序中的各个函数代码块。
- 全局数据区:存放程序的全局数据和静态数据。
- 堆区:存放程序的动态数据。
- 栈区:存放程序的局部数据,即各个函数中的数据。
6. 四种常用变量的作用域、生命周期、内存分布
- 局部变量
作用域:局部作用域(只在局部作用域中可见)
生命周期:程序运行出局部作用域即被销毁
内存分布:栈区 - 全局变量
作用域:全局作用域(全局变量只需在一个源文件中定义,就可以作用于所有的源文件。)
生命周期:程序运行期一直存在
引用方法:其他文件中要使用必须用extern 关键字声明要引用的全局变量。
内存分布:全局数据区
注意:如果在两个文件中都定义了相同名字的全局变量,连接出错:变量重定义
例子:
//defime.cpp
int g_iValue = 1;
//main.cpp
extern int g_iValue;
int main()
{
cout << g_iValue;
return 0;
}
- 静态全局变量
作用域:文件作用域(只在被定义的文件中可见。)
生命周期:程序运行期一直存在
内存分布:全局数据区
定义方法:static关键字,const 关键字
注意:只要文件不互相包含,在两个不同的文件中是可以定义完全相同的两个静态变量的,它们是两个完全不同的变量
例子:
const int iValue_1;
static const int iValue_2;
static int iValue_3;
int main()
{
return 0;
}
- 静态局部变量
作用域:局部作用域(只在局部作用域中可见)
生命周期:程序运行期一直存在
内存分布:全局数据区
定义方法:局部作用域用中用static定义
注意:只被初始化一次,多线程中需加锁保护,因此,使用 static 修饰局部变量可以在函数调用之间保持局部变量的值
例子:
static int count = 10; /* 全局变量 */
int main()
{
while(count--)
{
func();
}
return 0;
}
// 函数定义
void func( void )
{
static int i = 5; // 局部静态变量,只初始化1次
i++;
std::cout << "变量 i 为 " << i ;
std::cout << " , 变量 count 为 " << count << std::endl;
}
//输出:
变量 i 为 6 , 变量 count 为 9
变量 i 为 7 , 变量 count 为 8
变量 i 为 8 , 变量 count 为 7
变量 i 为 9 , 变量 count 为 6
变量 i 为 10 , 变量 count 为 5
变量 i 为 11 , 变量 count 为 4
变量 i 为 12 , 变量 count 为 3
变量 i 为 13 , 变量 count 为 2
变量 i 为 14 , 变量 count 为 1
变量 i 为 15 , 变量 count 为 0
7. 常量
整数常量:整数常量可以是十进制、八进制或十六进制的常量。前缀指定基数:0x 或 0X 表示十六进制,0 表示八进制,不带前缀则默认表示十进制。整数常量也可以带一个后缀,后缀是 U 和 L 的组合,U 表示无符号整数(unsigned),L 表示长整数(long)。后缀可以是大写,也可以是小写,U 和 L 的顺序任意。
字符串常量:字符串字面值或常量是括在双引号 “” 中的。一个字符串包含类似于字符常量的字符:普通的字符、转义序列和通用的字符。
- #define 预处理器
#define LENGTH 10
- const 关键字
const int LENGTH = 10;
二者的区别:
- 就定义常量说的话, const 定义的常数是变量也带类型, #define 定义的只是个常数不带类型。
- 就起作用的阶段而言,#define 是在编译的预处理阶段起作用,而 const 是在 编译、运行的时候起作用。
- 就起作用的方式而言,#define 只是简单的字符串替换,没有类型检查。而 const 有对应的数据类型,是要进行判断的,可以避免一些低级的错误(define只是替换,会使程序员忽略一些优先级的问题)
- 就空间占用而言,define预处理后占用代码段的空间,const会去为变量分配空间
- 就调试而言,define不能调试(预编译的时候会替换掉),const可以
- 从是否可以再定义的角度而言, const 不足的地方,是与生俱来的,const 不能重定义,而 #define 可以通过 #undef 取消某个符号的定义,再重新定义。
#define HEIGHT 10
//HEIGHT的作用域
//...
#undef HEIGHT
8. volatile变量修饰
volatile底层是通过一些内存屏障指令实现,如:loadload、loadstore…。它的作用主要是两个:
- 保证变量的可见性。多线程环境下,每个工作线程都有自己的寄存器变量,共享变量一旦更改,需要让其他线程立即知道。使用volatile修饰的变量要求,变量修改时必须把最新值刷回主存,变量读取时也必须从主存去读取。
- 防止指令重排序。编译器会为了代码执行效率去进行优化。
一般说来,volatile用在如下的几个地方:
-
- 中断服务程序中修改的供其它程序检测的变量需要加 volatile;
-
- 多任务环境下各任务间共享的标志应该加 volatile;
-
- 存储器映射的硬件寄存器通常也要加 volatile 说明,因为每次对它的读写都可能由不同意义;