目录
正文:
1. 数组名的理解
数组名实质是数组首元素的地址。验证代码如下:
#include<stdio.h>
int main()
{
int arr[10] = {0};
printf("%p\n",&arr[0]);
printf("%p\n",arr);//二者结果相同
return 0;
}
这里有一段代码,又会提出新的问题:
int arr[10] = { 1,2,3,4,5,6,7,8,9,10 };
printf("%d\n",sizeof(arr));
//输出结果为:40
数组名确实是数组的首元素地址,但是有两个例外的情况:
(1)sizeof(数组名),此时数组名表示整个数组,求的是整个数组的内存大小(单位字节)
(2)&数组名,这里的数组名表示整个数组,取出的是整个数组的地址(整个数组的地址与数组首元素的地址内涵上不同)
测试代码:
#include<stdio.h>
int main()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
printf("&arr[0]=%p\n",&arr[0]);
printf("arr =%p\n",arr);
printf("&arr =%p\n",&arr);
//三者输出结果完全相同
return 0;
}
那么 arr 与 &arr 之间的到底有什么区别呢?进行数组 + - 整数试试:
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
printf("&arr[0] = %p\n",&arr[0]);
printf("arr = %p\n",arr);
printf("&arr = %p\n",&arr);
printf("&arr[0] + 1 = %p\n",&arr[0] + 1);
printf("arr + 1 = %p\n",arr + 1);
printf("&arr + 1 = %p\n",&arr + 1);
代码结果:
&arr[0] = 0077F820
arr = 0077F820
&arr = 0077F820
&arr[0] + 1 = 0077F824
arr + 1 = 0077F824
&arr + 1 = 0077F848
结论:在指针+-整数时,arr + 1 跳过的是数组的一个元素,而 &arr + 1 跳过的是整个数组,这就很好的解释了 &数组名 代表的是整个数组。
2. 使用指针访问数组
#include<stdio.h>
int main()
{
int arr[10] = {0};
int* parr = arr;
//利用指针对数组进行输入
for(int i = 0;i < 10;i++)
scanf("%d",p + i);
//利用指针进行数组打印
for(int i = 0;i < 10;i++)
printf("%d",*(p+i));//等价于 printf("%d",arr[i]);
return 0;
}
在上述代码中,不难看出:*(p + i) == p[ i ] ,又因为 arr 是数组首元素地址,则:
结论:arr[ i ] == *(arr + i) ;&arr[ i ] == arr + i
3. 一维数组传参的本质
问题:我们之前都是在函数外部计算数组的元素个数,那可以把数组传给一个函数后,函数内部求数组元素的个数吗?(这里指字符串数组以外的数组)
#include<stdio.h>
void test(int arr[])
{
int sz2 = sizeof(arr) / sizeof(arr[0]);
printf("sz2 = %d\n",sz2);
}
int main ()
{
int arr[10] = {1,2,3,4,5,6,7,8,9,10};
int sz1 = sizeof(arr) / sizeof(arr[0]);
printf("sz1 = %d\n",sz1);
test(arr);
return 0;
}
// 结果:sz1 = 10 sz2 = 1
函数形参接收的是数组首元素地址,在函数内部写的 sizeof(arr) ,计算的是一个地址的大小,而不是一个数组的大小,所以不能利用函数求解数组元素个数。
结论:
1. 数组名是数组首元素的地址,在数组传参的时候,传递的是数组名,本质上数组传参传递的是数组首元素的地址。
2. 一维数组传参,形参部分可以写成数组的形式,也可以写成指针的形式。
4. 冒泡排序
核心思想:两两相邻元素进行比较。
#include<stdio.h>
void bubble_sort(int arr[],int sz)
{
for(int i = 0;i < sz - 1;i++)
{
int flag = 1;
for(int j = 0;j < sz - 1 - i;j++)
{
if(arr[j] > arr[j + 1])
{
flag = 0;
int tmp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = tmp;
}
}
if(flag == 1)
break;
}
for(int i = 0;i < sz;i++)
printf("%d ",*(arr + i));
}
int main()
{
int arr[10] = {10,9,8,7,6,5,4,3,2,1};
int sz = sizeof(arr) / sizeof(arr[0]);
bubble_sort(arr,sz);
return 0;
}
5. 二级指针
指针变量也是变量,是变量就会有地址,那么指针变量存放在哪里?
存放指针变量地址的变量,称为二级指针。

二级指针变量的运算:
以上述代码为例:
*ppa == pa;**ppa == a;一个 * 解引用一次,两个 * 解引用两次。
6. 指针数组
指针数组是存放指针的数组。

parr 是一个数组,数组有 3 个元素,每个元素的类型是 int *
指针数组的每个元素是个地址,又可以指向一块区域。
7. 指针数组模拟二维数组
#include<stdio.h>
int main()
{
int arr1[] = {1,2,3,4,5};
int arr2[] = {2,3,4,5,6};
int arr3[] = {3,4,5,6,7};
//数组名是数组首元素的地址,类型是 int* ,就可以存放在 parr 数组中。
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;
}

parr[ i ] 是访问 parr 数组的元素,parr[ i ]找到的数组元素指向了整型一维数组,parr[ i ][ j ]
就是整型一维数组中的元素。
二维数组每一行在内存空间上都是连续的,上述代码每行一维数组在内存上不连续,只是模拟出二维数组的效果,不完全等同于二维数组。
最后,感谢阅读,欢迎大家交流与指正。
&spm=1001.2101.3001.5002&articleId=163105376&d=1&t=3&u=c30f7159cc854089a5525b3927afc80f)
295

被折叠的 条评论
为什么被折叠?



