做中文网站的公司,昆明网页制作步骤,网站建设地位,苏州建设信息网站目录
1. 二级指针
1.1 二级指针是什么#xff1f;
1.2 二级指针的作用
2. 一维数组和二维数组的本质
3. 指针数组
4. 数组指针
5. 函数指针
6. typedef的使用
7. 函数指针数组
7.1 转移表 1. 二级指针
如果了解了一级指针#xff0c;那二级指针也是可以很好的理解…目录
1. 二级指针
1.1 二级指针是什么
1.2 二级指针的作用
2. 一维数组和二维数组的本质
3. 指针数组
4. 数组指针
5. 函数指针
6. typedef的使用
7. 函数指针数组
7.1 转移表 1. 二级指针
如果了解了一级指针那二级指针也是可以很好的理解的
1.1 二级指针是什么
二级指针跟一级指针一样也是接收地址但是它存的地址是一级指针的地址
int a 10;
int* p a; //存放a的地址
int** pp p;//存放p的地址 它们的关系就类似这样 一级指针能解引用获取到a的值二级指针也能通过解引用获取a的值区别就是次数不同而已
int main()
{int a 10;int* p a; int** pp p;printf(*p %d, **pp %d, *p, **pp);return 0;
}
我们可以理解二级指针用一次 * 就降一级
所以需要两个 * 才能获取到a第一次的*是得到p
1.2 二级指针的作用
一级指针的作用是可以在函数内部实现两个数的交换
如果只是简单的传参是无法实现两个变量的交换的
#include stdio.hvoid Swap(int a, int b)
{int tmp a;a b;b tmp;
}int main()
{int a 10;int b 8;Swap(a, b);printf(a %d, b %d\n, a, b);return 0;
}
输出:a 10, b 8 指针就可以实现
#include stdio.hvoid Swap(int* a, int* b)
{int tmp *a;*a *b;*b tmp;
}int main()
{int a 10;int b 8;Swap(a, b);printf(a %d, b %d\n, a, b);return 0;
}
输出:a 8, b 10
一级指针可以实现的东西二级指针当然也能实现了
#include stdio.hvoid Swap(int** a, int** b)
{int tmp **a;**a **b;**b tmp;
}int main()
{int a 10;int b 8;int* pa a;int* pb b;Swap(pa, pb);printf(a %d, b %d\n, a, b);return 0;
}
但这样做明显有点小题大做了
前面说了它们是一个分级的关系那么一级指针能对初始变量做的二级指针也能对一级指针做
我们要传参给数组改变变量需要传它的地址指针那么我们需要改变一级指针的时候就要传一级指针的地址二级指针作用也就体现再了这里
#include stdio.hvoid Swap(int** a, int** b)
{int tmp *a;*a *b;*b tmp;
}int main()
{int* a 10;int* b 8;Swap(a, b);printf(a %d, b %d\n, a, b);return 0;
}
2. 一维数组和二维数组的本质
一维数组其实就是指针的另一种形式二维数组也就是二级指针的另一种形式
例如
int* a 和 int a[]
int** a 和 int a[][5]
//二维数组第二个[]必须有值 怎么证明呢
int main()
{int a[] { 1,2,3,4,5 };printf(a[1] %d, *(a 1) %d\n, a[1], *(a 1));return 0;
} 这里的a[1] 和 *(a1) 最终打印出来的结果是一致的
所以为什么数组的第一个数组要从0开始而不是从1开始呢
大概是为了契合指针的引用而做了从0开始的决定这样a的下标是几指针加几都是一样的结果
二级指针也是这样
int main()
{int a[][5] { 1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5 };printf(a[1][1] %d, *(*(a 1) 1) %d\n, a[1][1], *(*(a 1) 1));return 0;
} 甚至指针和数组结合起来一起使用也是可以的两者并不冲突
int main()
{int a[][5] { 1,2,3,4,5, 1,2,3,4,5, 1,2,3,4,5 };printf(*(a[1] 1) %d\n, *(a[1] 1));return 0;
} 所以我们使用[]也是解引用*也是解引用
3. 指针数组
指针数组是指针还是数组
答案是数组它是存放指针的数组
我们可以这么记什么的什么前面是形容词后面是名词那么答案当然就是那个名词了
形似这样 这个数组的每一个元素都是存放着一个指针的上图存放的是一个整型指针
指针数组的每个元素又是一个个地址又可以指向另一块区域
int main()
{int* p1 1;int* p2 2;int* p3 3;int* p4 4;int* p5 5;int* arr[5] { p1,p2,p3,p4,p5 };printf(arr[2] %d, arr[2]);return 0;
}
输出:3
4. 数组指针
前面讲了指针数组是数组那么数组指针当然就是指针了
让我们来睁大眼睛好好的区分一下
int *p1[10]; //指针数组
int (*p2)[10]; //数组指针
上面的指针数组里的指针没有加上小括号所以 * 会优先和 int 结合p1自然就和[10]结合所以这是个有10个元素的整型指针数组
下面的数组指针里的指针加上了小括号所以*先和p2形成一个指针那么这个指针会指向后面的数组所以这是个整型的数组指针
如果我们需要存放一个数组的地址那么当然就是存放在数组指针里了
int arr[5];
int (*p2)[10] arr;
5. 函数指针
函数也是有它自己的地址的
void Swap(int* a, int* b)
{int tmp *a;*a *b;*b tmp;
}int main()
{printf(Swap: %p\n, Swap);printf(Swap: %p\n, Swap);return 0;
} 既然函数是有地址的那么我们未来也有可能会需要将函数的地址存储起来所以就有了函数指针
void (*pf1)(int, int) Swap;
void (*pf2)(int, int) Swap; 上面的两种方法都是一样的可以获取Swap的地址存储到pf1或者pf2中
前面的返回值要和函数相同后面的参数也要和函数相同即使没有参数也要加个 ()
6. typedef的使用
typedef是用来对类型进行重命名的可以将复杂的类型简单化
如果你觉得unsigned int 写起来不方便那么我们可以用typedef对它进行重命名那么以后就可以用uint代替unsigned int 了
typedef unsigned int uint;
自定义类型也是可以使用的以后自己定义的结构体、枚举等都可以用这个方法重命名让我们的代码写起来更方便看起来更简洁
typedef int* ptr_t;
typedef int(*parr_t)[5]; //新的类型名必须在*的右边
typedef void(*pfun_t)(int); //新的类型名必须在*的右边上面还有一些特殊的写法新的名字并不是一定都是写在后面的要注意看是什么类型才能决定怎么使用
7. 函数指针数组
跟前面的理解方法一样函数指针数组是数组是用一个数组存放多个函数的地址这个数组就是函数指针数组
下面的转移表可以很好的帮助我们理解它
7.1 转移表
#include stdio.hint 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;
}void menu()
{printf(***********************\n);printf(***** 1.add 2.sub *****\n);printf(***** 3.mul 4.div *****\n);printf(***** 0.exit *****\n);printf(***********************\n);
}int main()
{int x, y;int input;int (*p[5])(int, int) { 0,add,sub,mul,div };do{menu();printf(请选择:);scanf(%d, input);if (input 1 input 4){printf(请输入两个操作数:);scanf(%d %d, x, y);int ret p[input](x, y);printf(%d\n, ret);}else if (input 0){printf(退出计算器\n);}else{printf(输入错误请重新输入\n);}} while (input);return 0;
} 上面我们定义了一个p[5]数组来存放0和4个函数的地址我们知道了它的地址就可以直接使用它
使用方法 这里的ret是用来存放函数返回之后的结果这里先用p[input]解引用得到函数的地址再加上参数就可以使用那个函数了
比如 input 1 那么这个p[1]存放的是add的地址那么就相当于add(x, y)跟平常调用函数没有区别使用函数指针数组可以让我们的代码更加简洁如果一个一个写调用的话就比较麻烦看起来的效果自然没有这个好
感谢观看 完