[C语言]-基础知识点梳理-指针第二节

前言

各位师傅好,我是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;
}

总结:

今天我们讲解了 数组名的相关内容,二级指针,指针数组,数组指针,函数指针,函数指针数组的相关内容,后面还有一节指针的博客,会持续更新

  • 11
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值