【C语言】理解指针(2)

(一)数组名的理解及使用指针访问数组

(二)一维数组的传参本质及冒泡排序

(三)二级指针及指针数组

(四)指针数组模拟二维数组

一.数组名的理解

我们可以参考下面的代码:

#include"20230812定义.h"
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
	printf("%p\n", arr);
	printf("%p\n", &arr[0]);
	return 0;
}

我们代码测试一下:

 这说明在这种情况下(一维)数组名其实是数组元素的首元素的地址,这两者本质是一样的。

可是我们有两个地方不太一样,&数组名和sizeof(数组)。

sizeof(arr)为整个数组中元素所占字节的个数,&arr实际上是取出整个数组的地址,和arr还是不一样的。

我们试一下它们的加减整数比较:

 我们看上面这段代码,arr+1是整整跳过了40个字节,相当于跳过了整个arr数组,在64位环境下也是如此;“+1”代表偏移的量有多少,一般情况下“+1”可以跳过一个单元。

二.使用指针访问数组

我们可以使用指针的形式来访问数组:

#include"20230812定义.h"
int main()
{
	int arr[10] = { 0 };
	int i = 0;
	int* p = arr;
	for (i = 0; i < 10; i++)
	{
		scanf("%d", arr + i);
	}
	printf("\n");
		int sz = sizeof(arr) / sizeof(arr[0]);
		for (i = 0; i < sz; i++)
		{
			printf("%d ", arr[i]);
			printf("%d ", *(arr + i));
			printf("%d ", *(&arr[0] + i));
	}
	
	return 0;
}

结果如下:

 

 这样再次说明了数组名是数组首元素的地址,且*(arr+i)==arr[i]==*(&arr[0]+i)。

当我们设置成这样,也是可以运行的:

 结果如下:

 

 此时arr和p等价d,但是求数组大小时只能用arr。

三.一维数组传参的本质

我们像上面求一个数组的元素个数,只是在函数里试一下。

 说明了我们传参只是传了首元素的地址,在函数里面是不能直接计算元素个数的。

这里的sizeof(arr)实际上是计算一个地址的大小,与我们一般在函数外计算的不一样。

总的来说,我们数组传参时,形参既可以是数组名,也可以是指针。

四.冒泡排序

如下面的代码:

#include"20230812定义.h"
void Print(int arr[10], int sz)
{
	int b = 0;
	for (b= 0; b < sz - 1; b++)
	{
		int flag = 1;//假设这一趟已经排好了
		int a = 0;
		for (a = 0; a < sz - 1-b; a++)
		{
			if (arr[a] >= arr[a + 1])
			{
				int tmp = arr[a];
				arr[a] = arr[a + 1];
				arr[a + 1] = tmp;
				flag = 0;//无序
			}
		}
		if (flag == 1)//既然这一趟不需要交换,说明排好了
			break;
	}
}
int main()
{
	int arr[10];
	int i = 0;
	for(i=0;i<10;i++)
	{
		scanf("%d",arr+i);
	}
	int sz = sizeof(arr) / sizeof(arr[0]);
	Print(arr, sz);
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
}
	return 0;
}

核心是两两相邻的元素进行比较,使数组升序。

如:10 9 8 7 6 5 4 3 2 1......9 10 8 7 6 5 4 3 2 1......直到9 8 7 6 5 4 3 2 1 10,往复循环,进而得到1 2 3 4 5 6 7 8 9 10。

五.二级指针

如图所示:

#include"20230812定义.h"
int main()
{
    int a = 10;
    int* p = &a;//一级指针
    int** pp = &p;//二级指针
    int*** ppp = &pp;//三级指针
    printf("p=%p\n", p);
    printf("pp=%p\n", pp);
    printf("ppp=%p\n", ppp);
    printf("*ppp=%p\n", *ppp);
    printf("**ppp=%p\n", **ppp);
    printf("***ppp=%d\n", ***ppp);
    return 0;
}

        存放非指针类型的变量的地址的指针,叫做一级指针;存放一级指针的指针,叫做二级指针;存放二级指针的指针,叫做三级指针......以此类推,解引用也是一样的道理,一层一层抽丝剥茧。

六.指针数组

存放指针的数组叫做指针数组,我们可以换一个角度类比,即存放整型的数组叫做整型数组,如int arr[10]={1,2,3,4,5,6,7,8,9,10},这里面存放的是整型。

 

 指针数组arr最终指向的是整型元素,这又仅是一层地址,用int*类型就足够了。

七.指针数组模拟二维数组

我们之前接触过二维数组,现在我们用指针模拟二维数组。

 str[a]就是访问arr1,arr2,arr3;str[a][b]就是访问arr1,arr2,arr3的具体元素。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值