网站推广的目的是什么,抖音运营公司排名前十,html5国外网站模板html源码下载,浙江三建建设集团有限公司网站C语言【指针篇】#xff08;三#xff09; 前言正文1. 数组名的理解2. 使用指针访问数组3. 一维数组传参的本质4. 冒泡排序5. 二级指针6. 指针数组7. 指针数组模拟二维数组 总结 前言
本文主要基于前面对指针的掌握#xff0c;进一步学习#xff1a;数组名的理解、使用指针… C语言【指针篇】三 前言正文1. 数组名的理解2. 使用指针访问数组3. 一维数组传参的本质4. 冒泡排序5. 二级指针6. 指针数组7. 指针数组模拟二维数组 总结 前言
本文主要基于前面对指针的掌握进一步学习数组名的理解、使用指针访问数组、一维数组传参的本质、冒泡排序、二级指针、指针数组以及指针数组模拟二维数组。
正文
1. 数组名的理解
我们可能遇到过这样的代码
int arr[10] {1,2,3,4,5,6,7,8,9,10};
int *p arr[0];在这里arr[0]表示取到第一个元素的首地址而arr本身就是地址地址与首元素的地址一样如下代码可做验证
#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);return 0;
}运行结果果然一致 结论数组名和数组首元素的地址打印出的结果一模一样即数组名就是数组首元素 的地址。 但是有人又有这样的疑问既然一样它们所占字节是否也是相等的如下代码
#include stdio.h
int main()
{int arr[10] { 1,2,3,4,5,6,7,8,9,10 };printf(%zd\n, sizeof(arr));printf(%zd\n, sizeof(arr[0]));return 0;
}显然不同若arr是数组首元素的地址输出应该是4或8取决于系统中指针的大小。 其实数组名是数组首元素的地址这一说法是正确的 但存在两个例外 sizeof(数组名)sizeof中单独放数组名这里的数组名表示整个数组计算的是整个数组的大小单位是字节。 数组名这里的数组名表示整个数组取出的是整个数组的地址整个数组的地址和数组首元素的地址是有区别的)。 我们可以测试如下代码
#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有啥区别呢再看下面代码
#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[0]1 %p\n, arr[0] 1);printf(arr %p\n, arr);printf(arr1 %p\n, arr 1);printf(arr %p\n, arr);printf(arr1 %p\n, arr 1);return 0;
}可以发现arr[0]和arr[0]1相差 4 个字节arr和arr1相差 4 个字节这是因为arr[0]和arr都是首元素的地址1就是跳过一个元素。而arr和arr1相差 40 个字节这是因为arr是数组的地址1操作是跳过整个数组。至此数组名的意义就清楚了数组名是数组首元素的地址但有上述 2 个例外。
2. 使用指针访问数组
下面我们看如何使用指针快速访问数组下面给出常见写法 注意:语句上面的注释代表等价
#includestdio.hint 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);p;*/scanf(%d, p i);}//输出p arr;for (int i 0; i sz; i){/*printf(%d, *p);p;*//*printf(%d , *(p i));*//*printf(%d , arr[i]);*//*printf(%d , p[i]);*/printf(%d , i[arr]);//可以但不推荐毕竟太奇怪了}return 0;
}
最后自己敲出来理解一下。
3. 一维数组传参的本质
数组可以传递给函数本小节讨论数组传参的本质。先看一个问题之前都是在函数外部计算数组的元素个数能否把数组传给函数后在函数内部求数组的元素个数呢
#include stdio.h
void test(int arr[])//arr[]相当于指针变量x64是8字节
{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;
}输出结果
发现在函数内部没有正确获得数组的元素个数。
这是因为数组传参的本质是数组名是数组首元素的地址数组传参时传递的是数组名即本质上传递的是数组首元素的地址。 所以函数形参部分理论上应该使用指针变量来接收首元素的地址。在函数内部写sizeof(arr)计算的是一个地址的大小单位字节而不是数组的大小单位字节。正是因为函数的参数部分本质是指针所以在函数内部无法求出数组元素个数。
void test(int arr[])//参数写成数组形式,本质上还是指针
{printf(%d\n, sizeof(arr));
}
void test(int* arr)//参数写成指针形式
{printf(%d\n, sizeof(arr));//计算一个指针变量的大小
}
int main()
{int arr[10] {1,2,3,4,5,6,7,8,9,10};test(arr);return 0;
}两个的结果是一致的x64都是8 总结一维数组传参形参的部分可以写成数组的形式也可以写成指针的形式。
4. 冒泡排序
排序在数据结构中会重点讲这里简单说一下冒泡排序 冒泡排序的核心思想是两两相邻的元素进行比较。
方法1
//方法1
void bubble_sort(int arr[], int sz)//参数接收数组元素个数
{int i 0;for(i0; isz-1; i){int j 0;for(j0; jsz-i-1; j){if(arr[j] arr[j1]){int tmp arr[j];arr[j] arr[j1];arr[j1] tmp;}}}
}
int main()
{int arr[] {3,1,7,5,8,9,0,2,4,6};int sz sizeof(arr)/sizeof(arr[0]);bubble_sort(arr,sz);int i0;for(i0;isz;i){printf(%d,arr[i]);}return 0;
}方法2 - 优化
//方法2-优化
void bubble_sort(int arr[],int sz)
{int i0;for(i0;isz-1;i){int flag1;//假设这一趟已经有序了int j0;for(j0;jsz-i-1;j){if(arr[j]arr[j1]){int tmp arr[j];arr[j] arr[j1];arr[j1]tmp;flag 0;}}if(flag1)//这一趟没交换就说明已经有序,后续无序排序了break;}
}
int main()
{int arr[]{3,1,7,5,8,9,0,2,4,6};int szsizeof(arr)/sizeof(arr[0]);bubble_sort(arr, sz);int i0;for(i0;isz;i){printf(%d,arr[i]);}return 0;
}5. 二级指针
指针变量也是变量有地址指针变量的地址存放在二级指针中。
#include stdio.h
int main()
{int a10;int *pa a; int**ppapa;return 0;
}对于二级指针的运算有
*ppa通过对ppa中的地址进行解引用找到的是pa*ppa其实访问的就是pa。
int b 20;
*ppa b;//等价于 pa b;**ppa先通过*ppa找到pa然后对pa进行解引用操作*pa找到的是a。
**ppa 30;
//等价于*pa 30;
//等价于a 30;int main()
{int a 10;int* pa a;int** ppa pa; printf(%d\n, a);printf(%d\n, *pa);printf(%d\n, **ppa);return 0;
}6. 指针数组
指针数组是存放指针的数组类比整型数组存放整型、字符数组存放字符。指针数组的每个元素都是用来存放地址指针的每个元素又可以指向一块区域。 简单示例
int main()
{int a 10, b 20, c 30,d 40;int* parr[4] { a,b,c,d };for (int i 0; i 4; i){printf(%d , *(parr[i]));}return 0;
} 7. 指针数组模拟二维数组
代码演示
#include stdio.h
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 };int i 0;for (i 0; i 3; i){int j 0;for (j 0; j 5; j){printf(%d , parr[i][j]);}printf(\n);}return 0;
}
parr[i]用于访问parr数组的元素parr[i]找到的数组元素指向了整型一维数组parr[i][j]就是整型一维数组中的元素。
上述代码模拟出二维数组的效果但实际上并非完全是二维数组因为每一行并非是连续的。
总结
本文大部分内容都是围绕数组和指针两者结合使用并且涉及排序这个数据结构的重要内容喜欢或觉得有用的话还希望点赞关注收藏三连支持一下谢谢。