一、指针
1、指针变量所占空间
在32位环境中,占4字节
在64位环境中,占8字节
2、解除引用
“*运算符”称为间接值运算符或称为解除引用运算符,讲其应用于指针变量,可以得到该地址处存储的值。
例如:ptr是一个指针变量,则ptr存储的是一个地址,而*ptr表示存储在该地址处的值,*ptr与常规变量等效。
3、野指针与空指针
任意数值复制给指针变量没有意义,这样的指针变量就是野指针,野指针指向的区域是未知的。
在C++中,值为0的指针变量被称为空指针(null pointer)。空指针不会指向有效的数据。
PS:空指针也是有用的哦,不要瞧不起空指针
4、指针变量的宽度和跨度
自身类型和指向类型(见名知意)
指针变量的自身类型:
去掉变量名,剩余的部分就是指针变量的自身类型
int * ptr; 指针变量ptr的自身类型是int *
int ** ptr; 指针变量ptr的自身类型是int **
指针类型的指向类型:
去掉变量名及离它最近的一个*,剩余的部分就是指针变量指向的类型
int * ptr; 指针变量ptr指向类型是int
int ** ptr; 指针变量ptr指向类型是int *
指针变量所取内容的宽度(该宽度是一个整体“1”)
指针变量所取内容的宽度是由指针变量所指向的类型长度决定的。
指针变量+“1”的跨度
指针变量+“1”的跨度是由指针变量所指向的类型的大小决定。
short * p1 = NULL;
p1 + 1 // 此处+“1”,实际上是加了两个字节
5、void类型指针(无类型指针):
void* 指针变量可以指向任意变量的内存空间,任何类型指针变量都可以转为void *
6、const和指针
const修饰指针变量
(1)如果const位于 * 左侧,表示指针变量所指向的数据是常量(常量指针),
不能通过解引用修改该数据,指针变量可以指向其他的内存单元。
eg:const int* a;
(2)如果const位于 * 右侧,表示指针变量本身是常量(常指针),不能指向其他内存地址,指针变量所指的数据可以修改。
eg:int* const a;
(3)如果const位于 * 左右各一个,表示指向常量的指针常量。也就是指针变量和指针变量所指向的数据都不能修改。
eg:const int* const a;
7、指针和字符串
cout在输出字符指针的时候,会一直向后输出,知道遇到' \0 '
8、字符串指针和字符串(字符数组)的区别
字符串指针变量指向的字符串是常量,不可以对字符串进行修改。
const char* str1 = " hello world!";
char str2[] = " hello world!";
二、C++内存管理
1、new和delete运算符
使用new分配内存
C++中可以使用new运算符在运行阶段分配内存。(有的是在编译阶段就定义好了怎么分配内存。。。eg:常规数组的定义)
动态分配内存的格式:
typeName * pointer_name = new typeName;// typeName:就是你的类型名称
int* pn = new int;
new 运算符返回该内存的地址
数据对象:指的是为数据项分配的内存块。
动态分配内存使程序在管理内存方面有更大的控制权
new分配的内存块与常规变量声明分配的内存块不同。变量的值都存储在
栈内存(stack)区域中;而new运算符从堆(heap)或自由存储区(free store)
的内存区域分配内存
使用delete是否内存
delete运算符可以在使用完内存后,将内存归还给内存池。归还或释放的内存可供 程序的其他部分使用
使用delete时,后面要加上指向内存块的指针变量(内存块是由new分配);
int* ps = new int;
...
delete ps;
注意:
一定要配对使用new和delete,否则会发生内存泄漏(memory leak)
不要释放已经释放的内存块
不能使用delete来释放声明变量所获得的内存
2、创建动态数组
使用new创建动态数组
通常对于大型数据(如数组、字符串和结构),应使用new来分配
创建动态数组需要将数组的元素类型和元素个数数目告诉new
int* parr = new int[10]; new关键字动态开辟出一个空间,并返回空间首指针
注意:释放动态数组内存时:delete[] parr; // 记得加上[]
3、创建动态结构体
4、C++ 内存管理
c++的内存划分:
栈区:由编译器自动分配与释放,存放为程序运行时函数分配的局部变量、函数参数、返回数据、返回地址等。其操作类似于数据结构中的栈。
堆区:一般由程序员自动分配,如果程序员没有释放,程序结束时可能由os回收。
全局区(静态区):存放全局变量、静态数据。程序结束后由系统释放。
常量区(文字常量区):存放常量值,如字符串常量,不允许修改。程序结束后由系统释放。
代码区:存放函数体(类成员函数和全局区)的二进制代码。
c++管理数据内存的方式
c++根据用于分配内存的方法,有3种管理数据内存的方式:自动存储、静态存储和动态存储。
这三种方式分配的数据对象(内存空间)在存在时间的长短方面各不相同。
(1)自动存储:在函数内部定义的常规变量使用自动存储空间,被称为自动变量,他们在所属的函数被调用时自动产生,在该函数结束时消亡。自动变量通常存储在栈内存中。
(2)静态存储:静态存储是整个程序执行期间都存在的存储方式。使变量称为静态的方式有两种:一种是在函数外面定义它;另一种是在声明变量的时候使用关键字static;
static int num = 10;
(3)动态存储:new和delete运算符提供了一种比自动变量和静态变量更灵活的方法。
他们管理了一个内存池,这在c++中被称为自由存储空间或堆。该内存池同用于静态变量和自动变量的内存是分开的。
在栈中,自动添加和删除机制使得占用的内存总是连续的,但new和delete的相互影响可能导致占用的自由存储区不连续,这使得跟踪新分配内存的位置更困难。
5、普通局部变量和普通全局变量
普通局部变量也叫自动变量
(1)代码中的位置:在代码块{}内部定义的变量,就是局部变量。包括方法参数列表定义的变量
(2)存储位置:栈内存
(3)作用范围:离他最近的{}之间
(4)生命周期:当代码块执行的时候创建,当代码块执行完就销毁。
PS:局部变量,不初始化,不能使用。
同一个作用域中不能有同名变量。
不同的作用域中局部变量同名,采用就近原则
普通全局变量
(1)代码中的位置:文件中,函数外
(2)存储位置;全局区
(3)作用范围:当前源文件以及其他的源文件中
使用其他源文件中的变量,需要在前边声明
extern int num;
(4)声明周期:在整个程序运行过程。
PS:普通全局变量,不初始化,默认值为 0
普通全局变量和普通局部变量同名,采用就近原则。
6、静态局部变量和静态全局变量
静态局部变量:只需要在普通局部变量前加上static修饰
(1)代码中的位置:在代码块{}内部定义
(2)存储空间:全局区(注意跟普通局部变量的区别)
(3)作用域:离它最近的大括号间
(4)生命周期:整个程序进程(注意跟普通静态变量的区别)
PS:静态局部变量,不初始化,内容为0
不同的作用域中的静态局部变量同名,采用就近原则
静态局部变量如果被初始化语句执行多次,只有第一次有效
静态局部变量如果被初始化语句执行多次,只有第一次有效
// 静态局部变量如果被初始化语句执行多次,只有第一次有效
#inlude <iostream>
void fun(){
static int num = 10;
num++;
cout<< num << endl;
}
int main(){
fun();
fun();
fun();
fun();
return 0;
}
程序执行结果为
静态全局变量
(1)代码中的位置:文件中,函数外,使用static关键字
(2)存储空间:全局区
(3)只能在当前源文件有效(主要也是使用这个特点)
(4)生命周期:整个程序进程
6、类型别名