C++之指针、引用、数组、堆区栈区

此生再无相见时 提交于 2020-03-07 12:41:28

指针
指针(pointer)是一个值为内存地址的变量(或数据对象)
基本用法
数据类型 * 指针变量名 如 int * ptr_num
注意:
Int* p 写法偏向地址 P是一个地址变量 表示一个十六进制地址
Int *p偏向值 *p是一个整型变量 能够表示一个整型值
给指针赋值只能使用&符号

空指针(null pointer)空指针不指向任何对象,在试图使用一个指针之前首先检查是否为空
Int *ptr1 = nullptr; 如果用null需要包含cstdlib

Void指针
一种特殊的指针类型 可以存放任意对象的地址
注意:
void
指针存放一个内存地址,地址指向的内容是什么类1、型不能确定
2、Void类型指针一般用来:拿来和别的指针比较,作为函数的输入和输出;赋值给另一个void指针

指针小结:
指针同样是一个变量,只不过该变量中存储的是另一个对象的内存地址
如果一个变量存储另一个对象 的地址,则称该变量指向这个对象
指针变量可以赋值 指针的指向在程序执行中可以改变
指针P在执行中某时刻指向变量x在另一时刻可以指向y

注意: 指针命名规则和其他变量命名规则一样
指针不能与现有变量重名
应为指针指定一个地址后才能在语句中使用指针

引用 为对象起了另外一个名字(引用即别名)
Int int_value = 1024;
//refValue指向int_value,是int_value另一个名字
Int& reValue = int_value;
//错误,引用必须被初始化
Int& refValue2;
注意: 1、引用并非对象,只是为一个已经存在的对象起的别名
3、引用只能绑定在对象上,不能与字面值或某个表达式的计算结果绑定在一起
Int &ref_value = 10;//错误
4、引用必须初始化,所以使用引用之前不需要测试其有效性,因此使用引用可能会比指针效率高。
Double &ref = 100; 错误的(指向变量的引用) const Double &ref = 100;指向常量的引用是正确的

指针和引用的关系
引用对指针进行了简单封装,底层仍是指针
获取引用地址时,编译器会进行内部转换

指针与数组
数组:
存储在一块连续的内存空间中
数组名就是这块连续空间的首地址

指针的算术运算
指针的递增和递减(++、–)

数组与指针小结
数组名就是这块连续内存单元的首地址
Int num[50];//num是数组名,也可以理解成数组的收地址
Num的值与&num[0]的值是相同的
数组第i+1个元素可表示为:
第i+1个元素的地址 : &num[i+1]或者 num+i+1
第i+1个元素的值: num[i+1] 或*(num+i+1)同样尝试*++ptr_num
为指向数组的指针赋值:
Int *ptr_num = num;或int *ptr_num = &num[0];
指针变量可以指向数组元素
Int ptr_num = &num[4];或者intptr_num = num+4
动态分配内存
使用new分配内存
指针真正的用武之地:在运行阶段分配未命名的内存以存储值
在此情况下,只能通过指针来访问内存

//1、在运行阶段为一个int值分配未命名的内存
//2、使用指针来访问(指向)这个值(右->左)
int *ptr_int = new int;
Delete ptr_int;//释放由new分配的内存
使用delete释放内存
与new配对使用
不要释放已经释放的内存
不能释放声明变量分配的内存
Int *p =new int;//p在栈区 是一个整型指针变量 new int在堆区分配了int型空间
注意:不要创建两个指向同一内存块的指针,又可能误删两次
Int *ptr = new int;
Int * ptr1 = ptr;
delete ptr; delete ptr1;

动态分配的数组:
使用new创建动态分配的数组
Int *intArray = new int[10];
New运算符返回第一个元素的地址
使用delete[]释放内存
delete[] intArray;
[]释放整个数组
关于new和delete使用的规则:
1、不要使用delete释放不是new分配的内存
2、不要使用delete释放同意一内存两次
3、如果使用new[]为数组分配内存,则对应delete[]释放内存
4、对空指针使用delete是安全的
补充:程序的内存分配
栈区(stack)
由编译器自动分配释放 一般存放函数的参数值 局部变量的值等
操作方式类似数据结构的栈-先进后出
堆区(heap)
一般由程序员分配释放,若程序不释放,程序结束时可能由操作系统回收
注意:与数据结构中的堆是两回事,分配方式类似链表
全局区(静态区-stack)
全局变量和静态变量是存储在一起的
程序结束后由系统释放
文字常量区
常量字符串就放在这里,程序结束后由系统释放 双引号
程序代码区
存放函数的二进制代码

实例:
Int num = 0;//全局初始化区
Int *ptr1;//全局未初始化区
Int main()
{
//栈区
Int num2;
//栈区
Char str[] = “老酒军”;
//栈区
Char *ptr2;
//老酒军以及\0在常量区,ptr3在栈区
Char *ptr3 = “老酒军”;
//全局静态初始化区
Static int num3 = 1024;
//分配的内存在堆区
Ptr1 = new int[10];
Ptr2 = new char[20];
Return 0;
}

总结:
指针是一个变量,(值为内存地址)存储另一个变量(对象)的内存地址
指针的声明由基本类型、星号()和变量名组成
为指针赋值,赋值运算符右侧必须是一个地址
如果是普通变量需要在前面加一个取地址运算符
如果是另一个指针变量或者是一个数组,不需要加&运算符
运算符
用于返回指针指向的内存地址中存储的值
使用指针访问一维数组和二维数组的元素

*间接运算符 &取地址
指针支持运算 实际上是变量存储地址的移动
数组是有类型的 如int[]

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!