一、指针型函数
1.在C语言中允许一个函数的返回值是一个指针(即地址),这种返回指针值的函数称为指针型函数。
返回指针的函数的一般形式为:类型名 * 函数名(参数列表)
#include <stdio.h>
int *findNum(int a[], int len, int num);
int main(void)
{
int arr[] = {1,2,3,56,78};
int num;
printf("请输入一个整数:\n");
scanf("%d", &num);
int *p = findNum(arr, 5, num);
if (p == NULL)
printf("Not found!\n");
else
//打印输入数字的地址和输入数字对应的下标
printf("%p, %lu\n", p, p - arr); //1 2 3 56 78
return 0; //arr p
}
//查找一个用户输入的数字,找到返回该数字地址,并输出下标。否则返回为空。
int *findNum(int a[], int len, int num)
{
for (int i = 0; i < len; i ++)
{
if (a[i] == num)
return a + i;
}
return NULL;
}
注意:函数不可以返回局部变量的指针,函数调用结束,局部变量的空间已经被释放了,这 个时候这个空间的指针已经成为了 —— 悬垂指针。
2.函数可返回指针的类型。
1) 作为函数参数传入的指针可以返回。
2) 使用动态内存分配的空间的地址可以返回。
malloc, 堆区—需要手动释放
3) 静态变量和全局变量的指针可以返回。
二、函数指针变量
函数编译之后,也会占用一定的内存空间,那么也就具有地址。把这个函数的地址,就叫做函数的指针。把函数的指针就叫做函数的入口地址。
定义的一般形式:函数的返回值类型 (*指针变量名)(形式参数1, 形式参数2, …);
int sum(int a, int b)
{
return a+b;
}
int main(void)
{
// 定义一个指针变量p,指向sum函数
int (*p)(int a, int b) = sum;
// 或者 int (*p)(int, int) = sum;
// 或者 int (*p)() = sum;
// 利用指针变量p调用函数
int result = (*p)(1, 3);
// 或者 int result = p(1, 3);
printf("%d\n", result);//4
return 0;
}
三、指向指针的指针
如果一个指针变量存放的又是另一个指针变量的地址,则称这个指针变量 为指向指针的指针变量。
二级指针:数据类型 ** 变量名;
int main(void)
{
int a = 10;
int *p = &a;
int **p1 = &p;
printf("a = %d, *p = %d, **p1 = %d\n", a, *p, **p1);//a = 10, *p = 10, **p1 = 10
printf("p = %p, &a = %p, *p1 = %p\n", p, &a, *p1);//p = 0x7ffeefbff518, &a = 0x7ffeefbff518, *p1 = 0x7ffeefbff518
printf("&p = %p, p1 = %p\n", &p, p1);//&p = 0x7ffeefbff510, p1 = 0x7ffeefbff510
return 0;
}
四、通用类型指针
void *
1)任何类型的指针都可以赋值给 void *
void *p;
int *p1;
char *p2;
float *p3;
p = p1; p = p2; p = p3;
2)不能直接进行解引用 *pvoid,如果要进行解引用,需要进行
强制转换。
3)如果void * 赋给其他类型类型的指针,需要强制转换。
void *p;
int *p1;
char *p2;
float *p3;
p1 = (int *)p;
p2 = (char *)p;
p3 = (float *)p;
- void *都用于函数的参数和函数的返回值。