深入理解指针3

(一)数组名的理解

&arr[0];
arr;

通过之前的学习,我们可以知道,上面两行代码的意义相同,都是表示数组首元素的地址,但并不是所有情况都是这样,有两个例外

1.sizeof,sizeof中单独数组名,这里的数组名表示整个数组,计算的是整个数组的大小,单位是字节
2.&数组名,这里的数组名表示整个数组,取出的是整个数组的地址

(二)使用指针访问数组

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;
}

这里的arr是数组首元素的地址,可以赋值给p,那么其实在这里arr和p是等价的,我们可以使用arr[i]访问数组,那么也可以用p[i]访问数组

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;
}

(三)一维数组传参的本质

void test(int arr[])
{
	int sz2 = sizeof(arr) / sizeof(arr[0]);
	printf("sz2=%d", sz2);
}
int main()

{
	int arr[10] = { 0 };
	int sz1 = sizeof(arr) / sizeof(arr[0]);
	printf("sz1=%d\n", sz1);
	test(arr);
	return 0;
}

观察上方代码和运行结果,发现数组传递给函数后,函数内部没有正确获得数组的元素个数,我们知道数组名是数组首元素的地址,所以本质上数组传递的是数组首元素的地址。所以函数形参部分理论上应该使用指针变量来接受首元素的地址,但是正因为函数参数部分是本质指针,所以在函数内部是没办法求数组元素个数的

(四)冒泡排序 冒泡排序的核心思想就是:两个相邻的元素进行比较

1.理论基础

冒泡排序的核心思想就是:两个相邻的元素进行比较,我们给一个整型数组,里面存放10个乱序的整型元素,要求将它们从小到大排序,我们首先两两做比较,将第一个与第二个相比,如果第一个元素大于第二个元素,那么将它们交换顺序,否则不变,依次类推,那么想要完成全部排序,我们需要进行9趟冒泡排序,完成一趟冒泡排序之后,最大的数已经排到最后面,而下一趟只需比较前9位数,所以在第一次冒泡排序里面我们需要交换9次,而下一趟去除最后一位数不用排,只需交换8次,依次类推

2.代码实现

void dubble_test(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		int j = 0;
		{
			for (j = 0; j < sz - 1 - i; j++)
			{
				if (arr[j] > arr[j + 1])
				{
					int temp = arr[j+1];
					arr[j + 1] = arr[j];
					arr[j] = temp;

				}
			}
		}
	}
}

void print(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
int main()

{
	int arr[10] = { 1,2,4,9,3,6,7,4,23,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	print(arr, sz);
	dubble_test(arr, sz);
	print(arr, sz);
	return 0;
}

3.代码优化 上述代码中需要将数组里的元素全部交换一遍,但是如果数组中元素已经有序,那么就不需要依次排序交换了,如下代码

void dubble_test(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		int flag = 0;//假设这一趟已经有序
		int j = 0;
		
			for (j = 0; j < sz - 1 - i; j++)
			{
				if (arr[j] > arr[j + 1])
				{
					int temp = arr[j+1];//发生交换就说明无序
					arr[j + 1] = arr[j];
					arr[j] = temp;
					flag = 1;

				}
			}
			if (flag ==0)//这一趟没有交换就说明已经有序,后续无需交换
			{
				break;
		}
	}
}

void print(int arr[], int sz)
{
	int i = 0;
	for (i = 0; i < sz; i++)
	{
		printf("%d ", arr[i]);
	}
	printf("\n");
}
int main()

{
	int arr[10] = { 1,2,4,9,3,6,7,4,23,5 };
	int sz = sizeof(arr) / sizeof(arr[0]);
	print(arr, sz);
	dubble_test(arr, sz);
	print(arr, sz);
	return 0;
}

(五)二级指针

指针变量也是变量,所以也有地址,那么用什么去存储指针变量的地址呢?答案就是二级指针

int main()

{
	int n = 0;
	int* p1 = &n;//一级指针
	int** p2 = &p1;//二级指针
	return 0;
}

我们知道可以通过解引用操作符*来获取指针指向的内容,那么二级指针是否也可以用*来获取最初变量的值呢,如下代码实现

int main()

{
	int n = 10;
	int* p1 = &n;//一级指针
	int** p2 = &p1;//二级指针
	printf("%d", **p2);//*p2=p1,**p2=*p1=n
	return 0;
}

(六)指针数组

我们知道,整型数组,就是存放整型的数组,字符数组,就是存放字符的数组,而指针数组呢,没错,就是存放指针的数组

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

我们可以通过int*parr里面的下标依次找到arr1,arr2,arr3,再通过arr里面里面的下标找到其中的元素,这就相当于二维数组

int main()

{
	int arr1[5] = {1,2,3,4,5};
	int arr2[5] = { 2,3,4,5,6 };
	int arr3[5] = { 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;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值