当前位置: 首页 > news >正文

【C语言】指针初阶2.0版本

这篇博文我们来继续学习指针的其他内容

在这里插入图片描述

指针2.0

  • 传值调用与传址调用
    • 传值调用
    • 传址调用
  • 一维数组与指针
    • 理解数组名
    • 使用指针
    • 深入理解一维数组
  • 二级指针
  • 指针数组
  • 二维数组与指针

传值调用与传址调用

在开始之前,我们需要先了解这个概念,后面才能够正常的学习

传值调用

int add(int x, int y)
{return x + y;
}
int main()
{int a = 10;int b = 20;int c = add(a, b);printf("%d", c);return 0;
}

经典的传值调用,只需要传值即可,没有过多的要求,但如果我们的要求是将ab互换大小,再用这样的代码就行不通了

void ecn(int x, int y)
{int tmp = x;x = y;y = tmp;
}
int main()
{int a = 10;int b = 20;ecn(a, b);printf("a = %d\n", a);printf("b = %d\n", b);return 0;
}

在这里插入图片描述
我们发现,这样做交换不了两者的值,是因为形参是实参的一份临时拷贝,形参也是有地址的,改变形参影响不了实参,这时我们只能进行传址调用

传址调用

void ecn(int* x,int* y)
{int tmp = *x;*x = *y;*y = tmp;
}
int main()
{int a = 10;int b = 20;ecn(&a, &b);printf("a = %d\n", a);printf("b = %d\n", b);return 0;
}

在这里插入图片描述
这样就能进行调换了,改变实参的值

一维数组与指针

理解数组名

int arr[5] = {1,2,3,4,5};

当我们想要访问arr数组时,我们有一下几种方法

int i = arr[0];
int* p = &arr[0];
int* p = arr;

第一种不必多说,利用访问下标操作符对数组进行访问。第二、三种是我们上一篇文章说的(可移步上一篇:指针初阶),通过指针对数组进行访问,arr与&arr[0]是一样的,都是数组的首元素地址
那我们可能会有疑问了:那&arr是什么样的呢,跟这两个也一样吗?下面我们用编译器来测试下,顺便证明一下第二三种是一样的
打印它们的地址

#include <stdio.h>
int main()
{int arr[10] = { 1,2,3,4,5 };printf("&arr[0] = %p\n", &arr[0]);printf("arr =     %p\n", arr);printf("&arr =    %p\n", &arr);return 0;
}

在这里插入图片描述
我们发现它们的地址都是相同的,那它们都相同吗?我们再来看一下

#include <stdio.h>
int main()
{int arr[5] = { 1,2,3,4,5 };printf("%d\n", sizeof(arr));return 0;
}

在这里插入图片描述
如果它们都相同,那么sizeof(arr)与sizeof(arr【0】)应该相同,那应该在32位下为4,只有整个数组的大小才为20,这与我们之前所看到的相悖,我们最后来看一下区别在哪

#include <stdio.h>
int main()
{int arr[5] = { 1,2,3,4,5 };printf("&arr[0] =   %p\n", &arr[0]);printf("&arr[0]+1 = %p\n", &arr[0] + 1);printf("arr =       %p\n", arr);printf("arr+1 =     %p\n", arr + 1);printf("&arr =      %p\n", &arr);printf("&arr+1 =    %p\n", &arr + 1);return 0;
}

在这里插入图片描述
我们可以看到&arr+1跟另外两个不同,地址加了20,而另外两个加了4;正如我们所想,arr确实代表着一个数组,但&arr取的是首元素的地址,整个数组是一个整体

使用指针

#include <stdio.h>
int main()
{int arr[5] = { 0 };int i = 0;int sz = sizeof(arr) / sizeof(arr[0]);int* p = arr;for (i = 0; i < sz; i++){scanf("%d", p + i);}for (i = 0; i < sz; i++){printf("%d ", p[i]);//这里*(p+i)=p[i]}return 0;

数组元素的访问在编译器处理的时候转换成⾸元素的地址+偏移量求出元素的地址,然后解引⽤来访问。

深入理解一维数组

当我们写函数的时候,如果想要改变数组的内容:⼀维数组传参,形参的部分可以写成数组的形式,也可以写成指针的形式。
其实这个也是想当然的,因为数组可以用指针来表示,二者等同,那么取而代之肯定也是非常正确的,因为数组的本质就是指针

二级指针

二级指针的概念也很简单,就是存放一级指针的地址的指针

int main()
{int i = 10;int* pi = &i;int** ppi = &pi;return 0;
}
*ppi = pi;
**ppi = i;

同理,存放二级指针地址的就是三级指针

指针数组

指针数组就是存放指针的数组,里边每个元素都是地址

int* arr1;//里边的指针类型全部为int*
char* arr2;//里边的指针类型全部为char*

二维数组与指针

#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 };//我们一般把p作为指针变量,后面加上arr表示是数组指针变量,有关于数组指针变量的知识我们下期再分享int i = 0;int j = 0;for (i = 0; i < 3; i++){for (j = 0; j < 5; j++){printf("%d ", parr[i][j]);}printf("\n");}return 0;
}

我们看到很熟悉的parr[ i ][ j ]的形式,这其实就是二维数组的真正形态,在运行时二维数组也是要先变成指针的形式再进行运算的,所以说数组的本质是指针

这篇2.0就到这里了,感谢阅读
在这里插入图片描述

http://www.lryc.cn/news/308864.html

相关文章:

  • 小红书关键词爬虫
  • 网络爬虫的危害,如何有效的防止非法利用
  • 2024/2/29 备战蓝桥杯 6-1 二分
  • 浅析ARMv8体系结构:原子操作
  • 综合练习(二)
  • sql-labs第46关(order by盲注脚本)
  • 13款可以轻松上手画图软件推荐
  • vue实现商品评分效果(通过插件实现)
  • SpringBoot 手写 Starter
  • C++ 学习笔记(Structured bindings)
  • K8S常用kubectl命令汇总(持续更新中)
  • 加密和签名的区别及应用场景
  • 双非二本找实习前的准备day3
  • 又挖到宝了!国人团队研发的AI视频工具PixVerse,这么好用居然还完全免费!(强烈推荐)
  • 勒索病毒普通用户防范建议
  • Zabbix“专家坐诊”第231期问答
  • 【.NET Core】深入理解IO - FileSteam流
  • CentOS7 Mysql 忘记密码或临时密码进不去时怎么跳过密码进去然后再更改密码
  • 深度学习 精选笔记(8)梯度消失和梯度爆炸
  • linux操作docker
  • k8s Pod 进阶(资源限制,健康检查探针详解,启动退出,pod生命周期,)
  • SpringBoot整合ActiveMQ步骤
  • MySQL的单表和多表查询
  • 攻防世界例题wp
  • 仿牛客网项目---显示评论和添加评论功能的实现
  • idea集成git详解教程(实用篇)
  • 搭建LNMP环境并配置个人博客系统
  • 为什么网络安全缺口这么大,还是这么缺网络安全工程师?
  • 创新洞察|诺奖获得者埃德蒙·费尔普斯谈未来:中国创新从何而来?
  • SpringMVC 学习(六)之视图