常见字符
*
- 注释:/* 这是一个注释*/
- 乘法:a * b
- 取值运算符:*指针变量,int a = 4,*a ????
- 指针变量:数据类型 *变量名, int *no = &bh,代表了no是一个指针
- 数据类型:int*:整型指针类型、char* 字符指针类型,char* c=(char *) &b。int no=38,int* ptr=&no, &no和ptr是一个东西,no和*ptr是一个东西。
- 间接值/解除引用/解引用运算符:
注:int *no 和 int* no什么区别
1. 实际上没有区别
2. int* a, b; 这里 a 是指向 int 的指针,而 b 只是一个普通的 int 整数变量。
3. int *a, *b; 这样的声明清晰地表明 a 和 b 都是指向 int 的指针。
::
- 变量属于哪个域:std::count<<"no"
- 当局部变量和全局变量名称相同时,会屏蔽全局变量使用局部变量,如果想使用全局变量,使用::,:: a。
常见关键词
typedef
数据类型的别名
static(静态)
静态局部变量
- 主要作用:会影响变量的存储期和作用域。
- 只会被初始化一次
- 静态局部变量:static修饰的局部变量生命周期和程序相同。即在函数调用结束后不会被销毁,而是保持其值直到下次调用。
- 静态类成员:用 static 声明的类成员属于整个类,而不是类的各个实例。
const(常量)
- 主要作用:增强程序的安全性
- 初始化之后,值不能被修改
- 当 const 修饰类的成员函数时,表示该函数不会修改类的任何成员变量
指针
- 常量指针:const 数据类型 *变量名;不能通过解引用的方法修改内存地址中的值(用原始的变量名是可以修改的)。
-
Int a=3,b=4;
const int* p=&a; #报错
*p = 13; p=&b; #不报错
-
- 指针常量
- 数据类型 * const 变量名;
- 指向的变量(对象)不可改变。
- 在定义的同时必须初始化,否则没有意义。
- 可以通过解引用的方法修改内存地址中的值。
-
Int a=3,b=4;
const int* p=&a; #不报错
*p = 13; p=&b; #报错
-
新名字:引用
-
常指针常量
-
const 数据类型 * const 变量名;
-
指向的变量(对象)不可改变,不能通过解引用的方法修改内存地址中的值。
-
新名字:常引用。
-
常量指针:指针指向可以改,指针指向的值不可以更改。
指针常量:指针指向不可以改,指针指向的值可以更改。
常指针常量:指针指向不可以改,指针指向的值不可以更改。
记忆秘诀:*表示指针,指针在前先读指针;指针在前指针就不允许改变。
常量指针:const 数据类型 *变量名
指针常量:数据类型 * const 变量名
-
void
- 函数的返回值用void,表示函数没有返回值。
- 函数的参数填void,表示函数不需要参数(或者让参数列表空着)。
- 函数的形参用void *,表示接受任意数据类型的指针。
- 注意:
- 不能用void声明变量,它不能代表一个真实的变量,但是,用void *可以。
- 不能对void *指针直接解引用(需要转换成其它类型的指针)。
- 把其它类型的指针赋值给void*指针不需要转换。
- 把void *指针赋值给把其它类型的指针需要转换。
内存
内存分为内核空间和用户空间,内核空间由操作系统管理,与程序员没什么关系。我们写的程序运行在用户空间。一个c++源程序编译成可执行程序后,二进制文件的大小是固定的,最多几十兆。
程序运行时,内存主要分成四个区,分别是栈、堆、数据段和代码段。
栈:存储局部变量、函数参数和返回值。不管计算机的内存是8G还是16G,分配给栈的只有几兆。修改系统参数可以调整栈的大小。
堆:存储动态开辟内存的变量。内存越大,分配的内存就越大。
n数据段:存储全局变量和静态变量。
代码段:存储可执行程序的代码和常量(例如字符常量),此存储区不可修改。
栈和堆的主要区别:
1)管理方式不同:栈是系统自动管理的,在出作用域时,将自动被释放;堆需手动释放,若程序中不释放,程序结束时由操作系统回收。
2)空间大小不同:堆内存的大小受限于物理内存空间;而栈就小得可怜,一般只有8M(可以修改系统参数)。
3)分配方式不同:堆是动态分配;栈有静态分配和动态分配(都是自动释放)。
4)分配效率不同:栈是系统提供的数据结构,计算机在底层提供了对栈的支持,进栈和出栈有专门的指令,效率比较高;堆是由C++函数库提供的。
栈的效率非常高,堆是用链表来管理的,效率会低一点。
5)是否产生碎片:对于栈来说,进栈和出栈都有着严格的顺序(先进后出),不会产生碎片;而堆频繁的分配和释放,会造成内存空间的不连续,容易产生碎片,太多的碎片会导致性能的下降。
6)增长方向不同:栈向下增长,以降序分配内存地址;堆向上增长,以升序分配内存地址。
动态分配内存new
申请内存的语法:new 数据类型(初始值); // C++11支持{}
如果动态分配的内存不用了,必须用delete释放它,否则有可能用尽系统的内存。
for (int ii = 1; ii > 0; ii++){int* p = new int[100000]; // 一次申请100000个整数。cout << "ii="<<ii<<",p=" << p << endl;}
内存会螺旋式越来越大,(一会大一会小,是因为系统有交换区)
静态分配内存
空指针
- 用0或NULL都可以表示空指针。int* p=0,表示还没有指向任何地址。
- 如果对空指针使用delete运算符,系统将忽略该操作,不会出现异常。
-
用0和NULL表示空指针会产生歧义,C++11建议用nullptr表示空指针,也就是(void *)0。