网站怎么续费,外贸公司英文网站,4399游戏网页版,做药物研发的人上什么网站系列文章目录 文章目录 系列文章目录前言1. 指针的使⽤和传址调⽤结论#xff1a;实参传递给形参的时候#xff0c;形参会单独创建⼀份临时空间来接收实参#xff0c;对形参的修改不影响实 参。那么这个时候#xff0c;就要搬出指针大哥#xff0c;在main函数中将a和b的地…系列文章目录 文章目录 系列文章目录前言1. 指针的使⽤和传址调⽤结论实参传递给形参的时候形参会单独创建⼀份临时空间来接收实参对形参的修改不影响实 参。那么这个时候就要搬出指针大哥在main函数中将a和b的地址传递给Swap函数Swap函数⾥边通过地址间接的操作main函数中的a和b像是把家地址搬到函数中直接改变家里的东西a, b的值。 2 .数组名的理解所以说数组名就是数组⾸元素(第⼀个元素)的地址。 3. 使⽤指针访问数组4 . 一维数组函数传参形本质接下来进入重点⾸先从⼀个问题开始我们之前都是在函数外部计算数组的元素个数那我们可以把函数传给⼀个函数后函数内部求数组的元素个数吗 5. ⼆级指针总结2级指针是存放一级指针的地址 6. 指针数组指针数组是存放指针的数组但是并非是2维数组原因是模拟的数组并不连续而数组在内存上是连续存放的。 前言
1. 指针的使⽤和传址调⽤
学习指针的⽬的是使⽤指针解决问题那什么问题⾮指针不可呢
案例写⼀个函数交换两个整型变量的值 代码如下
#include stdio.h
void Swap1(int x, int y)
{int tmp x;x y;y tmp;
}
int main()
{int a 0;int b 0;scanf(%d %d, a, b);printf(交换前a%d b%d\n, a, b);Swap1(a, b);printf(交换后a%d b%d\n, a, b);return 0;
}输出结果 这是为什么呢 我们发现在main函数内部创建了a和ba的地址是0x00cffdd0b的地址是0x00cffdc4在调⽤Swap1函数时将a和b传递给了Swap1函数在Swap1函数内部创建了形参x和y接收a和b的值但是x的地址是0x00cffcecy的地址是0x00cffcf0x和y确实接收到了a和b的值不过x的地址和a的地址不⼀样y的地址和b的地址不⼀样相当于x和y是独⽴的空间那么在Swap1函数内部交换x和y的值⾃然不会影响a和b当Swap1函数调⽤结束后回到main函数a和b的没法交换。Swap1函数在使⽤的时候是把变量本⾝直接传递给了函数这种调⽤函数的⽅式我们之前在函数的时候就知道了这种叫传值调⽤。 结论实参传递给形参的时候形参会单独创建⼀份临时空间来接收实参对形参的修改不影响实 参。
所以Swap是失败的了。
那么这个时候就要搬出指针大哥在main函数中将a和b的地址传递给Swap函数Swap函数⾥边通过地址间接的操作main函数中的a和b像是把家地址搬到函数中直接改变家里的东西a, b的值。
代码展示
#includestdio.h
void Swap2(int*px, int*py)
{int tmp 0;tmp *px;*px *py;*py tmp;
}
int main()
{int a 0;int b 0;scanf(%d %d, a, b);printf(交换前a%d b%d\n, a, b);Swap1(a, b);printf(交换后a%d b%d\n, a, b);return 0;
}输出结果 我们可以看到实现成Swap2的⽅式顺利完成了任务这⾥调⽤Swap2函数的时候是将变量的地址传递给了函数这种函数调⽤⽅式叫传址调⽤。
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);return 0;
}输出结果
所以说数组名就是数组⾸元素(第⼀个元素)的地址。
但是有两个例外 • sizeof(数组名)sizeof中单独放数组名这⾥的数组名表⽰整个数组计算的是整个数组的⼤⼩ 单位是字节 • 数组名这⾥的数组名表⽰整个数组取出的是整个数组的地址整个数组的地址和数组⾸元素 的地址是有区别的 除此之外任何地⽅使⽤数组名数组名都表⽰⾸元素的地址。 还有一点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, arr1);printf(arr %p\n, arr);printf(arr1 %p\n, arr1);return 0;
}输出结果 这⾥我们发现arr[0]和arr[0]1相差4个字节arr和arr1 相差4个字节是因为arr[0] 和 arr 都是⾸元素的地址1就是跳过⼀个元素。 但是arr 和 arr1相差40个字节这就是因为arr是数组的地址1 操作是跳过整个数组的。到这⾥⼤家应该搞清楚数组名的意义了吧。
3. 使⽤指针访问数组
有了前面知识我们便可以使用指针访问数组啦其实数组也相当于指针如*p 1 arr[1],扩展 数组名arr是数组⾸元素的地址可以赋值给p其实数组名arr和p在这⾥是等价的。那我们可以使⽤arr[i]可以访问数组的元素那p[i]是否也可以访问数组呢
#include stdio.h
int main()
{int arr[10] {0};//输⼊int i 0;int sz sizeof(arr)/sizeof(arr[0]);//输⼊int* p arr;for(i0; isz; i){scanf(%d, pi);//scanf(%d, arri);//也可以这样写}//输出for(i0; isz; i){printf(%d , p[i]);}return 0;
}在第18⾏的地⽅将*(pi)换成p[i]也是能够正常打印的所以本质上p[i] 是等价于 *(pi)。
4 . 一维数组函数传参形本质
接下来进入重点⾸先从⼀个问题开始我们之前都是在函数外部计算数组的元素个数那我们可以把函数传给⼀个函数后函数内部求数组的元素个数吗
展示如下
#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;
}输出结果
很明显函数是没有正确获得数组元素个数的上面我们学习了数组名是数组⾸元素的地址那么在数组传的时候传递的是数组名也就是说本质上数组传参本质上传递的是数组⾸元素的地址。 所以函数形参的部分理论上应该使⽤指针变量来接收⾸元素的地址。 那么在函数内部我们写sizeof(arr) 计算的是⼀个地址的⼤⼩单位字节⽽不是数组的⼤⼩单位字节。正是因为函数的参数部分是本质是指针所以在函数内部是没办法求的数组元素个数的。 总结⼀维数组传参形参的部分可以写成数组的形式也可以写成指针的形式.
5. ⼆级指针 要理解如下
int main()
{int a 30;int * pa a;//取出a的地址 * 表示pa是指针指针的类型是int类型int * * ppa p;//ppa前的*表示ppa是指针指针的类型是int *类型
}2级指针的解引用 对上面案例分析像是扒白菜一样一层一层来如下展示
最终得到结果
总结2级指针是存放一级指针的地址
6. 指针数组
指针数组是存放指针的数组 结合如上知识那么指针是可以模拟数组的 扩展指针数组模拟⼆维数组
#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};int i 0;int j 0;for(i0; i3; i){for(j0; j5; j){printf(%d , parr[i][j]);}printf(\n);}return 0;
}图来展示
parr[i]是访问parr数组的元素parr[i]找到的数组元素指向了整型⼀维数组parr[i][j]就是整型⼀维数组中的元素。
但是并非是2维数组原因是模拟的数组并不连续而数组在内存上是连续存放的。
都看到这里了那就点个赞吧学习大家