小沈的C++学习7——指针
这节课终于学到指针了,话说感觉我是不是在前面几篇博客已经用过不少次这玩意了。但是指针到底是个什么东西呢?今天就让我们来学习指针这个东西。
首先我们小学一年级就学过,电脑里面有内存这个东西,就是利用电位高低存储各种数据,然后可以让cpu各种调用的小容器,而各种数据就听从程序的指挥,在一个个小格子里落户,这个格子就是内存地址。这个时候如果一个函数内部运行的时候在内存上留下了一串数据,它想把这一串数据都交给主函数,那它就可以直接把某个小格子的位置告诉主程序,主程序就可以利用这个位置信息直接到内存里去找这个函数留下来的数据。而这个位置信息就是指针。
首先我们要知道,指针本身也是一种数据,意思就是我们拿到一个指针,到指针指的位置上拿到一个数据,可能也是一个指针。
有了指针,我们甚至可以自己创造一个数据类型。比如我们所有函数都遵循这样一个约定:返回一个指针,指针指向一个指针数组,指针数组的一个指针指向一个数字,代表这个数据的长度或者内存长度,第二个指针指向另一个数字数组,代表这个数据里面每个数据的数据类型,第三个及之后的指针则指向各个数据。这个数据类型是不是很熟悉?没错,只要我们愿意,我们也可以手作一个列表。并且由于指针可以指向指针,这个列表可以不断嵌套(禁止禁止套娃)。
一、指针定义和运算
首先既然我们有了地址,那我们也要知道地址的数据有多长,是个什么类型的数据,所以对应的指针也会有相应的类型,比如int对应的指针类型就是int*,double对应的指针类型就是double*
*是取内容运算符,&是取地址运算符
*+指针名 ——>获取指针指向的值
&+变量名——>获取变量的地址
&+指针名就是存储指针的地址
**不允许把一个数的赋予指针变量,但是指针变量可以做加减运算
如int*p;p++;就代表将指针指向的位置向前移动一个地址
int*p,q;int a=q-p;就表示p与q地址之间的距离
比如我们有一个数组,就可以把数组第一个数的指针作为函数的返回值,然后之后的函数就可以调用这个指针和之后的数据。
二、指针的运算
1.指针变量初始化赋值,*p=b;
2.把一个变量的地址赋予指向相同数据类型的指针变量。例如:
int a,*pa;
pa=&a;
3.把一个指针变量的值赋予指向相同类型变量的另一个指针变量
int a,*pa=&a,*pb;
pb=pa;
结果:pb也指向a的地址
4.把数组的首地址赋予指向数组的指针变量
int a[5],*pa;
pa=a;
数组的数组名可以直接当指针使用(p.s.仅限一维数组,如果二位数组还是老老实实用p=&a[0][0]吧)
p.s. pa[i]=*(pa+i)=**(a+i)
a=*a=pa=&a[0]
a和*a都是数组的首地址
5.把字符串的首地址赋予指向字符类型的指针变量
char *pc;pc = "c language";
6.把函数的入口地址赋予指向函数的指针变量。
例如
int (*pf)();
pf=f;//f为函数名
这个指针就非常有用了,我们可以将函数的入口作为指针变量输入一个函数,map函数的实现就是靠它的。
三、堆内存分配
有的时候我们不知道程序要处理的数组的大小是多少,定义了一个数组,定义多了浪费,定义少了不够用,很是让人头痛。对于这类问题,C++提供了内存需求随运行进展时大时小的解决方案,即堆内存——动态内存的申请和释放办法。
申请: malloc(); new;
释放: free(); delete;
#include内存分配#include using namespace std; int main() { /*malloc free*/ int arraysize,*array; array=(int *)malloc(arraysize); for(int i=0;i<10;i++){ array[i]=i*2; } cout< endl; for(int i=0;i<11;i++){ cout< endl; } free(array); /*new delete*/ array=new int[arraysize]; for(int i=0;i<10;i++){ array[i]=i*3; } for(int i=0;i<11;i++){ cout< endl; } delete array; }
程序会在内存的堆区开辟一块内存用来存储数据,数据存储完后可以把数据复制给一个变量或者直接释放这一片内存(即标记为“空闲”)
底层开发的时候要经常考虑如何处理内存的分配来优化程序
四、const指针
const主要有三类:指向常量的指针(常量指针)、指针常量、常量指针常量
您搁这排列组合呢?
别急,我们一个一个聊
1.常量指针 :这个很简单,就是告诉编译器,指针指向的是常量,不能变换指针的内容
理解:指针可变,数据不可变
形式:const int*p;
2.指针常量:指针本身就是常量
理解:指针不可变,数据可变
形式:int const *p;
3.常量指针常量:指针和数据都不可变
形式:const int *const p;
好像还真是排列组合
五、指针与函数
函数虽然不是变量(我记得这个人之前说过函数即变量来着← ←,是谁啊——还不是为了方便理解)但是它在内存中占有实际位置。函数的首地址就是该函数的入口地址,它可以赋给指针变量。
指针函数:float *func() 表示函数的返回值是一个指针
函数指针:float (*f)(intx) 这个指针指向的是一个函数
我们的又可以进化了:
#include宇宙超级无敌霹雳旋风终极无敌版V2.0using namespace std; int max(int a,int b){ if(a>b){ return a; } return b; } int min(int a,int b){ if(a<b){ return a; } return b; }//比较 int *findst(int *p,int h,int l,int (*func)(int,int)){ int res=*p; int num=0; for(int i=1;i ){ int bak = func(res,p[i]); if(res!=bak){ res = bak; num=i; } } cout< endl; int res_y_x[3]={res,num/l+1,num%l+1}; int *myx=&res_y_x[0]; return myx; }//“打擂台” int main(){ /*矩阵实战*/ int d[3][4]={{1,2,3,4},{4,5,6,7},{7,8,9,10}}; int *p=&d[0][0]; int *q=findst(p,3,4,max); cout<<"最大的数是"<<*q<<"\n它在第"<<*(q+1)<<"行第"<<*(q+2)<<"个"<<endl; q=findst(p,3,4,min); cout<<"最小的数是"<<*q<<"\n它在第"<<*(q+1)<<"行第"<<*(q+2)<<"个"; }