在学习指针前,先了解一下这些概念:指针就是地址 (是内存单元的编号)。指针变量的定义:基类型 * 指针变量名;基类型:决定了 存放的地址编号 对应的内存空间中 数据的类型;* :表明,此时定义是指针这种数据类型的变量;指针变量名:即标识符。野指针:指针变量指向 随机(不明确),想使野指针不野:int *p = NULL;指针核心用途:在被调函数修改到主调函数中数据
eg.int a = 10;int * p;p是一个变量 ---意味着p对应的有一块空间,是一个指针类型的变量 --- 意味着p对应空间要存放的 是"地址"这种数据,p的基类型是int型 --- p对应空间要存放的 是 存放着int类型数据的内存空间的地址;int *p = &a;a是一个int型的变量,a对应的有自己的一块空间,这块空间存放的是 int型的数据,即p指向了a。
指针可以进行的运算:&,*,关系运算,p+N,p-N(N是整型常量),p++,p--,p-q(算p到q相距多少)
------------------------------------------------
指针操作数组:
一 整型一维数组 :
(1)具体操作:printf("a[i] = %d\n",a[i]); :a[i]数组下标运算,本质上是个指针运算,具体过程如下:
int *p = &a[0],a[i] <=> *(p+i)<=> *(a+i),a[i] <=> *(a+i),i[a] <=> *(i+a)
(2)快速排序:
step1: 找基准值 :第一个元素充当基准值(交换的是基准值位置上的值)
step2: 从右向左 找第一个比基准值小的值
step3: 从左向右 找第一个比基准值大的值
step4: 将找到的值 交换
step5: 重复 2~4 ,begin与end相遇
step6: 将相遇位置上的值 与 基准值交换
step7: 对小的部分 继续快速排序,对大的部分 继续快速排序
二 字符型一维数组:字符型一维数组操作方式较为简单,在此不过多赘述,只讨论一些关于const的问题。
为什么要使用:const char *,目的是防止误操作,可以提前发现问题,如,const int a = 10; (只读变量), const char *s,原则: const 离谁近 就限定谁 (就近) <=> char const *s
eg.char * const p;即p的指向不能被修改;char const *const s;即p的指向和p本身都不能被修改
三 指针访问二维数组
step1.指针访问二维数组元素
int a[3][4] = {1,2,3,4,5,6,7};
int (*p)[4] = a;p的类型 = 数组指针类型
step2.通过指针访问到二维数组元素
*(*(p+i)+j)
*( a[i] +j)
a[i][j]
step3.二维数组指针的理解
a ------------ &a[0]
&a[0][0]------ a[0]
a + 1 --------- 行
a[0] + 1------ 列
*(a+1)-------- a[1]
四 指针数组:是个数组,数组中存放的是指针(地址)
char *s[] = {"hello1","hello2","hello3","hello4","hello5"};
char s[][10] = {"hello1","hello2","hello3","hello4","hello5"};
五 函数指针:int (* p) (int a,int b)
1.回调函数(callback):通过函数指针的方式进行函数调用,pfn是指向回调函数的指针,根据不同的打印需要写不同的函数,在主函数中调用打印函数时传所需要的回调函数指针即可。
2.qsort:void qsort(void *base, size_t nmemb,size_t size,int (*compar)(const void *, const void *):
功能:对数组排序
参数:@base 获得数组的起始地址
@nmemb 说明 待排序数组元素个数
@size 说明 单个元素的大小
@compar 说明 元素间大小关系的判断依据
int compare(const void * a, const void *b)
{
}
参数:const void * a,const void * b,用来获得 比较的数组中两元素的地址
六 二级指针:可以理解为指针的指针,在此贴一段代码可以思考一下,传参时传s与&s有什么区别,哪一种会报错(段错误),为什么会报错。
七 动态内存分配(申请)
1.void * malloc(size_t size)
功能:从堆区申请一块内存
参数:size表示要申请的字节个数
返回值:成功 返回申请到的堆区内存的首地址,失败 NULL
内存泄露是指申请内存用完了,但是没有释放
2.void free(void *ptr)
功能:释放之前堆上申请到的空间
参数:ptr 之前申请到的堆上空间的地址
3.void *calloc(size_t nmemb, size_t size);
功能:从堆区申请一块内存
参数:@nmemb 元素个数
@size 单个元素的大小
返回值:成功 返回申请到的堆区内存的首地址,失败NULL
4.void *realloc(void *ptr, size_t size):如果要改变的内存后还有空余,在原来内存地址加空间,如果没有空余,直接找另一块内存并把原来内存上的数据拷贝到新的内存中
功能:改变ptr指向空间的大小
参数:ptr指要改变的内存的地址,size指要改变为多少字节
5.注意:同一块空间不能多次释放;free只是告诉操作系统,这块空间不再使用,系统可以回收自由使用,但是free并不清0 释放的空间