目录
一、指针函数
1、指针函数:返回值为指针的函数,绝不能返回局部变量的地址(全局变量、静态变量与传进去的指针地址均可返);
2、用法:
int *foo(int *p)
{
static int i = 100;
return p;
}
int main(void)
{
int i = 10;
*foo(&i) = 100;//foo(&i)为i的地址,*foo(&i)为i本身
printf("%d\n",i);//输出i为100
return 0;
}
二、动态内存分配
(一)malloc函数
1、一般形式:void *malloc(size_t size);
(1)参数size: size 表示申请的空间的大小,单位字节;
(2)返回值:成功返回申请到内存空间的地址;失败返回 NULL。
(3)该函数申请的空间在内存上一定是连续的,返回的是一个指针,指向申请的内存空间(内存空间未初始化全是随机数);
2、malloc函数为内存分配函数(指针型函数),
使用该函数要包头文件#include<stdio.h>
3、在使用该函数时要判断内存空间是否申请到,申请空间申请不到会返回空指针。
(二)free函数
1、释放函数 :释放申请到的内存空间
2、一般形式:
void free(void *ptr);
3、(1)功能:释放之前申请的堆上的空间 ;
(2)参数:ptr 一定是之前申请到堆上空间的地址 ;
(三)注意事项
1、在使用整个内存空间的过程中,申请到内存空间的地址不能改变(一定要保存好);
2、不要多次一起使用free函数;
free(p);//交还完后指针变量p变为野指针
free(p);//此时指针变量p为野指针
为防止野指针出现:
free(p);
p = NULL;
free(p);//此时p为空指针,不会出现问题
3、free(p); 写在 return 0; 前无论是否分配到内存空间都可被处理;
4、申请空间后一定要释放(好借好还,再借不难)。
(四)示例
拼接字符串:先申请一个内存空间存放“Hello”字符串,再申请一个内存空间把“Hello”先放进去再把字符串“World!”拼接在后面,释放掉第一次申请的内存空间,输出拼接的字符串后释放掉第二次申请的内存空间。
(五)realloc函数
1、一般形式:void *realloc(void *ptr,size_t size);
void *ptr:原来空间的地址;size_t size:新开的空间需要多大;
2、realloc函数(把原来空间的内容拷过来并释放原来的空间)用于缩容或扩容。
3、示例:
(六)calloc函数
一般形式:void *calloc(size_t nmemb, size_t size);
申请空间numemb * size 个字节
(七)reallocarray函数
一般形式:void *reallocarray(void *ptr, size_t nmemb, size_t size);
三、函数指针
(一)函数指针
1、指向函数类型的指针;
2、一般形式:
int add(int a, int b)
{
return a + b;
}
int (*p)(int a, int b);//此时未初始化未赋值,p为野指针;可省略ab明确参数类型,参 数名无所谓
p = add;//函数的函数名即为该函数的入口地址
printf("%d\n", (*p)(10, 20));//也可写成p(10,20)为间接访问
add(10, 20)为直接访问
运行结果为30
3、作用:降低函数耦合性。
(二)回调函数
1、回调函数:通过函数指针在函数的参数中调用函数;
2、用例:前面两个函数为回调函数;

(三)qsort函数
1、一般形式:
2、用例:
(四)小考题
立即跳到0x30001000(地址值,可以理解为函数的入口地址)处开始执行代码:
四、指针的数组
int *a[10];//定义一个指针数组(该数组存放了10个指针)
printf("%lu\n", sizeof(a));//占80个字节,一个指针占8个字节
其中const char *argv[]为指针数组,通过一堆字符串向主函数传参
用例:
五、指针的指针(二级指针)
(一)考点
以下代码能否正常运行,不能运行崩在哪里?
1、void getMemory(char *p)
2. {
3. p = malloc(100);
4. }
5. int main(void)
6. {
7. char *s;
8. getMemory(s);//s指针未指向malloc申请的100个字节
9. strcpy(s, "Hello");//此行代码崩溃,s为野指针(随机数)
10. puts(s);
11. }
该程序编译不报错,运行崩溃
正确代码:
1、void getMemory(char **p)//char *为指针的基类型,*为类型说明符,说明p为 指针
2. {
3. *p = malloc(100);
4. }
5. int main(void)
6. {
7. char *s;
8. getMemory(&s);
9. strcpy(s, "Hello");
10. puts(s);
11. }
(二)用例
(三)口诀
1.二维数组作为函数参数,形参为指向数组的指针;
2.指针数组作为函数参数,形参为指向指针的指针。
示例1:
int a[3][4];
int rows = sizeof(a) / sizeof(*a);
foo(&a[0], rows);
void foo(int(*a)[4], int rows);
示例2:
char *s[3];
int len = sizeof(s) /sizeof(*s);
bar(&s[0], len);
void bar(char **s, int len);
(四)例题
1、指针数组打印;
2、指针数组逆序;
3、指针数组排序;
4、指针数组查找。