- 字符指针
- 数组指针
- 指针数组
- 数组传参和指针传参
- 函数指针
- 函数指针数组
- 指向函数指针数组的指针
- 回调函数
-
指针复习
1.指针就是个变量,用来存放地址,地址是唯一标识一块内存空间
2.指针的大小是固定的4/8个字节(32/64)
3.指针是有类型的,指针的类型决定了指针的+-整数的步长,指针类型对指针解引用操作权限有多大
4.指针的运算 指针+-整数; 指针-指针 ; 指针的关系运算
5.指针加指针(指针+指针)这是不可以的🙅 毫无意义
1.字符指针 char*
char ch = 'w';
char* pc = &ch;
char arr[] ="abcdef";
char* p = arr;
char* ps = "abcdef";
2. 指针数组
int main()
{
char* arr[5];//存放指针的数组,指针数组
char* arr[5] = {"abcdef","zhangsan","hehe","wangcai","ruhua"};
//不是把5个字符串放在数组里,而是把首字符地址,存放在数组里去
int* arr1[10];
char** arr1[10];
return 0;
}
3.数组指针 是指针
指向数组的指针,数组的地址
int arr[10] = {1,2,3,4,5,6,7,8,9};//&arr 取出arr的地址
int (*pa)[10] = &arr;
//指针指向数组 这个数组(10个元素)int类型
3.1 数组名和&数组名
数组名是首元素地址;&数组名则是 数值的地址;
从数值的角度他们俩一样 但从类型的角度不同
&arr = 0x013FBB0;
arr = 0x013FBB0;
//虽然取出的地址都一样 但类型不同
&arr+1 = 0x013FBD8; // 8*16^0+2*16^1 = 40 10个int
arr+1 = 0x013FBB4;
三种情况
1.sizeof(arr);//在sizeof里的数组名则是 整个数组
2.&arr ;//取地址&arr 则是 整个数组
3.其他情况出现arr数组名则都是 首元素地址
3.2 数组指针到底有什么用
void print1(int arr[10],int sz)
{
int i = 0;
for(i = 0;i<sz; i++)
{
printf("%d",arr[i]);
}
printf("\n");
}
void print2(int (*p)[10],int sz)
{
int i = 0;
for(i = 0; i<sz ;i++)
{
printf("%d",(*p)[i]);//*(&arr)
}
}
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int sz = sizeof(arr)/sizeof(arr[0]);
print1(arr,sz);//arr 为首元素地址
print2(&arr,sz);//把10个整形元素的数组传过来
return 0;
}
数值指针在一维数组中用的少,在二维数组中比较常见;
int arr[3][5] = {{1,2,3,4,5},{2,3,4,5,6},{3,4,5,6,7}};
print3(arr,3,5);
print3(int arr[3][5], int r; int c)
{
int i = 0;
for(i = 0; i<r;i++)
{
int j =0;
for(j = 0;j<c;j++)
{
printf("%d",arr[i][j]);
}
printf("\n");
}
}
print4(&arr,3,5);
void print4(int(*p)[5],int r, int c)
{
int i = 0;
for(i = 0; i<r;i++)
{
int j =0;
for(j = 0;j<c;j++)
{
printf("%d",*(*(p+i)+j));
}
}
}
在二维数组中,arr为首元素地址,二维数组的首元素地址就是二维数组的第一行
arr是二维数组的数组名,
*(p+i) == p[i] 等价于
4. 数组传参和指针传参
4.1 数组传参
一维数组传参
*数组传参 形参 可以是数组也可以是指针
int arr[10] = {0};
test(arr);
1.test(int arr[]) //ok
2.test(int arr[10]) //ok
3.test(int* arr) // ok
------------------------
int *arr2[20] = {0}; //指针数组 int(*)[20] 20个int*类型元素
test2(arr2);
1.test(int* arr2[20]);
2.test(int** arr);
二维数组传参
总结:二维数组只能省略
int arr[3][5] {0};
test(arr);
1.test(int arr[3][5]); ok
2.test(int arr[][]); no
3.test(int arr[][5]); ok 可以省略行
4.test(int* arr);arr是一行 的地址
5.test(int* arr[5]); no
6.test(int(*arr)[5]); ok
7.test(int** arr);no
4.2 指针传参
一级指针传参
int arr[10] = {1,2,3,4,5,6,7,8,9};
int* p = arr;
int sz = sizeof(arr)/sizeof(arr[0]);
//一级指针p: 传给函数
print(p,sz)
void print(int* p ,int sz)
//当一个函数参数部分为一级指针的时候,函数能接收什么函数呢?
void test(int* p)
{}
int a = 0;
test(&a); //ok
int *ptr = &a;
test(ptr); //ok
int arr[10];
test(arr); //ok
二级指针传参
#include <stdio.h>
void test(int** ptr)
{
printf("num = %d\n", **ptr);
}
int main()
{
int n = 10;
int*p = &n;
int **pp = &p;
test(pp);
test(&p);
return 0;
}
5.函数指针
指向函数的指针
int Add(int x, int y)
{
return x+y;
}
int main()
{
int arr[10] = {0};
printf("%p\n",&arr); // 取出数组的地址;
printf("%p\n",Add); // 相同 都是函数的地址
printf("%p\n",&Add); // Add 和&Add 一样
int(*pf)(int x, int y) = &Add; // int (*)(int , int)
int sum = (*pf)(3,5); //
printf("%d\n",sum);
int sum = Add(3,5);
int sum = pf(3,5);
}
函数指针数组
是数组 一种存储函数指针的数组
int* p;//整形指针
int* arr[5];//整形指针数组
int(*pf)(int,int);//函数指针
int(*pfArr[4])(int,int);//函数指针数组
int (*)(int,int);
pfArr[4];
//可以存放多个参数相同,返回类型相同的函数的地址;
//函数指针数组的用途:转移表
#include <stdio.h>
int add(int a, int b)
{
return a + b;
}
int sub(int a, int b)
{
return a - b;
}
int mul(int a, int b)
{
return a*b;
}
int div(int a, int b)
{
return a / b;
}
int main()
{
int x, y;
int input = 1;
int ret = 0;
int(*p[5])(int x, int y) = { 0, add, sub, mul, div }; //转移表
while (input)
{
printf( "*************************\n" );
printf( " 1:add 2:sub \n" );
printf( " 3:mul 4:div \n" );
printf( "*************************\n" );
printf( "请选择:" );
scanf( "%d", &input);
if ((input <= 4 && input >= 1))
{
printf( "输入操作数:" );
scanf( "%d %d", &x, &y);
ret = (*p[input])(x, y);
}
else
printf( "输入有误\n" );
printf( "ret = %d\n", ret);
}
return 0;
}
指向函数指针数组的指针
是一种指针 指向函数指针数组的指针
//函数指针
int (*pf)(int x, int y);
//函数指针数组
int (*pfArr[5])(int x, int y);
pfArr[5] int(*)(int , int );
//指向函数指针数组的指针
int (*(*pfArr)[5])(int x, int y);
回调函数
回调函数就是一个通过函数指针调用的函数。如果你把函数的指针(地址)作为参数传递给另一个函数,当这个指针被用来调用其所指向的函数时,我们就说这是回调函数。回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
说人话就是函数调用别的函数来实现功能 详情请看qsort函数的模拟实现
总结
以上就是本文的全部内容啦 作为C的灵魂---指针 原来有这么多种类型 看到这里了还不来一个一键三连吗 你的点赞是我创作的动力QAQ