C++ 指针笔记

​​​​创建指针变量的规范:
int *p = nullptr; //如果不进行初始化,p就会指向未知内存,变成“野指针”
p = new int[n];
delete [] p;
p = nullptr; //被delete后不重新进行初始化,p也会变成“野指针”
(函数中 new 的指针在函数结束时不会自动 delete,所以依然要手动释放)
局部变量在栈中分配,而堆允许程序在运行时(而不是编译时)申请某个大小的空间
malloc()|new 在堆中寻找未被使用的内存,找够所需的字节数后返回该内存的起始地址
free()|delete 返还由 malloc()|new 动态申请的堆内存空间
new 以后在 delete 之前不要重新 new 或者改变指针的值==>导致原来申请的空间无法访问;
如果系统能提供的堆空间不够分配会返回一个空值 NULL
所以需要加上 if(p) 进行判断来避免分配失败的情况
delete 以后要让 "p=nullptr;" —— delete 后 p 为未初始化的状态,此时 p 指向一个随机的内存空间

Sum(int *array[]|*array, int n) —— array所占空间是指针变量的大小而不是数组大小
所以不能用 sizeof(array)/sizeof(*array),所以第二参数 n[数组元素个数] 必须要给

连续定义三个指针:
int *q,*p,*t;
定义一个指针和两个整型:
int* p,q,t;

指向常量的指针:
const char* p;
常量指针:
char * const p;
指向常量的指针常量:
const char* const p;

行指针:
int (*p)[n], a[m][n];
p=a;
p++; //p++指向数组的下一行跳过了n个元素

指针数组(多用于处理字符串,比如将多个字符串排序):
int *p[n]; //其中每一个元素都是一个指针,用来存放变量的地址
void sort(char *color[], int n){ //选择排序(升序)
    char *ptr;
    int i,j,k;
    for(i=0;i<n-1;i++){
        k=i;
        for(j=i+1;j<n;j++){
            if( strcmp(color[k],color[j]) > 0)
                k=j; //字符串比较,记下最小字符串指针的下标
        }
        if(k!=i){ //地址交换,交换指针的指向
            ptr=color[i];
            color[i]=color[k];
            color[k]=ptr;
        }
    }
}
char *color[]={"Red","Orange","Yello","Green","Blue"};
sort(color,5);

指向指针的指针:
int **p //p存储它指向的指针的地址,*p就是它指向的指针

函数指针(指向函数的指针,存放函数的入口地址):
void (*fp)(); ——函数指针指向code区,而数据指针指向data、stack和heap区
经常定义同一种函数指针可以用typedef简化:
typedef int(*FUN)(int a, int b); /*声明FUN是一个函数指针类型*/
FUN funp|funp[]; /*创建*/
FUN func(FUN); //参数为函数指针且返回函数指针的函数
/*返回指针的函数:int *func() {} —— 返回一个int类型的指针*/

NULL指针:
int *p = nullptr; //nullptr只作为空指针常量
c++不允许直接将void*隐式的转化为其他类型,所以NULL不能被定义为((void*)0)
0和NULL既是整数常量又是空指针常量,为了解决函数重载的二义性,引入nullptr

数组名对应一块内存,是指针常量,其地址与容量生命周期内不变,只有数组内容可变
void*是不确定类型的指针(不能算数操作)/任何类型的指针都可直接赋给它无需类型转换

函数的指针形参是局部变量,不能修改函数外的原指针的值,但可间接修改指针指向的值
通过被调函数修改实参:
1.定义形参为引用类型
2.定义形参为指针类型进行间接存取

函数的形参指针是实参指针的副本,因为他们的值相同(即指向同一块内存空间),所以--
--通过提领形参值(存放的地址)修改其所指空间的内容会导致实参所指的内容一起改变--
--但如果给形参指针申请新的内存空间,是把一片连续地址首地址的值赋给了形参指针--
--只是单独改变形参的值(即它指向的地址)而实参的值(所指地址)和里面的内容并未改变.
解决方案——使用指向指针的指针作为参数申请内存(虽然也是副本但形参提领后的空间跟实参为同一块):
void GetMemory(char **p, int num){
    *p = (char*)malloc(sizeof(char) * num);
}
char *str = nullptr;
GetMemory(&str, 100);

———————————————————————————————————————————————————————————————————————

动态|静态的指针:该指针指向——堆内存(heap)|固定的内存块(分配和释放由系统管理)
1.  char* p1 = new char[10];
2.  char* p2 = "abcde";
3.  if(p1) { strcpy(p1,p2); }
4.  p2 = p1;
5.  delete p2;
6.  p2 = NULL;
7.  p1 = NULL; 
p1所指的是堆内存可以动态生成; p2在语句4前所指的是固定内存块不可控制由系统管理
执行 语句4 之后 —— p2 也指向了堆内存(heap)
执行 语
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值