前言
各位师傅好,我是qmx_07,今天来为大家讲解 用指针理解数组,二级指针,以及指针数组,之后会持续更新相关内容!
数组名的理解
我们先来看看这段代码:
我们发现,数组名就是数组⾸元素(第⼀个元素)的地址
那这两种方式,又有怎样的不同呢?
&arr[0]和arr的取地址方式,是只移动一个单位长度
而 &arr 的取地址方式,是移动一整个数组长度
使用指针 去使用数组
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
int arr[10] = { 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
int* p = arr;
//输入
for (int i = 0; i < sz; i++)
{
scanf("%d", p + i);
}
//输出
for (int i = 0; i < sz; i++)
{
printf("%d ", *(p + i));
}
return 0;
}
通过 int* p 获取数组的首个元素位置,再通过+i,依次访问修改元素,在进行遍历
二级指针
二级指针: 简单来说就是 存放一级指针的地址
二级指针的流程,先找一级指针的位置,再根据一级指针存储的地址,找到变量
指针数组
概念: 存放指针的数组
名字有些绕嘴,画下图大家理解下:
指针数组模拟二维数组
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
int main()
{
int arr1[] = { 1,2,3,4,5 };
int arr2[] = { 2,3,4,5,6 };
int arr3[] = { 3,4,5,6,7 };
int* parr[3] = { arr1,arr2,arr3 };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 5; j++)
{
printf("%d ",*(*(parr+i)+j) );
}
printf("\n");
}
return 0;
}
思路:*(parr+i)按照顺序 找到每一个大空间,*(*(parr+i)+j)再遍历大空间的每一个数据
画图剖析
你也可以写成这个样子:
*(*(parr+i)+j) == parr[i][j] 这两种方式是等价的
练习题
冒泡排序:两两相邻的元素进⾏⽐较
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
void bubble_sort(int arr[], int sz)
{
int i = 0;
int flag = 1;//假设已经有序了
for (i = 0; i < sz - 1; i++)
{
int j = 0;
for (j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
flag = 0;//发生交换就说明,无序
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
if (flag == 1)//说明已经有序,后面不用排序了
{
break;
}
}
}
int main()
{
int arr[] = { 3,1,7,5,8,9,0,2,4,6 };
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr, sz);
for(int i = 0; i < sz; i++)
{
printf("%d ", arr[i]);
}
return 0;
}
思路: 1.如果已经完成排序 不进行冒泡排序
2.如果 乱序,则 j 和 j+1 比较,满足条件换位置 直到完成正序排序
画图剖析
实在不好意思,这个gif动图 总是出现卡壳,大概是这种思路,第一次循环如果还是有部分乱序,到后面会再进行一次排序,直到正序
数组指针
概念:存放的应该是数组的地址,能够指向数组的指针变量
数组指针变量:int (*p)[10];
注意: []的优先级要⾼于*号的,所以必须加上()来保证p先和*结合
函数指针
可以看到 函数名调用,就是直接读取函数的地址,所以我们把函数地址保存在指针里,就可以拿指针进行调用函数
函数指针数组
要把函数的地址存到⼀个数组中,那这个数组就叫函数指针数组
int (*parr1[3])();
parr1 先和 [] 结合,说明parr1是数组,数组里的内容是:int (*)() 的函数指针
练习题
使用函数指针数组 写一个计算器
#define _CRT_SECURE_NO_WARNINGS 1
#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 }; //转移表
do
{
printf("*************************\n");
printf(" 1:add 2:sub \n");
printf(" 3:mul 4:div \n");
printf(" 0:exit \n");
printf("*************************\n");
printf("请选择:");
scanf("%d", &input);
if ((input <= 4 && input >= 1))
{
printf("输⼊操作数:");
scanf("%d %d", &x, &y);
ret = (*p[input])(x, y);
printf("ret = %d\n", ret);
}
else if (input == 0)
{
printf("退出计算器\n");
}
else
{
printf("输⼊有误\n");
}
} while (input);
return 0;
}
总结:
今天我们讲解了 数组名的相关内容,二级指针,指针数组,数组指针,函数指针,函数指针数组的相关内容,后面还有一节指针的博客,会持续更新