玩转指针(2)

一、数组名的理解

数组名是数组首元素的地址,但有两种例外情况。

在这里插入图片描述

例外情况① sizeof(数组名)

sizeof中单独放数组名,这里的数组名表示整个数组,求的是整个数组的大小,单位是字节。
int main()
{
	int arr[10] = { 1,2,3,4,5,6,7,8,9,0 };
	printf("%zd\n", sizeof(arr));//这里的数组名如果理解为数组首元素的地址的话,那么在64位环境下应该是8个字节,在32位环境下应该是4个字节
	//但输出的结果却是40个字节,显然理解有误。
	//其实这里求的是整个数组所占内存空间的大小
	printf("%zd\n", sizeof(arr + 0));//这里sizeof中不是单独放的数组名,而是arr+0,这里的arr+0应该理解为数组首元素的地址。
	                                 //那么在64位环境下应该是8个字节,在32位环境下应该是4个字节 
}

例外情况②&数组名

这里的数组名也表示整个数组,取出的是整个数组的地址。注意,整个数组的地址与数组首元素的地址是不一样的。

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

因为&arr[0]与arr都是int * 类型的地址,故&arr[0]+1与arr+1都是跳过一个int类型的长度。&arr表示取出整个数组的地址,则&arr+1表示跳过整个数组。

二、使用指针访问数组

int main()
{
	int arr[10] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//输入
	for (int i = 0; i < sz; i++)
	{
		scanf("%d", arr+i);//arr+i表示下标为i元素的地址
	}
	//输出
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", *(arr + i));
		//printf("%d ", *(i + arr));
		//printf("%d ", arr[i]);
		//printf("%d ", i[arr]);
	}
	return 0;
}
总结: ①arr+i与i+arr均表示arr数组中下标为i元素的地址 。
② arr[i]与i[arr]与*(arr+i)与*(i+arr)均表示arr数组中下标为i的元素。

三、一维数组传参的本质

①数组传参时,实参写数组名,形参既可以写成数组的形式,也可以写成指针的形式。形参无论写成哪种形式,本质上传递的还是数组首元素的地址。并且形参的数组和实参多数组是同一个数组。
②形参写成数组形式的好处:对于没有学过指针的初学者而言,更容易上手数组。
③一维数组传参时,形参若写成一维数组时,数组的大小可以省略;二维数组传参时,形参若写成二维数组时,二维数组行的大小可以省略,列的大小不能省略。

在这里插入图片描述
在这里插入图片描述

四、冒泡排序

例如将n个乱序的整数排成升序,需要进行n-1趟排序,每一趟解决一个元素
Input(int* arr, int sz)
{
	for (int i = 0; i < sz; i++)
	{
		scanf("%d", arr + i);
	}
}

void bubble_sort(int* arr, int sz)
{
	  /*数组中有sz个元素,需要进行sz - 1趟冒泡排序,每一趟解决一个元素。因此外循环要循环sz-1次*/
	for (int i = 0; i < sz - 1; i++)
	{
		/*
		第一趟冒泡排序需要将sz-1对元素两两比较,第一趟冒泡排序结束后,最大的元素就排好位置了
		第二趟冒泡排序需要将sz-2对元素两两比较,第二趟冒泡排序结束后,第二大的元素就排好位置了
		第三趟冒泡排序需要将sz-3对元素两两比较,第三趟冒泡排序结束后,第三大的元素就排好位置了
		依次类推
		*/
		for (int j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				int temp = 0;
				temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
	}
}

void Ouput(int* arr, int sz)
{
	for (int i = 0; i < sz; i++)
	{
		printf("%d ", *(arr + i));
	}
}

int main()
{
	int arr[10] = { 0 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	//输入
	Input(arr, sz);
	//将数组中的元素排成升序
	bubble_sort(arr, sz);
	//输出
	Ouput(arr, sz);
	return 0;
}

以上的冒泡排序算法(bubble_sort函数)在某种情况下,运行时会特别浪费时间。比如arr数组中的元素本来就满足升序时,bubble_sort函数依旧会进行sz-1趟冒泡排序,但显然这比较浪费时间。下面对bubble_sort函数进行优化,优化目的:当arr数组中的元素本来就满足升序时,只需要进行一趟冒泡排序。
void bubble_sort(int* arr, int sz)
{
	/*数组中有sz个元素,需要进行sz - 1趟冒泡排序,每一趟解决一个元素。因此外循环要循环sz-1次*/
	for (int i = 0; i < sz - 1; i++)
	{
		/*
		第一趟冒泡排序需要将sz-1对元素两两比较
		第二趟冒泡排序需要将sz-2对元素两两比较
		第三趟冒泡排序需要将sz-3对元素两两比较
		依次类推
		*/
		int flag = 1;//假设arr数组中的元素已经满足升序

		for (int j = 0; j < sz - 1 - i; j++)
		{
			if (arr[j] > arr[j + 1])
			{
				flag = 0;
				int temp = 0;
				temp = arr[j];
				arr[j] = arr[j + 1];
				arr[j + 1] = temp;
			}
		}
		if (flag == 1)
		{
			break;
		}
	}
}

五、二级指针

①何为二级指针

一级指针如Int * a、 char* a、float *a,显然一级指针也是变量,是变量就有地址,二级指针就是存储一级指针地址的变量。

在这里插入图片描述

②何时使用二级指针

以后取出一级指针的地址时,若想要将它存起来,就用二级指针存储。

六、指针数组

①何为指针数组

整型数组(如int arr[10])是用来存放整型变量的数组;字符数组(如char arr[10])是用来存放字符变量的数组。同理指针数组是用来存放指针变量的数组。

在这里插入图片描述

②指针数组的应用

在这里插入图片描述

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

在这里插入图片描述

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值