指针【理论知识速成】(3)

一.指针的使用和传值调用:

在了解指针的传址调用前,先来额外了解一下 “传值调用”

1.传值调用:

对于来看这个帖子的你相信代码展示胜过千言万语

#include <stdio.h>
#include<assert.h>
int convert(int a, int b)
{int c= 0;c = a;a = b;b = c;return(a, b);
}
int main()
{int x = 0;int y = 30;convert(x, y);printf("x=%d y=%d", x, y);return 0;
}
//输出结果依然为x=0,y=30;

那为什么通过函数调用最终x,y的结果依然没有被改变?因为在调用时形参a,b也会单独开辟一块新的空间,a与x之间与b同y之间依旧相互独立,所以a是a,x是x,同理b是b,y是y,a只是继承了x的数值而已,b 也只是继承了y的数值而已。所以传值调用的定义就把变量本身传递给了函数
那如果想通过函数调用改变x,y又该怎么办呢?接下来就需要了解传址调用啦

2.传址调用:

同样的定义来之前先将代码呈上

#include <stdio.h>
#include<assert.h>
int convert(int * a, int * b)
{int c= 0;c = *a;*a = *b;*b = c;return(*a, *b);
}
int main()
{int x = 0;int y = 30;convert(&x, &y);printf("x=%d y=%d", x, y);return 0;
}
//输出结果为x=30,y=0;

此代码不同于上一代码,此码将x,y的地址通过指针传递到函数convert中,成功调换了x,y的值。所以将变量的地址传递给函数,就叫做传址调用
。#### 3.传值调用传址调用分别在何种情况下使用:
了解了传值调用与传址调用后那么在何种情况下使用传址调用,又该在何种情况下使用传值调用呢?

答:在不需要改变变量本身时可采用传值调用,否则采用传址调用。

二.指针和数组的关系

前面提到过指针可以用来查询地址,int *p=arr, *p=arr[0],又提到过指针类型的作用,即为指针+1时所跳过的字节数,这一块则是在细致的讲指针如何遍历数组

1.数组名的理解

int main()
{int arr[] = { 1,2,3,4 ,5};printf("%p ", arr);printf("%p ", &arr);printf("%p ", &arr[0]);printf("%p ", sizeof(arr));return 0;
}

输出结果:

在这里插入图片描述

由此可看到上述四组输出arr,&arr,&arr[0],都指向了同一地址,是不是证明三种指针完全性等,事实真的是这样嘛,再来看一组代码

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

输出结果:
在这里插入图片描述
在上述结果中arr与arr[0]在+1后也指向同一地址,而&arr,则指向了其它区域,经过计算发现arr与arr[0]+1跳过的字节长度为一个元素,而&arr+1跳过的长度为一个数组,综上可以确定arr与arr[0]是完全相等的,指向的位置为元素的首地址,但同样有例外**&arr取的就是整个元素的地址,除此之外sizeof(arr)取的也是整个元素的地址**。

2.使用指针访问数组

#include<stdio.h>
int main()
{int arr[10] = {};int* p = arr;int j = 0;int sz = sizeof(arr) / sizeof(arr[0]);for (j = 0; j < sz; j++){scanf("%d", p + j);}for (j = 0; j < sz; j++){printf("%d", p + j);//将p+j改为p[j],也完全可以,结果不会产生改变}return 0;
}

3.一维数组传参的本质

数组在传参的时候所传的是数组首元素的地址

#include<stdio.h>
int print(int arr[])//传递的其实是一个指针
{int sz = sizeof(arr) / sizeof(arr[0]);//这里算的是指针的大小比上元素个数的大小printf("s=%d", sz);return 0;
}
int main()
{int arr[10] = {};print(arr);return 0;
}
//程序的输出结果在x64的环境下为2,x86为1.

二.二维指针

在正式了解二维指针前,可以先联想“二维数组”,二维数组的定义就是以一维数组为元素组成的数组,可推测二维指针大概意思是指向一维指针的指针就叫做二维指针。
在这里插入图片描述

1.代码表示:

int *p=0;//此为一维指针
int ** pp=0;//此为指向一维数组*p,的二维指针*pp(二维指针的名称不一定和一维指针的名称有关系)

2.组成:

在这里插入图片描述
不要把二维指针想的过于复杂,其实*p也就是一个指针变量

3.作用:

二维指针可以通过查询一维指针指向的地址,寻找到变量

#include<stdio.h>
int main()
{int a = 0;int* p = &a;int** q = &p;printf("%d", **q);return 0;
}
//输出结果为0

三.指针数组

同样的在了解指针数组前先联想“整型数组”,没错指针数组就是由指针组成的数组,就是这么好懂
在这里插入图片描述

1.表示方式以及组成:

int arr[]={1,2,3,4};//这个是整型数组,int 表示的就是数组元素的类型是int 
int * arr[]={arr,arr1,arr2}//这个是指针数组,int *表示的就是数组元素类型是int *

2.:指针数组模拟二维数组:

#include<stdio.h>
int main()
{int arr[] = { 1,2,3 };int arr1[] = { 2,3,4 };int arr2[] = { 3,4,5 };int* a[] = { arr,arr1,arr2 };int i, j;for (i = 0; i < 3; i++){for (j = 0; j < 3; j++){printf("%d ", a[i][j]);//也可以写成*(*(a[i])+j)}printf("%d\n");}return 0;
}

注:二维数组中的每个元素都是连续存放的,而指针数组中的每个元素并不确保是连续存放

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/535326.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Python】python实现Apriori算法和FP-growth算法(附源代码)

使用一种你熟悉的程序设计语言&#xff0c;实现&#xff08;1&#xff09;Apriori算法和&#xff08;2&#xff09;FP-growth算法。 目录 1、Apriori算法2、F-Growth算法3、两种算法比较 1、Apriori算法 def item(dataset): # 求第一次扫描数据库后的 候选集&#xff0c;&am…

OpenCASCADE开发指南<四>:OCC 数据类型和句柄

一个软件首先要规定能处理的数据类型&#xff0c; 其次要实现三项最基本的功能——引用管理、内存管理和异常管理。在 OCC 中&#xff0c;这三项功能分别对应基础类中的句柄、内存管理器和异常类。 1 数据类型 在基本概念篇里&#xff0c;已经介绍了 OCC 数据类型的分类&…

Linux:好用的Linux指令

进程的Linux指令 1.查看进程信息 ​​​​ps ajx | head -1 && ps ajx | grep 进程名创建一个进程后输入上述代码&#xff0c;会打印进程信息&#xff0c;当我们在code.exe中写入打印pid&#xff0c;ppid&#xff0c;这里也和进程信息一致。 while :; do ps ajx | he…

Python语言在编程业界的地位——《跟老吕学Python编程》附录资料

Python语言在编程业界的地位——《跟老吕学Python编程》附录资料 ⭐️Python语言在编程业界的地位2024年3月编程语言排行榜&#xff08;TIOBE前十&#xff09; ⭐️Python开发语言开发环境介绍1.**IDLE**2.⭐️PyCharm3.**Anaconda**4.**Jupyter Notebook**5.**Sublime Text** …

机器学习——过拟合问题、正则化解决法

过拟合的基本概念 欠拟合&#xff1a;假设函数没有很好的拟合训练集数据&#xff0c;也称这个假设函数有高偏差&#xff1b; 过拟合&#xff1a;过拟合也称为高方差。在假设函数中添加高阶多项式&#xff0c;让假设函数几乎能完美的拟合每个样本数据点&#xff0c;这看起来很…

使用ubuntu搭建hadoop伪分布全过程图解

目录 1. 安装jdk 2. 添加java环境变量 3. 设置免密登录 4. 安装hadoop 5. 添加hadoop环境变量 6. 修改hdoop-env.sh文件 7. 修改core-site.xml文件 8. 修改yarn-site.xml文件 9. 修改mapred-site.xml文件 10. 修改hdfs-site.xml文件 11. 进行授权 12. 创建namenode…

【论文精读】Transformer:Attention Is All You Need

《动手学深度学习》关于Transformer和注意力机制的笔记 李沐《动手学深度学习》注意力机制 文章目录 《动手学深度学习》关于Transformer和注意力机制的笔记一、文章概览&#xff08;一&#xff09;摘要&#xff08;二&#xff09;结论部分&#xff08;三&#xff09;引言&am…

java基础2-常用API

常用API Math类 帮助我们进行数学计算的工具类。 里面的方法都是静态的。 3.常见方法如下&#xff1a; abs:获取绝对值 absExact:获取绝对值 ceil:向上取整 floor:向下取整 round:四舍五入 max:获取最大值 …

第十四届蓝桥杯蜗牛

蜗牛 线性dp 目录 蜗牛 线性dp 先求到达竹竿底部的状态转移方程 求蜗牛到达第i根竹竿的传送门入口的最短时间​编辑 题目链接&#xff1a;蓝桥杯2023年第十四届省赛真题-蜗牛 - C语言网 关键在于建立数组将竹竿上的每个状态量表示出来&#xff0c;并分析出状态转移方程 in…

游泳防水耳机排名,高性价比国际游泳耳机品牌排行榜前十名

随着科技的飞速发展&#xff0c;运动游泳耳机已经成为当代运动时尚和游泳爱好者的必备装备之一。在游泳训练或是户外运动时&#xff0c;一款高性价比的游泳耳机不仅能带给我们高品质的音乐体验&#xff0c;还能有效防水防汗&#xff0c;陪伴我们享受运动带来的乐趣。为了帮助大…

视频素材网站哪个好?推荐几个高清无水印的短视频素材网

小伙伴们&#xff0c;如果你也是短视频的狂热爱好者&#xff0c;想要制作出优质满分的短视频作品&#xff0c;但苦于不知道从哪儿搞来那些高清无水印的素材&#xff0c;那今天你就来对地方啦&#xff01;我这里有几个绝佳的素材网站推荐给你&#xff0c;让你的创作源源不断。 …

Kamailio的SIP服务的性能

官方的性能报告&#xff1a; Kamailio (OpenSER) 1.2.0 - Transaction Module and User Location Performance Tests 如下的提取的性能参数也是基于官方的性能报告&#xff0c;信令走的UDP&#xff0c;作为做系统方案的参照&#xff0c;Kamailio的性能还是非常&#xff0c;非常…