C语言指针

2023-11-11

1、指针的概念

C程序中变量的值都是存储在计算机内存特定的储存单元中的,内存中的每个单元都有唯一的的地址,就像街区中的房子都有唯一的地址、宾馆中的房间都有唯一的编号一样。那么如何获取这个地址呢?这就要用到取地址运算符,即“&”。计算机把整个内存条分成一个个的小小的存储单元,每个存储单元都有一个唯一的地址。

定义:

类型关键字 *指针变量名 = &变量名;

内存中的地址都是按字节编号的,即内存中每个字节的存储单元都有一个唯一的地址,在程序编译或函数调用时,根据程序中定义的变量类型为变量分配相应字节数的存储空间。如图1.1所示。在内存中定义了一个变量i,再将i赋值为5,即i的内容中保存了一个5,对于这个内存位置在内存条中有一个唯一的编号去标志这一块内存区域,即地址0x0012 FF00。当定义了一个指针类型的变量时pi时,在内存条中也会去分配给它一个唯一的地址,在pi的内存区域中也存放了一个地址,这个地址就是变量i的地址。所以我们可以根据pi中存放的地址去寻找变量i的内容

图1.1

与图1.2所示,简单来说就是pi指向i的内存空间,i的内存空间存放的内容是5,pi的内存空间存放的是i的地址。

图1.2

2、指针访问

2.1、直接访问

当我们想使用指针时,我们可以直接利用变量的地址进行存储,在变量前加一个“&”,即取地址运算符

例如:

1> scanf("%d",&num);

首先找到变量num的起始地址,比如起始地址为10010;然后将键盘输入的值,比如3保存到10010开始的位置。此时,变量num在内存中的地址和值就为10010和3。

2> printf("num = %d\n",num);

首先找到变量num的起始地址10010,然后在10010开始的四个字节中取出值3,最后再将它输出。

2.2、间接访问  

间接访问是我们使用较多的一种方式,其访问方式就是通过指针取访问某一个变量的值。其指针就是存放其他变量的地址的一种特殊的变量。

例如:

int x = 10;

int *y = &x;

通过指针变量y存取变量x的值的过程如下:

首先找到指针变量y的地址,例如11001,读取y中保存的值,例如10010,(10010为变量x的地址);然后再从10010的起始位置读取四个字节的内容(10)。图解表达如图2.1所示

图2.1

程序示例:

#include "stdio.h"

int main()
{
	int x = 10;
	int *y = &x;

	printf("&x = %p\n",&x);
	printf("y = %p\n",y);
	
	return 0;
}

运行结果为:

&x = 000000000061FE14
y = 000000000061FE14

由此可以说明,y里面存储的是x的地址,也表明刚刚的图解是正确的。

3、指针变量和指针

3.1、指针变量和指针
  • 一个变量,保存的是另一个变量的地址的叫做指针变量。
  • 一个变量的地址称为该变量的“指针”。
  • 解析:地址1010110是变量x的地址(指针),指针变量p来存放x变量的地址,则p为指针变量,x的地址1010110称为指针。

用图可以表示为:

其中p为指针变量,保存的是x的地址1010110,x的地址1010110为指针,x为一个普通变量。

3.2、“&”和“*”的使用

当我们定义了一个变量x,即int x = 10;我们要定义一个指针指向x时,就写为int *y = &x;现在y中存的就是变量x的一个地址。当我们想要修改x的值时,我们可以直接在y的前面加一个*,即*y = 20,这样我们就可以通过指针去修改x的一个值,即*y等价于x。全部过程即为:

int x = 10;
int *y = &x;
*y = 20;
3.3、野指针

有如下代码,请问有什么问题?

#include "stdio.h"

int main()
{
	int x,*pi;

	*pi = 5;
	printf("%d,%d\n",x,*pi);
	
	return 0;
}

当我们运行这个代码时,编译器可能会在第七行进行报错。这是因为指针变量pi和变量x都没有初始化。因此指针变量pi的值在此处通常不可预知。语句*pi = 5;执行时将向一个位置不可预知的存储单元写入数据,这样的操作可能导致非法内存访问错误或者程序逻辑上的错误。右值为不属于程序所拥有存储单元的地址的指针变量称为“野指针”

4、指针案例

通过一个函数去交换两个变量的值。

#include "stdio.h"

void fun(int x,int y)
{
	int temp;

	temp = x;
	x = y;
	y = temp;

	printf("x = %d, y = %d\n",x,y);
}

int main()
{
	int x = 123;
	int y = 234;
	fun(x,y);
	printf("X_ = %d, Y_ = %d\n",x,y);
	
	return 0;
}

运行结果为:

x = 234, y = 123
X_ = 123, Y_ = 234

可以看到,因为x和y是一个形参,对于形参是实参的一个拷贝,所以只在fun()函数中对拷贝本进行了交换,但是不影响我们的一个变换,即这种方法是不可改变的。

该例我们传进去的是一个指针变量(地址),即int *x,int *y。这样我们在函数中对其进行了交换。

#include "stdio.h"

void fun(int *x,int *y)
{
	int temp;

	temp = *x;
	*x = *y;
	*y = temp;

	printf("x = %d, y = %d\n",*x,*y);
}

int main()
{
	int x = 123;
	int y = 234;
	printf("X_init = %d, Y_init = %d\n",x,y);
	fun(&x,&y);
	printf("X_ = %d, Y_ = %d\n",x,y);
	
	return 0;
}

运行结果为:

X_init = 123, Y_init = 234
x = 234, y = 123
X_ = 234, Y_ = 123

可以看到,x和y原来的值是123和234,运行fun()函数之后,x和y的值进行了改变,即x和y的值就变为234和123。

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

C语言指针 的相关文章

随机推荐

  • 视频点播服务器的配置如何选择,需要多大的带宽

    对于普通的企业网站 服务器带宽只需5M 10M 每天面对1w用户是没有问题的 图片网站 10M带宽可能只支持100 1k人 天访问 然后 如果是一个视频点播网站 服务器的带宽将增加几十倍 特别是对于视频点播服务器 瓶颈是带宽 视频点播服务器
  • 知识星球-伙伴匹配系统笔记2

    朋友伙伴匹配系统笔记2 1 前端整合路由 下载vue router 由于我们使用的是vue3 所以对应的是4版本的路由 npm install vue router 4 或者 yarn add vue router 4 如下图 前端整合路由
  • BootLoader介绍

    文章目录 一 BootLoader的引入 二 BootLoader的启动方式 三 BootLoader的结构和启动过程 四 自己写一个BootLoader 1 BootLoader第一阶段 2 BootLoader第二阶段 一 BootLo
  • Python爬虫常见HTTP状态码及解决方案

    爬虫工程师在数据采集过程中 不可避免地会遇到各种各样的问题 我们需要快速地对HTTP请求返回的各种异常状态码来判断处理 以便于我们及时调整爬虫策略 优化思路 及时完成作业 正常情况下 在使用代理IP时会出现以下错误状态码 一 代理链接失败
  • vue3使用高德地图,自定义点标记、默认点聚合样式、点击点标记获取信息

    1 需求 根据不用的类型和经纬度展示不同的自定义点标记 点标记太多 使用点聚合优化 参考 https blog csdn net qq 39157025 article details 120287561 2 在index html使用CD
  • Java学习笔记18——接口

    接口 接口概述 接口的特点 新建接口 创建一个实现类 Demo测试 总结 接口的成员特点 成员变量 构造方法 成员方法 类和接口的关系 类和类的关系 类和接口的关系 接口和接口之间的关系 抽象类与接口之间的区别 成员区别 关系区别 设计理念
  • c#基础知识---集合之队列

    队列 Queue 代表了一个先进先出的对象集合 当您需要对各项进行先进先出的访问时 则使用队列 当您在列表中添加一项 称为入队 当您从列表中移除一项时 称为出队 Queue 类的方法和属性 下表列出了 Queue 类的一些常用的 属性 属性
  • MySQL进阶(终篇)

    无知的我正在复习MySQL进阶知识 笔记特点是 我重新整理了涉及资料的一些语言描述 排版 而使用了自己比较容易理解的描述 同样是回答了一些常见关键问题 如果有遇到有任何无法进展问题或者疑惑的地方 应该在讨论区留言 或者 其他途径以寻求及时的
  • [开发工具使用基础-vs2013] 增加外部文件到项目工程

    此文适合于在vs2013中入门C 编程的人员借鉴 主要功能是添加外部文件 比如你网上下载的 cpp文件和 h头文件 到本项目工程 过程演示 1 新建一个C 空项目NewProgram 项目名自取 对于你的话就是你自己的项目了 完成后解决方案
  • Unity资源管理——使用UnityWebRequest从云端下载Assetbundle包

    1 环境 基于Unity2018 2 2 思路 1 使用UnityWebRequest Get方法去获取AB包 2 在协程中返回UnityWebRequest实例对象的SendWebRequest方法返回值 3 当UnityWebReque
  • wpf 保存图片到任意格式jpg,png,bmp

    private void ExportBtn Click object sender RoutedEventArgs e SaveFileDialog saveFileDialog new SaveFileDialog saveFileDi
  • nodejs中文教程-windows下nodejs开发环境的安装与配置

    么是Node js 还服务器端javascript 对于这个概念我在这篇文章不做解释 可以自己去搜索了解下 服务器端js不是新技术 只是最近的node js的火爆让他爆发了 我会在以后的文章里解释什么是node js 这里只是纯粹的搭建 连
  • HarmoneyOS鸿蒙系统零代码编程入门

    文章目录 前言 学习资源网址 工具以及基本环境准备 搭建HarmonyOS项目 申请成为华为开发者 实现 您好 世界 入门程序 前言 2021年6月3日 华为终于推出了HarmoneyOS 即鸿蒙操作系统公测 着实振奋人心 分布式操作系统
  • Linux学习篇 1.Linux的磁盘规划

    历时1个月的学习 对Linux终于小有了解 初步可以做些操作了 同时对Linux有了更深的理解 以前没接触的时候觉得高不可攀 经过一段时间的学习才发现 原来也没想象中的那么难 哈哈 独乐乐不如群乐乐 下面是我以做笔记的方式写的文章 有些生硬
  • 用py写一个时间盲注的脚本(初学向)

    用py写一个时间盲注的脚本 1 首先我们要清楚时间盲注的特点是利用了sql中sleep这个函数 借助的是响应时间不同来判断构造语句的对错 那么我们主要思路就要通过记录响应时间来执行一系列操作 下面是我写的一个简单脚本 2 import re
  • 告诉你如何应对HR索要薪资证明!

    有些企业的HR会要求求职者提供薪资证明 尤其是对于 骑驴找马 的求职者 HR不便于进行背景调查 更倾向于让求职者提供薪资证明 面对这种情况 根据前程无忧论坛的调查数据显示 有26 的受访者愿意提供薪资证明 其余的受访者要么拒绝提供 要么直接
  • 基于SpringBoot开发的停车位管理系统(调用百度地图api)

    文章目录 项目介绍 主要功能截图 前台 后台 部分代码展示 设计总结 项目获取方式 作者主页 超级无敌暴龙战士塔塔开 简介 Java领域优质创作者 简历模板 学习资料 面试题库 关注我 都给你 文末获取源码联系 项目介绍 基于SpringB
  • spring security免登录动态配置方案2

    序 之前有篇文章讲了怎么进行免登录动态配置的方案 动用了反射去实现 有点黑魔法的味道 这里再介绍另外一种方案 permitAll spring security config 4 2 3 RELEASE sources jar org sp
  • 巴菲特致股东的一封信:2011年

    原文请参考 http www berkshirehathaway com letters 2014ltr pdf 学习心得 全文如下 致伯克希尔哈萨维的股东 2011年我们的A股和B股每股账面价值增长了4 6 在过去47年 即现任管理层就职
  • C语言指针

    1 指针的概念 C程序中变量的值都是存储在计算机内存特定的储存单元中的 内存中的每个单元都有唯一的的地址 就像街区中的房子都有唯一的地址 宾馆中的房间都有唯一的编号一样 那么如何获取这个地址呢 这就要用到取地址运算符 即 计算机把整个内存条