一.数组名的理解
1.对于数组而言,数组名通常指首元素的地址,但是有两个例外:
① sizeof(数组名); ②&数组名
我们都知道sizeof是一个操作符,它只关注于占用内存空间的大小,不在乎内存中存放的什么数据,那么数组在内存中连续存放, 它作为一个整体,在计算占用内存空间大小时理所应当应该全部计算,所以sizeof(数组名)—>指的是整个数组,计算整个数组的大小。
&数组名,也表示整个数组,取出的是整个数组的地址,整个数组的地址与首元素地址在值上没有什么差异,但是当 &arr+1 时, 就会发现 : 地址跳过了整个数组;
而 arr+1 时: 跳过的是一个元素:
2.当有了以上的知识,我们可能会思考:
int arr[10] = { 0 };
int i = 0;
for(i=0;i<10;i++)
{
printf("%d ",arr[i]);
}
数组 arr[ i ] 是什么意思 ?
基于对数组和指针的理解,我们知道arr[0]指向数组的第一个元素,arr[i]指向第i+1个元素,而*(arr+i)也指向了第i+1个元素
那是否可以用arr+1代替arr[i] ?
答案是肯定的,由此,我们可以看出arr[ i ] 的本质就是 *(arr + i) ;
到了这,我们又会想 : 既然 arr[ i ] = *(arr + i),那么 [ ]的作用是什么?
我们可能会写出一个这样的代码 :
int arr[10] = { 0 };
int i = 0;
for(i=0;i<10;i++)
{
printf("%d ",i[arr]);
}
然后我们会神奇的发现:它输出的结果也是正确的!
由此证明了,[ ]仅仅是一个操作符,它仅仅是为了将arr的第 i 个元素转换成 地址的形式再计算,也就是*(arr + i)的形式。
总结:(以arr为数组名)
①arr通常表示首元素地址,在sizeof(arr)和&arr中指整个数组;
②输入或输出数组,可用 :注:scanf输入时用的是地址,不需要解引用 arr+i—>*(arr+i); arr[i] = i[arr] = (arr+i); p+i(其中int* p = arr) ; 注:关于指针:指针变量就是一个变量,是一个可以存放地址的变量,也需要开辟一个空间(地址)放p的地址(int* p) ;
二.一维数组传参:
1.本质:实参的数组名就是首元素地址;
2.所以形参即使写成数组形式,本质上也是一个指针变量,故函数传参,形参数组int arr[ ] ([ ]大小可写可不写)=int* arr;
注:当我们传参时,传过去的是首元素地址,test()中int arr[]实际已经是指向第一个元素的地址,故 arr已经 不再是一个数组,而相当于一个整型指针,所以形参数组int arr[ ] =int* arr;同时在数组传参时,我们通常会 将数组的大小也作为参数传给函数。
三.冒泡排序
## 一维数组传参应用
#include<stdio.h>
void input(int* arr, int sz)//用指针接收数组首元素地址
{
int i = 0;
for (i = 0; i < sz; i++)
{
scanf("%d", arr + i);//以arr+i的形式输入
}
}
void bubble_sort(int* arr,int sz) //可用递归
{
int i = 0;
int count = 0;
for (i = 1; i <= sz; i++)
{
int j = 0;
for (j = 0;j<sz-i; j++)
{
if (arr[j] > arr[j + 1])
{
int tem = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tem;
}
}
}
}
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);
bubble_sort(arr,sz);
print(arr, sz);
return 0;
}