C语言指针-什么是指针,如何引用指针

2023-10-27

C语言指针-什么是指针,如何引用指针

1.什么是指针

如果在程序中定义了一个变量,在对程序进行编译时,系统就会给这个变量分配内存单元,编译系统根据程序中定义的变量类型,分配一定长度的空间。内存区的每一个字节有一个编号,这就是“地址”,它相当于旅馆中的房间号,在地址所标志的内存单元中存放的数据则相当于旅馆房间中居住的旅客。

​ 通过地址就能找到所需的变量单元,可以说,地址指向该变量单元,将地址形象化的称为“指针”,意思是通过它(指针)能找到以他为地址的内存单元。

比如:一个房间的门口挂了一个房间号2008,这个2008它房间的地址,或者说2008指向“该房间”。

注意:

对不同类型的数据,在内存中分配的存储单元大小(字节数)和存储方式是不同的,例如:整数以补码形式存放,实数以指数形式存放,如果指定地址1010,希望从该单元中调出数据,虽然可以找到指定的存储单元,但是无法确定是从一个字节中取信息还是两个字节取信息。为了有效存取一个数据,除了知道位置信息外,还需要该数据的类型信息,地址包括内存编号和它所指向的数据的类型信息或者说它是带“类型的地址”。例如:int a;&a表示变量a的地址,确切的说它是整型变量a的地址。

例如:

int a,float b;
分配到2000开始的存储单元中,&a和&b的信息不完全相同
虽然存储单元编号相同,但是他们的数据类型是不一样的

2.存储单元的地址和内容

假设定义了整型变量i,j,k,20002003分配给i;20042007分配给j;2008~2011分配给k;

一般是通过变量名来引用变量的值printf(“%d\n”,i);

在编译的时候,系统分配4个字节给i,并建立了变量名和地址的对应表,因此在执行上面语句时,从该4个字节中按照整型数据的存储方式读出整型变量i的值,然后按十进制整数格式输出。

注意:对变量的访问都是通过地址进行的

2.1直接访问和间接访问

打一个比方:

为了打开一个A抽屉,有两种办法,方法1是将A钥匙带在身上,需要时直接找出该钥匙打开抽屉,取出所需的东西,这就是“直接访问”,方法2是,为了安全起见,将A钥匙放到另一个抽屉B中锁起来,如果需要打开A抽屉,就需要先找出B钥匙,打开B抽屉,取出A钥匙,在打开A抽屉,取出A抽屉中的东西,这就是“间接访问”。

直接按变量名进行的访问,称为“直接访问

依然是上面的例子,如果输入

printf("%d",&i);
//在执行时,把键盘输入的值送到地址为2000开始的整型存储单元中国
k = i + j;
//从2000~2003字节取出i的值,再从2004~2007取出j的值,相加后送到k所占用的2008~2011字节单元中

如果是将变量i的地址存放到另一个变量中,然后通过变量来找到变量i的值,从而访问i变量的方式称为“间接访问”。

用一个来存放整型变量的地址

i_pointer = &i;
//把i的地址(2000)存放到i_pointer中
//i_pointer的值就是2000(即是变量i所占用单元的起始地址)
//间接访问i的值:
先找到存在“变量i的地址”的变量i_pointer,从中取出i的地址,然后在2000字节开始的存储单元中取出i的值

在这里插入图片描述

为了表示将数值为3送到变量中,有两种方式

(1)直接访问:将3直接送到变量i所标识的单元中,如i=3。这是根据变量名直接向变量i赋值,由于变量名与变量的地址有一一对应的关系,就按此地址直接对变量i的存储单元进行访问。

(2)间接访问:将3送到变量i_pointer所指向的单元(即变量i的存储单元),例如“*i_pointer = 3”,其中 *i_pointer表示i_pointer指向的对象。

在这里插入图片描述

指向就是通过地址来体现的,假设i_pointer中的值是变量i的地址(2000),这样就在i_pointer和变量i之间建立一种联系,即通过i_pointer能知道i的地址,从而找到变量i的内存单元。

​ 由于通过地址就能找到所需的变量单元,因此说,地址指向该变量单元(如同一个房间号指向某一房间一样),将地址形象的称为“指针”。意思是通过指针就能找到以它为地址的内存单元(如同根据地址2000就能找到哦啊变量i的存储单元一样)。

​ 如果有一个变量专门用来存放另外一个变量的地址(即指针),则称它为“指针变量”,i_pointer就是一个指针变量。指针变量就是一个地址变量,用来存放地址,指针变量的值是地址(即指针)。

即:指针是一个地址,而指针变量是存放地址的变量

3.指针变量

指针变量的定义:

存放地址的变量是指针变量,它是用来指向另一个对象(如变量,数组,函数等)。

例如:通过指针变量访问整型变量

#include<stdio.h>
int main()
{
	int a=100,b=10;//定义整型变量a和b,并且初始化
    int *p1,*p2;//定义指向整型数据的指针变量p1和p2
    p1 = &a;//把变量a的地址赋给指针变量p1
    p2 = &b;//把变量b的地址赋给指针变量p2
    printf("a=%d,b=%d\n",a,b);//输出ab的值
    printf("*p1=%d,*p2=%d\n",*p1,*p2);//输出变量ab的值
    return 0}

"*"表示指向

"*p1"表示指针变量p1所指向的变量,也就是变量a,

*p2同理。

 int *p1,*p2;//表示定义了两个指针变量
   printf("*p1=%d,*p2=%d\n",*p1,*p2);//表示指针*p1和*p2所指向的变量

注意:

在定义指针变量的时候,一定要指定指针变量的类型。

在这里插入图片描述

3.1定义指针变量

形式:

类型名 *指针变量名;
例如:
    int *p1,*p2;
//int是指针的基本类型,表示指针变量可以指向的变量的类型。
//*p1和*p2可以指向整型的变量i和j,不能指向浮点类型的a和b

注意:

(1)*表示该变量为指针型变量

(2)定义指针变量时候必须指定类型,因为不同数据类型在内存中所占的字节数和存放方式是不一样的。

(3)一个变量的指针包含两个方面:一是以存储单元编号表示纯地址,一是它指向的存储单元的数据类型(int,char等)

(4)指向整形数据的指针类型表示为"int *",读作指向int的指针或者简称int指针,其他类型的同理。

(5)指针变量中只能存放地址指针,不要将一个整数赋给一个指针变量,因为从形式上看整数只能赋给整形变量,而不能赋给指针变量,地址只能用地址符号"&"得到并赋给一个指针变量例如:”p=&a“;

3.2引用指针变量

熟练掌握运算符

(1)&,取地址运算符,&a是变量a的地址

(2)*,指针运算符(间接访问运算符)

(3)*p表示指针变量p指向的对象

(1)给指针变量赋值

p=&a;
//把a的地址赋值给p,指针变量p的值是变量a的地址,p指向a

(2)引用指针变量指向的变量

p=&a;
printf("%d",*p);//以整数形式输出指针变量p所指向的变量的值,即变量a的值
*p=1;//把1赋给p当前所指向的变量,相当于把1赋给a,即a=1

(3)引用指针变量的值

p = &a;
printf("%o",p);//以八进制数形式输出指针变量p的值,即输出a的地址

3.3编程:输入两个a和b两个整数,按先大后小的顺序输出a和b

方法一:用指针的方法处理这个问题,不交换整型变量的值,而是交换两个指针变量的值

#include<stdio.h>
int main()
{
	int *p1,*p2,*p;//定义的三个int*类型的指针变量 
	int a,b;
	printf("please input two number:");
	scanf("%d%d",&a,&b);
	p1 = &a;//p1指向a的地址 
	p2 = &b;//p2指向b的地址 
	if(a<b)
	{
		p=p1;
		p1=p2;
		p2=p;
        //可以不用定义中间变量
        //p1=&b;p2=&a
	}
	printf("a=%d,b=%d\n",a,b);
	printf("max=%d,min=%d\n",*p1,*p2);
	return 0;
 } 

方法二:利用指针作为函数参数

#include<stdio.h>
void swap(int *p1,int *p2){
	int temp;
	temp = *p1;
	*p1 = *p2;
	*p2 =temp;
} 
int main(void)
{
	int a,b;
	printf("please input two number:");
	scanf("%d%d",&a,&b);
	int *p1,*p2;
	p1 = &a;//把a的地址赋给p1
	p2 = &b;//把b的地址赋给p2
	if(a<b)
	{
		swap(p1,p2);
	}
	printf("a=%d,b=%d\n",a,b);
	return 0;
}

注意:

void swap(int *p1,int *p2){
	int *temp;//没有初始化,是野指针
	*temp = *p1;
	p1 = *p2;//‘int *’ from ‘int类型不匹配
	p2 =*temp;
} 
void swap(int *p1,int *p2){
	int *temp=NULL;//error
    //改为:
    //int *temp=(int *)malloc(sizeof(int));
	*temp = *p1;
	*p1 = *p2;
	*p2 =*temp;
} 

指针定义为NULL的时候,表示为空指针,指向的是一个零地址,零地址是没有存储空间的,指针指向零地址是不可用的,读写都不能,也不能访问。

malloc是在堆区连续的开辟空间,空间可以赋初值为0,但是它就不叫0地址,空间连续后是可以用的,0地址是没有连续空间的,所以是不能用的。

void swap(int x,int y)
{
    int temp;
    temp = x;
    x=y;
    y=temp;
}

函数调用时,a的值传给x,b的值传给y,x和y的值是交换了,但是a和b的值是没有交换的,因为在函数结束的时候,x和y释放了,形参的值并没有改变实参

在这里插入图片描述

如何调用函数得到要改变的值:

①通过形参改变实参,使用指针变量

②设计的函数的形参为指针类型的

void swap(int *p1,int *p2){
	int *temp=(int *)malloc(sizeof(int));
	temp = p1; 
	p1 = p2;
	p2 =temp;
} 

,b的值传给y,x和y的值是交换了,但是a和b的值是没有交换的,因为在函数结束的时候,x和y释放了,形参的值并没有改变实参

[外链图片转存中…(img-hNXi52xQ-1660563958276)]

如何调用函数得到要改变的值:

①通过形参改变实参,使用指针变量

②设计的函数的形参为指针类型的

void swap(int *p1,int *p2){
	int *temp=(int *)malloc(sizeof(int));
	temp = p1; 
	p1 = p2;
	p2 =temp;
} 

实参变量和形参变量之间的数据传递是单向的“值传递”,用指针变量作为函数参数也应该遵从这一规则。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C语言指针-什么是指针,如何引用指针 的相关文章

  • 静态构造函数和 BeforeFieldInit?

    如果类型没有静态构造函数 则将执行字段初始值设定项 就在使用该类型之前 或者在某个时间点突发奇想 运行时 为什么这段代码 void Main start Dump Test EchoAndReturn Hello end Dump clas
  • 捕获 .aspx 和 .ascx 页面中的异常

    问题说明了一切 请看以下示例代码 ul li li ul
  • 如何使用 openSSL 函数验证 PEM 证书的密钥长度

    如何验证以这种方式生成的 PEM 证书的密钥长度 openssl genrsa des3 out server key 1024 openssl req new key server key out server csr cp server
  • strlen() 编译时优化

    前几天我发现你可以找到编译时strlen使用这样的东西 template
  • 在 Mono 中反序列化 JSON 数据

    使用 Monodroid 时 是否有一种简单的方法可以将简单的 JSON 字符串反序列化为 NET 对象 System Json 只提供序列化 不提供反序列化 我尝试过的各种第三方库都会导致 Mono Monodroid 出现问题 谢谢 f
  • 如何在 C# 中将 Json 转换为对象

    我想将 Json 转换为 C 中的对象 这里的 Json 是 值 e920ce0f e3f5 4c6f 8e3d d2fbc51990e4 如何使用 Object 问题看似愚蠢 但其实并不那么愚蠢 我没有简单的 Json 我有 IEnume
  • 如何向 Mono.ZeroConf 注册服务?

    我正在尝试测试 ZeroConf 示例http www mono project com Mono Zeroconf http www mono project com Mono Zeroconf 我正在运行 OpenSuse 11 和 M
  • 条件类型定义

    如果我有一小段这样的代码 template
  • 如何防止 Blazor NavLink 组件的默认导航

    从 Blazor 3 1 Preview 2 开始 应该可以防止默认导航行为 https devblogs microsoft com aspnet asp net core updates in net core 3 1 preview
  • 在 azure blob 存储中就地创建 zip 文件

    我将文件存储在 Blob 存储帐户内的一个容器中 我需要在第二个容器中创建一个 zip 文件 其中包含第一个容器中的文件 我有一个使用辅助角色和 DotNetZip 工作的解决方案 但由于 zip 文件的大小最终可能达到 1GB 我担心在进
  • Unity c# 四元数:将 y 轴与 z 轴交换

    我需要旋转一个对象以相对于现实世界进行精确旋转 因此调用Input gyro attitude返回表示设备位置的四元数 另一方面 这迫使我根据这个四元数作为默认旋转来计算每个旋转 将某些对象设置为朝上的简单方法如下 Vector3 up I
  • 让网络摄像头在 OpenCV 中工作

    我正在尝试让我的网络摄像头在 Windows 7 64 位中的 OpenCV 版本 2 2 中捕获视频 但是 我遇到了一些困难 OpenCV 附带的示例二进制文件都无法检测到我的网络摄像头 最近我发现这篇文章表明答案在于重新编译一个文件 o
  • 对于 C# Express 用户来说,有哪些好的工具可以识别可能重复的代码? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 也可以看看 有什么工具可以检查重复的 VB NET 代码吗 https stackoverflow c
  • 如何在多线程应用程序中安全地填充数据并 Refresh() DataGridView?

    我的应用程序有一个 DataGridView 对象和一个 MousePos 类型的列表 MousePos 是一个自定义类 它保存鼠标 X Y 坐标 类型为 Point 和该位置的运行计数 我有一个线程 System Timers Timer
  • SQLAPI++ 的免费替代品? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 是否有任何免费 也许是开源 的替代品SQLAPI http www sqlapi com 这个库看起来
  • 如何编写一个接受 int 或 float 的 C 函数?

    我想用 C 语言创建一个扩展 Python 的函数 该函数可以接受 float 或 int 类型的输入 所以基本上 我想要f 5 and f 5 5 成为可接受的输入 我认为我不能使用if PyArg ParseTuple args i v
  • 如何获取带有某个属性注释的所有属性?

    我刚刚从 Roslyn 开始 我想找到所有用属性名称 OneToOne 注释的属性 我启动了 SyntaxVisualizer 并能够获取对该节点的引用 但我想知道是否有更简单的方法来实现此目的 这就是我所拥有的 var prop docu
  • 如何组合两个 lambda [重复]

    这个问题在这里已经有答案了 可能的重复 在 C 中组合两个 lambda 表达式 https stackoverflow com questions 1717444 combining two lamba expressions in c
  • 从后面的代码添加外部 css 文件

    我有一个 CSS 文件 例如 SomeStyle css 我是否可以将此样式表文档从其代码隐藏应用到 aspx 页面 您可以将文字控件添加到标头控件中 Page Header Controls Add new System Web UI L
  • 如果找不到指定的图像文件,显示默认图像的最佳方式?

    我有一个普通的电子商务应用程序 我将 ITEM IMAGE NAME 存储在数据库中 有时经理会拼错图像名称 为了避免 丢失图像 IE 中的红色 X 每次显示产品列表时 我都会检查服务器中是否有与该产品相关的图像 如果该文件不存在 我会将其

随机推荐

  • 字符串压缩(小知识点)

    当对字符串进行修改的时候 需要使用 StringBuffer 和 StringBuilder 类 和 String 类不同的是 StringBuffer 和 StringBuilder 类 的对象能够被多次的修改 并且不产生新的未使用对象
  • Maven 项目的配置与程序的运行

    Maven 是一个 Java 包管理工具 需要下载和安装 通过配置 Maven 以后建立项目时就不需要再创建 lib 目录并导入相关的包 只需要在它的配置文件 pom xml 文件中进行包的配置 这样的配置方法提供了便利 大大节约了资源 在
  • Zookeeper入门

    Zookeeper概念 Zookeeper是一个开源的 分布式的项目 是apache的一个项目 从设计模式的角度理解 Zookeeper是基于观察者模式的 它负责存储大家都关心的数据 然后接受观察者的注册 一旦这些数据发生变化 则会通知已注
  • 华为OD机试 - 区块链文件转储系统(Java)

    题目描述 区块链底层存储是一个链式文件系统 由顺序的N个文件组成 每个文件的大小不一 依次为F1 F2 Fn 随着时间的推移 所占存储会越来越大 云平台考虑将区块链按文件转储到廉价的SATA盘 只有连续的区块链文件才能转储到SATA盘上 且
  • Unity Animation ---Unity中录制某个物体的运动到AnimationClip(一)

    在某些情况下 我们需要把物体的运动状态 材质变化等信息录制下来存储到Clip中 比如说 用到ITween DoTween等插件控制物体运动 然后想把运动的过程记录下来 就需要在Editor Runtime下进行一些操作来达到我们的目的 所幸
  • VsCode远程调试c++

    1 WSL安装 ubuntu18 04 或者直接连接远程的ubuntu服务器 windows10 安装WSL 参考文档 Install WSL Microsoft Docs 开始使用 WSL VS Code Microsoft Docs i
  • jq单击button修改input的value

    HTML代码 div 内容来源 div
  • 【深度学习】基于卷积神经网络(tensorflow)的人脸识别项目(二)

    活动地址 CSDN21天学习挑战赛 目录 前言 基本思路 关于环境 通过anaconda导入配置 数据集 训练集 验证机与测试集 划分规则 预处理 从指定路径读取训练数据 设置标签 按照指定图像大小调整尺寸 数据归一化 最值归一化 norm
  • 用户分享|当我升级了 CloudQuery 2.2.0 后......

    导读 7 月 13 日 CloudQuery 下文简称 CQ 2 2 0 版本正式发布 在看到官方文档对新版本的介绍后 马上进行安装测试 本文主要为大家介绍从 CQ 1 4 2 升级到 2 2 的考量因素 测试情况 分享一些实践经验 给大家
  • 十六种炫酷纯css加载动画(一)

    一个好的开篇 会给你这个项目增加不少分值 有没有遇到过打开页面加载一段时间 页面内容才加载出来 在等待加载的过程中页面却是空白页 给用户的体验特别不好 会让项目降一个档次 下面的十六种炫酷炸裂的css加载动画 会让你在等待的过程中 体验视觉
  • ISM解释结构模型法

    ISM解释结构模型法 并不知道是个啥 是风险分析方向的同学毕业要用到的 感觉不是很难 但是有着自己对应的原理 对于没有编程基础的同学来说可能有点难度 我也忘了数据从哪来的了 不过计算的过程是没错的 导入原始矩阵B B 0 0 0 0 0 1
  • 片上网络(1)概述

    前言 NoC On Chip Networks 片上网络 由于多核乃至众核时代的到来 用于连接它们的可扩展 低延迟 大带宽的通信结构变得至关重要 在核心较少时 总线Bus和矩阵 交叉开关Crossbar是主要的互联结构 总线可以提供较低的传
  • 【mktime】mktime函数使用

    函数原型 time t mktime struct tm 其中的 tm 结构体定义如下 struct tm int tm sec 秒 取值区间为 0 59 int tm min 分 取值区间为 0 59 int tm hour 时 取值区间
  • Toolchain的安装与验证(有图 ,超详细)

    安装包 链接 https pan baidu com s 1d1ihSB2LFzITyinVM m02A 提取码 1234 安装步骤 1解压安装包 2将解压后的文件放到与CMake同样的文件夹中 不放也可以 只要记住文件的位置 后续要用到
  • 01-Chrome架构:仅仅打开了1个页面,为什么有4个进程

    在开始之前 我们一起看下 Chrome打开一个页面需要启动多少进程 你可以点击Chrome浏览器右上角的 选项 菜单 选择 更多工具 子菜单 点击 任务管理器 这将打开Chrome的任务管理器的窗口 如下图 和Windows任务管理器一样
  • 服务的数据

    服务独立后 剩下的就是如何处理数据 1 规范化数据模型的问题 传统关系型数据库通过三大范式来约束数据存储 会使得查询涉及多关联 JOIN 时 查询性能严重低下 大量数据存储在一起 这种中心化思想 会造成访问瓶颈 可用性低 2 数据去中心化
  • physx转换矩阵终于正确了,哈哈,就是TMD太累

    从5月28日到8月27日晚上21 52 终于正确转换矩阵了 当然这只是个开端 恨不得吐槽 PHYSX太坑爹了 资料真TMD少 还得看文档 让爷过着苦逼的日子 这个苦逼日子只是开始不久 还远远没有结束 不过看到亮光了 上周连接后 发现不对 老
  • 湖南理工学院图像处理与计算机视觉,信息与通信工程一级学科硕士研究生培养方案...

    一 学科代码 0810 二 培养目标 适应社会主义现代化建设需要 培养德 智 体全面发展的高级专门人才 要求本学科硕士学位获得者达到如下目标 1 较好地掌握马克思主义基本理论 坚持四项基本原则 热爱祖国 遵纪守法 品德良好 学风严谨 具有较
  • RWKV解读:在Transformer的时代的新RNN

    转载地址 RWKV解读 在Transformer的时代的新RNN 知乎作者 徐传飞 在Transformer时代 介绍一个非Transformer架构的新网络 RWKV RWKV是一种创新的深度学习网络架构 它将Transformer与RN
  • C语言指针-什么是指针,如何引用指针

    C语言指针 什么是指针 如何引用指针 文章目录 C语言指针 什么是指针 如何引用指针 1 什么是指针 2 存储单元的地址和内容 2 1直接访问和间接访问 3 指针变量 3 1定义指针变量 3 2引用指针变量 3 3编程 输入两个a和b两个整