苏州乡村旅游网站建设策划书.doc,incapsula wordpress,软件项目管理平台,网站建设优化推广排名目录 #x1f3c9;前言
#x1f680; 数组名的理解
#x1f680;使用指针访问数组
✈一维数组传参的本质
✈冒泡排序
#x1f3c6;二级指针
#x1f3c6;指针数组
#x1f3c6;指针数组模拟二维数组
#x1f389;结束语 #x1f3c9;前言
上一章#xff0c;小…
目录 前言 数组名的理解
使用指针访问数组
✈一维数组传参的本质
✈冒泡排序
二级指针
指针数组
指针数组模拟二维数组
结束语 前言
上一章小赵和各位聊了关于C语言指针的开篇章我们聊了指针最初的模样但指针这个东西远远不止上一章那样简单因为我们开辟的内存远远不止这么简单毕竟还有数组的开辟还有函数等等这些包括我们的指针它也是有内存的那我们究竟该如何去访问它们的地址如何使用它们的地址内存这样的地址内存又究竟对我们编写代码会带来什么样革命性的改变下面小赵讲讲一一为你解答。 数组名的理解
首先想和各位说的一点就是其实我们的数组名就是我们这个数组的地址那这个数组的地址究竟是整个数组的地址呢还是说是我们的数组首元素的地址还是说是我们数组结尾的那个地址。这里我们打印出来看看。 那我们通过我们对我们的数组打印地址我们发现我们的首元素地址和我们的数组名代表的地址是一样的那么我们的数组的地址其实也就明白了。
那如果我们对我们的地址名取地址呢这里我们也可以打印看看。 这里我们惊讶的发现这两个地址居然是一样的那这样是否可以说明我们arr与arr,是一样的
这里小赵给大家的解释一下虽然这两个地址是一样的但含义却是极大的不同这个就和我们之前聊的单位一样char int 等arr取得是整个数组的地址所以如果你对它加一它的单位实际上就是加了一个数组那另外一个呢如果只是arr它其实代表的就是首元素地址几乎等价于arr[0],那它加的就是以每一个数组的元素的大小为单位那么它的加一就是加到数组的下一个数组的元素。
使用指针访问数组
好了有了上面的知识作为支撑我们就可以试着去探讨如何用我们的指针和我们的数组相联系了。
int main()
{int arr[10] { 0};int i 0;int sz sizeof(arr) / sizeof(arr[0]);//数组有多少个元素int* p arr;//取首元素地址for (int i 0; i sz; i){scanf(%d, p i);//给数组每个位置赋值}for (i 0; i sz; i){printf(%d, *(p i));//打印数组每个位置}return 0;
}
这个代码小赵要和大家解释一下这里我们的数组是定义好的而且我们的指针指向的是首元素的地址那么我们其实对它加加就相当于从数组首元素向后走其实还要给大家补个概念其实我们的指针指向那个地址那我们的p其实就相当于这个地址这也就是我们说的指针地址。那这里就是地址就不用加而下面我们打印的是地址里面的东西所以要解地址操作。
那这时候有人要问了能不能超过这个数组进行访问了其实是不行的因为这里就是一种越界。
int main()
{int arr[10] { 0 };int i 0;int sz sizeof(arr) / sizeof(arr[0]);//数组有多少个元素int* p arr;//取首元素地址for (i 0; i sz1; i){printf(%d, *(p i));//打印数组每个位置}return 0;
} 那这个空间就是未知打印的东西也是未知的。再看这个
int main()
{int arr[3] { 0 };int i 0;int sz sizeof(arr) / sizeof(arr[0]);//数组有多少个元素int* p arr;//取首元素地址for ( i 0; i sz1; i){scanf(%d, p i);//给数组每个位置赋值}for (i 0; i sz1; i){printf(%d, *(p i));//打印数组每个位置}return 0;
} 在这里我们就使用了未被定义的空间那么我们的程序是会报错的。所以这种未被定义的空间是不能使用的我们指针指向它的时候其实我们的指针也就相当于野指针。 ✈一维数组传参的本质
#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;
在讲一维数组传参本质前先给大家看一段代码这个代码应该就是我们学指针前所用的数组传入函数的方式但我们其实不知道的是我们传入的究竟是整个数组的还是数组的某一个呢这个代码刚好可以帮我门验证一下这一点。 在这里我们可以看到我们代码运行后的结果是 101这就证明了我们传入的数组其实只传了一个那么为什么会这样呢其实结合小赵这章所聊的内容我们可以知道我们传入函数的是数组名那数组名是什么呢其实就是指针啦那就证明我们传入函数的其实是个数组首元素指针。那这就好办了那我们以后数组不就可以用指针传了吗而且指针改的是地址可以让我们在函数中的操作进入我们的数组中。这里补的一点是sizeofarr,计算的是这个所代表的存在里面东西的大小如果在函数外面它表示就是整个数组这一点比较特殊只有在sizeof这里才代表这个意思。而我们在函数里面它代表的就是我们传入的首元素的地址计算的也只有数组首元素的大小。
void test(int* arr)//参数写成指针形式
{printf(%d\n, sizeof(arr) / sizeof(arr[0]));//计算⼀个指针变量的⼤⼩
}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;
} 这里我们用指针试试 发现结果一样与我们的猜想是一致的。
✈冒泡排序
有了上面的知识我们就可以试着用指针来编我们的冒泡排序了。
#include stdio.h
void BOBBLE(int* a)//优化版冒泡排序
{for (int m 0; m 4; m){int flag 1;//判断是否排序完成for (int j 0; j 4 - m; j){if (a[j] a[j 1])//如果a[ji]都大于arr[j],则证明排序已经完成了{flag 0;//如果排序未完成那么将falg置为零int t a[j 1];a[j 1] a[j];a[j] t;}}if (flag 1)//如果完成结束循环break;}}
int main()
{int a[5] { 0 };int i;for (i 0; i 5; i){scanf(%d, a[i]);}BOBBLE(a);for (int m 0; m 5; m){printf(%d, a[m]);}return 0;
} 我们会发现有了指针的加入让我们原本冗杂的长的代码变得更容易看懂可以将我们的冒泡排序加入到我们的函数中去了而且由于我们的指针改的其实是数组地址里面的内容那这就让我们的数组可以真正的改变了这个有点类似1的交换 。
同时我们对我们的之前的冒泡排序进行了优化让我们的代码可以不用执行的很复杂大大加快代码了运行速度。 二级指针
那好了数组解决了吧那我们一级指针的地址咋说谁能来管管呢就这样我们的二级指针诞生了。
当然我们得先看看我们指针是否有地址看看它的地址。 我们看到我们指针指向的地址与我们指针本身的地址是不一样的这也就间接证明了我们的指针其实是有自己独立的地址。
那我们的二级指针是什么样的其实也蛮简单的我们可以用上一章的思想解决打开一个空间要一个钥匙那我们现在打开两个呢那不就是两个吗。
int main()
{int a 0;int* p a;int** b p;printf(%p\n, a);printf(%p\n, p);printf(%p\n, p);printf(%p, b);
} 那我怎么才能访问到里面的a能其实也就是开两次锁。 指针数组
那紧接着下来就是我们有木有这样一个数组里面存的是指针呢那其实也是有的。我们之前聊到数组前面的那个就是它里面的元素类型那我们只要将前面写成int*char*等就可以了。
int main()
{int a 0;int* p a;int* b[1] { p };//指针数组printf(%d, *(b[0]));
} 指针数组模拟二维数组
那一维数组聊完了那二维数组呢这里就不得不提小赵前面的概念了二维数组里面每个元素其实就是一维数组那既然是一维数组我们是不是可以试着用一维数组的首元素地址代替呢然后再对这个元素地址进行解指针操作加一加二等这样是不是就让指针数组模拟二维数组的操作完成了。
#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[3] { arr1, arr2, arr3 };//数组名是数组⾸元素的地址类型是int*的就可以存放在parr数组中int i 0;int j 0;for (i 0; i 3; i){for (j 0; j 5; j){printf(%d , parr[i][j]);//这里要解释一下其实我们a[1]*(a1)的操作那我们这里的arr[1][2]其实也就等于*(arr[1]2)的操作。}printf(\n);}return 0;
}这里要和家人们 解释的其实就是我批注的那一块我们的arr[]这个操作其实就是在对我们的arr进行解指针的操作而括号里面的数就是我们arr数字地址的移动然后进行解指针。
结束语
好了小赵今天的分享就到这里了如果大家有什么不明白的地方可以在小赵的下方留言哦同时如果小赵有什么地方说得不对也希望得到大家的指点谢谢各位家人们的支持。你们的支持是小赵创作的动力加油。 如果觉得文章对你有帮助的话还请点赞关注收藏支持小赵如有不足还请指点小赵及时改正感谢大家支持