指针
指针:特定类型数据在内存中的储存地址,即内存地址
指针变量:记录地址的变量
int main(int argc, char *argv[]) {
int num = 10;
//here * means declare a pointer
int * p; //declare p is a pointer variable
//here int because the pointer point to a int
p = # //assign address of num to pointer p
cout << p <<endl; //0x860ebffdb4 output the address
cout <<*p; //10 here * means take the value of the pointer address
}
野指针和空指针
野指针:被声明但未初始化(赋值)的指针。这个指针会指向随机的内存空间,可能导致位置问题。
如
int * p; //声明指针(8字节空间)(此时其实已经随机分配了地址了)
*p = 10; //这边是向未知的,随机的4字节内存区域,修改存储值为10
为避免野指针,将指针置为空指针更为安全。
int * p = NULL; //空指针 指向内存中编号为0的空间 用于初始话指针变量
int * p = nullptr;
两种方法都可以
NULL是c++内置的宏,nullptr是C++11标准引入的关键字
指针运算
int num = 10;
//* means declare a pointer
int * p; //declare pointer variable
p = # //assign address of num to pointer p
cout<< p <<endl; //0xcd415ff924
p++;
cout<< p <<endl; //0xcd415ff928
int 类型指针+1,地址+4(字节)
指针+n或-n,内存地址 +n * 类型大小 或 -n * 类型大小
int v[] = {1,2,3};
int *vp = v; // v is address of v[0]
cout<< *vp<<endl; //1
cout<<*(++vp)<<endl; //2
cout<<*++vp<<endl; //3
cout<<*(vp++)<<endl; //3
cout<<*vp++<<endl; //10 because point to the address out of the array
动态内存分配
C++变量,数组创建是自动分配内存的,称之为静态内存分配
这种分配方式不会进行内存空间的自动清理。(无垃圾回收机制)
需要手动的管理内存,即手动分配,用完清理。
new
用于申请并分配内存空间并提供指向该空间的指针
delete
用于释放内存,仅可用于new运算符申请的内存区域
int *kk =new int;
*kk = 10;
cout << *kk <<endl;
delete kk;
int *ll = new int[5];
ll[0] = 1; //指针也可用下标,等同于*(p+0)
*p = 1;
p[1] = 2; //等价于*(p+1)
cout<< p[0] <<endl;
cout<<*(p+1)<<endl;
delete[] p; //delete[] pointer 删除数组空间
删除数组元素
int * p = new int[5]{1,3,5,7,9} ;
int * pnew = new int[4];
//删除数组元素,就是遍历老的数组将数组元素拷贝到新的数组中,跳过不要的元素
for(int i=0;i<5;i++) {
if(i == 2) {
continue;
}
if (i>2) {
pnew[i-1] = p[i];
}
pnew[i] = p[i];
}
delete[] p; //可选
for(int i=0;i<4;i++) {
cout<< pnew[i] <<endl;
}
数组元素的插入
int * p = new int[5]{1,3,5,7,9} ;
int * pnew = new int[7];
//在数组中插入元素就是将老数组元素和新数组元素一起复制到新数组中
int offset = 0;
for(int i=0;i<7;i++) {
if( i==1) {
pnew[i] = 100;
offset++;
continue;
}if (i==3) {
pnew[i] = 200;
offset++;
continue;
}
pnew[i] = p[i-offset];
}
delete[] p;
for (int i=0;i<7;i++) {
cout<<pnew[i]<<endl;
}
指针悬挂
指针指向区域已经被回收(delete),这种问题称之为:指针悬挂
删除p1后会导致p2指针不能正常使用,因为区域已经被回收。
两点经验:
1.不要轻易进行指针间的赋值 2.delete前确保此空间不再被使用
const指针(常量指针)
三类:指向const的指针,const指针,指向const的const指针
指向const的指针
表示指向区域的数据,是不变的,但可以更换指向
int num = 10,num2 = 100;
//指向const的指针 指向的数据变不了,指向可变
const int * p = #
p = &num2;
const指针
表示指针本身不可更改,但指向的数据可以更改
//const指针,指向不可变,数据可变
int * const p2 = #
*p2 = 100;
指向const的const指针
指针和指向的区域的值,都不可改变
//指向const的const指针 都不可变
const int * const p3 = &num2;