这一篇主要是学习数组与指针的关系。
正文:
一.数组名的理解
这里我直接放一个代码来看看:
可以看出,这里使用*p指向数组首元素的地址,但实际上数组名就是数组首元素的地址。
int*p=&arr[0];
int*pa=arr;
即说明这两个语句中取到到地址是一样的。
我们来做个测试吧。
可以看到,这里打印出来的地址完全一样,说明数组名就是数组首元素的地址。
那这里细心的人会有疑问了,之前我经常写这样的代码:
int main()
{
int arr[10]={0};
int sz=sizeof(arr)/sizeof(arr[0]);
return 0;
}
那么如果这里数组名是地址的话,sizeof(arr)为什么又计算的是数组的长度呢?
这就是例外了,数组名不是地址的情况只有两种:
1.使用sizeof(arr)的时候,这里的arr代表整个数组。
2.使用&取用整个数组的地址的时候(&arr),这里的arr也是代表整个数组。
除此之外,所有的数组名都代表是数组首元素的地址。
二.使用指针访问数组
那么在我们知道数组名就是数组首元素的地址之后,那肯定是有运用的,这里我们就可以用指针访问数组了,话不多说,直接上代码:
int main()
{
int arr[10] = { 0 };
int sz = sizeof(arr) / sizeof(arr[0]);
for (int i = 0;i < sz;i++)
{
scanf("%d", arr + i);//使用数组名读取,它本身就是地址不用加 & 符号
}
for (int i = 0;i < sz;i++)
{
printf("%d ", *(arr + i));//数组名解引用打印数组元素
}
return 0;
}
效果如下:
可以看出,这里使用数组名+i来依次访问数组元素,有了指针我们访问数组元素的方法就更加多样化了。
三.一维数组传参的本质
在我们学过函数之后,我明白了数组是可以传给函数的:
int func(int* arr)
{
}
int main()
{
int arr[10];
func(arr);
return 0;
}
那么数组名是数组首元素的地址,这里的 func(arr); 传过去的 数组名(arr)自然也就是数组首元素的地址了,在函数中采用了int*arr来接收。
这里问一个问题,可以在函数中用sizeof求数组的长度吗?
答案是不能的,这里写个代码来演示一下:
void func(int* arr)
{
int sz = sizeof(arr) / sizeof(arr[0]);
printf("sz=%d\n", sz);
}
int main()
{
int arr[10];
int sz = sizeof(arr) / sizeof(arr[0]);
printf("sz=%d\n", sz);
func(arr);
return 0;
}
一个在函数外用sizeof计算,一个在函数内用sizeof计算。
结果如下:
这里可以发现在函数内部并没计算出正确的数组长度。
原因就是因为函数传递参数的时候传过去的数组首元素的地址(数组名)。那么在函数中计算的长度其实就是 (数组首元素地址的长度)/(数组首元素的长度)==8/4=2。
总结一下就是如果需要数组的长度就在传参数的时候就和数组名一起传过去。
四.冒泡排序
这里我自己运用以前学的写一个冒泡排序(让数组元素升序排列)的算法。
//冒泡排序(经典题型)
#include<stdio.h>
void input(int *arr, int sz)
{//给数组输入数字
int i;
for (i = 0; i < sz; i++)
{
scanf_s("%d", arr+i);
}
}
void Func(int * arr,int sz)
{//依照升序交换位置
int i = 0;
for (i = 0; i < sz - 1; i++)
{
int j;
for (j = 0; j < sz - 1 - i; j++)
{
if (arr[j] > arr[j + 1])
{
int temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
}
void print(int *arr,int sz)
{//打印出升序后的数组
int i = 0;
for (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);
Func(arr, sz);
print(arr,sz);
return 0;
}
效果如下
好啦,这一篇就到这里了
谢谢大家的阅读!