C语言之指针

目录

函数的参数

对象和地址

取地址运算符

注意

指针

注意

指针运算符

注意


在C语言中,指针是一个十分重要的概念,它的作用是“指示对象”。

例如:你要去一座公寓楼找一位朋友,公寓楼由很多楼层组成,每个楼层由若干个房间组成,而房间都有属于一个自己的编号,假如你不知对应的楼层的房间号,你需要一个一个房间去找,这是很麻烦的,而当你指定对应的房号时就能快速精准定位目标,而这里的房间号就对应为地址,也可以称为指针。


下面我们由一个例子来引出接下来我们所要学习的关于指针的基本知识:

函数的参数

#include<stdio.h>/*将n1和n2的和、差分别保存在sum、diff中(错误的示范)*/
void sum_diff(int n1, int n2, int sum, int diff)
{sum = n1 + n2;diff = (n1 - n2) ? n1 - n1:n2 - n1;
}
int main()
{int na, nb;int wa = 0, sa = 0;puts("请输入两个整数:");printf("整数A:");scanf("%d", &na);printf("整数B:");scanf("%d", &nb);sum_diff(na, nb, wa, sa);printf("两数之和是%d,两数之差是%d", wa, sa);return 0;
}

main函数在调用sum_diff函数时,实参na,nb,wa,sa的值会分别传递给形参n1,n2,sum,diff。这个复制的过程是单向的,这中参数传递方式称为值传递,这样即使改变形参sum,diff的值原来的wa,sa的值并不会改变。

因此在调用sum_diff函数之后,在main函数中wa,sa的值依然是0.

在前面的学习中,我们可以得知,函数返回到调用源的返回值只能有1个,不能返回到两个以上的值,所以不能将和、差返回给函数。

为了解决这个问题,必须掌握C语言学习的难点之一——指针(pointer)


对象和地址

变量是“保存数值的盒子”,它并不是像下图中随意存放的:

而是下面这样有序的存放在内存空间里:

变量具有多个侧面或者是属性,举例来说,其中一个属性就是数据类型长度,上面中的int型和double型的数据长度就不同,这两个变量的长度可以通过sizeof()求得。

有些编译器中sizeof(int)、sizeof(double)是相等的,但是构成它们的每一位却不尽相同

 数据类型决定变量可以表示数值范围,除此之外,表示变量在内存中生命期范围的存储期以及变量名也都是变量的重要属性。

在广阔的内存空间上,存在着很多对象,这就需要某种方式来表示各个对象在内存中存储的位置,这就是地址(address)

对象(变量)的地址是指其在内存中的存储编号,其中int型变量n的地址为212,double型变量x的地址为216。


取地址运算符

每个对象都有地址,那么我们来看下它们的地址是怎样的:

#include<stdio.h>int main()
{int    n;double x;int  a[3];printf("n的地址:%p\n", &n);      printf("x的地址:%p\n", &x);printf("a[0]的地址:%p\n", &a[0]);printf("a[1]的地址:%p\n", &a[1]);printf("a[2]的地址:%p\n", &a[2]);return 0;
}
/*n的地址:0061FECC
x的地址:0061FEC0
a[0]的地址:0061FEB4
a[1]的地址:0061FEB8
a[2]的地址:0061FEBC*/

对象的地址通常都是由十六进制数表示的,但是在不同的编译器下,有时结果也不相同。

我们一直使用的单目运算符&通常被称为取地址运算符(address operator),将&写在对象名之前就可以得到该对象的地址。

如果对象的长度为2,占用212号和213号的内存单元,那么该对象的地址就是它的首地址212号。

取地址运算符
  &a                                                       取得a的地址(生成指向a的指针)

注意

取地址运算符&的功能是取得对象的地址,表示对象地址的转换说明为%p(p为pointer的首字母)。


指针

只显示地址并无意思,让我来看看更具实际作用的功能吧:

#include<stdio.h>int main()
{int Lihua = 178;//李华的身高int Wangjun = 175;//王军的身高int Xiaoming = 179;//小明的身高int *honghong, *huahua;//红红、花花honghong = &Lihua;//honghong指向Lihua(喜欢李华)huahua = &Xiaoming;//huahua指向Xiaomingprintf("红红喜欢的人身高:%d\n", *honghong);printf("花花喜欢的人身高:%d\n", *huahua);honghong = &Wangjun;//honghong指向Wangjun(移情别恋)*huahua = 180;//将huahua指向的对象赋值为180(修改花花喜欢的人身高)putchar('\n');printf("李华的身高是:%d\n", Lihua );printf("王军的身高是:%d\n", Wangjun );printf("小明的身高是:%d\n", Xiaoming );printf("红红喜欢的人的身高是:%d\n", *honghong);printf("花花喜欢的人的身高是:%d\n", *huahua);return 0;
}

变量honghong和huahua的声明中,变量名前带有 * ,通过该声明定义了两个“指向int型变量的指针变量”,它们指向的是int型对象

我首先明确一下“int型变量”和“指向int型变量的指针变量”有何区别:

☛int型变量:保存“整数”盒子

☛指向int型变量的指针变量:保存“存放整数对象的地址”的盒子

我们以下图为例:

int型Lihua的地址是212号,因此若执行“honghong = &Lihua”,honghong中就会被存入212号,这是honghong和Lihua的关系就是honghong指向lihua

当指针p的值为对象x的地址时,一般说“p”指向“x”。

honghong的数据类型是“指向int型变量的指针型”

honghong = &Lihua;

&Lihua的类型也是“指向int型变量的指针”,取地址运算符与其说时取得地址,不如说是生成指针。

表达式&Lihua是指向Lihua的指针,其值为Lihua的地址。

注意

将取地址运算符&写在Type型对象x前得到的&x为Type *指针,其值为x的地址。


指针运算符

在进行显示的地方,就要用到指针运算符(也称为间接访问运算符)的单目运算符 * (unary operator)。将指针运算符*写于指针之前,就可以显示该指针指向的对象内容。

指针运算符
*a                                          a指向的对象
#include<stdio.h>int main()
{int a = 10;int *pa = &a; *pa = 20;	printf("%d", a);return 0;
}

在这里*pa就存放变量a的地址,就相当于“pa指向的对象”,因此*pa就是变量a的别名,所以改动*pa存放地址的值,也就相当于改动了a的值。

注意

当pa指向a时,*pa就是变量a的别名。


指针在C语言中是十分重要的,但是不难理解:指针就相当于一个门牌号方便与从内存单元中查找,而形如int *a;的形式 *a指的是指针型变量,而加上int就是创造了一个保存对象地址的变量,而取得地址的指针型变量就相当于该地址所在变量的分身。

相信大家只要用心梳理几遍就可以明了了。在下面的学习中我们还将会学习关于函数、数组与指针的关系。

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

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

相关文章

十八、本地配置Hive

1、配置MYSQL mysql> alter user rootlocalhost identified by Yang3135989009; Query OK, 0 rows affected (0.00 sec)mysql> grant all on *.* to root%; Query OK, 0 rows affected (0.00 sec)mysql> flush privileges; Query OK, 0 rows affected (0.01 sec)2、…

GO设计模式——18、迭代器模式(行为型)

目录 迭代器模式&#xff08;Iterator Pattern&#xff09; 迭代器模式的核心角色&#xff1a; 优缺点 使用场景 代码实现 迭代器模式&#xff08;Iterator Pattern&#xff09; 迭代器模式&#xff08;Iterator Pattern&#xff09;提供了一种统一的方式来访问一个容器对…

P1614 爱与愁的心痛

P1614 爱与愁的心痛 [P1614 爱与愁的心痛](https://www.luogu.com.cn/problem/P1614?contestId150480 P1614 爱与愁的心痛 题意 最近有 n 个不爽的事&#xff0c;每句话都有一个正整数刺痛值&#xff08;心理承受力极差&#xff09;。想知道连续 m 个刺痛值的和的最小值是多…

打造高效接口测试:专栏介绍

在软件开发过程中&#xff0c;接口测试是非常重要的一环。它可以帮助我们确保系统的各个模块之间的交互是否正常&#xff0c;从而提高软件的质量和稳定性。本文将介绍如何使用Python编写一个自动化接口测试框架&#xff0c;包括框架对比、接口测试框架介绍、接口测试框架流程和…

原理图中VCC、VDD、VEE、VSS、VBAT各表示什么意思

一、名词解析 &#xff08;1&#xff09;VCC&#xff1a;Ccircuit 表示电路的意思, 即接入电路的电压 &#xff08;2&#xff09;VDD&#xff1a;Ddevice 表示器件的意思, 即器件内部的工作电压; &#xff08;3&#xff09;VSS&#xff1a;Sseries 表示公共连接的意思&#…

使用html+css+js+three.js写圣诞树

实现效果&#xff1a; <head><meta charset"UTF-8"><title>Musical Christmas Lights</title><link rel"stylesheet" href"https://cdnjs.cloudflare.com/ajax/libs/normalize/5.0.0/normalize.min.css"><sty…

网络编程:多进程和多线程编程

1. 多进程编程 1.1 fork #include <sys/types.h> #include <unistd.h> // 调用失败返回 -1 设置 errno pid_t fork( void );子进程返回 0&#xff0c;父进程返回子进程 PID&#xff1b; 信号位图被清除&#xff08;父进程的信号处理函数不再对新进程起作用&…

【网络编程】网络通信基础——简述TCP/IP协议

个人主页&#xff1a;兜里有颗棉花糖 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 兜里有颗棉花糖 原创 收录于专栏【网络编程】【Java系列】 本专栏旨在分享学习网络编程的一点学习心得&#xff0c;欢迎大家在评论区交流讨论&#x1f48c; 目录 一、ip地…

sql_lab之sqli中的报错注入,less13

报错注入&#xff08;less-13&#xff09; 正常报错注入&#xff1a; 1.输入用户名和密码123 123显示登录错误 2.输入用户名和密码123’ 123显示登录错误 123后面有’)说明是’)注入 3.查询数据库名 1) and updatexml(<a><b></b></a>,concat(1111…

大数据知识图谱解码:从核心概念到技术实战

文章目录 大数据知识图谱解码&#xff1a;从核心概念到技术实战1. 概述什么是知识图谱知识图谱与自然语言处理的关系 2. 发展历程语义网络本体论大数据时代的知识图谱知识图谱与深度学习的融合 3. 研究内容知识图谱的建模与表示知识抽取知识图谱的融合与对齐知识图谱的推理知识…

KMP入门级别算法详解--终于解决了(next数组详解)

对于正常的字符串模式匹配&#xff0c;主串长度为m&#xff0c;子串为n&#xff0c;时间复杂度会到达O&#xff08;m*n&#xff09;&#xff0c;而如果用KMP算法&#xff0c;复杂度将会减少线型时间O&#xff08;mn&#xff09;。 设主串为ptr"ababaaababaa";&#…

Prometheus介绍和安装

Prometheus介绍和安装 1. Prometheus介绍 Prometheus&#xff08;普罗米修斯&#xff09;是一个最初在SoundCloud上构建的监控系统。自2012年成为社区开源项目&#xff0c;拥有非常活跃的开发人员和用户社区。为强调开源及独立维护&#xff0c;Prometheus于2016年加入云原生云…

P4 音频知识点——PCM音频原始数据

目录 前言 01 PCM音频原始数据 1.1 频率 1.2 振幅&#xff1a; 1.3 比特率 1.4 采样 1.5 量化 1.6 编码 02. PCM数据有以下重要的参数&#xff1a; 采样率&#xff1a; 采集深度 通道数 ​​​​​​​ PCM比特率 ​​​​​​​ PCM文件大小计算&#xff1a; ​…

[THUPC 2024 初赛] 二进制 (树状数组单点删除+单点查询)(双堆模拟set)

题解 题目本身不难想 首先注意到所有查询的序列长度都是小于logn级别的 我们可以枚举序列长度len&#xff0c;然后用类似滑动窗口的方法&#xff0c;一次性预处理出每种字串的所有出现位置&#xff0c;也就是开N个set去维护所有的位置。预处理会进行O(logn)轮&#xff0c;每…

KubeSphere金丝雀发布流量分布调节不生效(将所有流量按比例分配给灰度发布版本)

如题 金丝雀发布按照流量比例访问不能生效 1、自制应用生成的路由添加注释: nginx.ingress.kubernetes.io/service-upstream:"true" 2、项目网关开启 3、完成 以上&#xff0c;祝好。

什么是SpringMVC

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 SpringMVC之参数获取 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 系列文章目录前言一、概念二、Spring…

Tomcat远程调试

windows环境 写一个 startup-debug.bat&#xff0c;指定tomcat的根目录&#xff0c;端口自己定义 rem *******设置Tomcat目录*******-- set CATALINE_HOMED:\asd\A8-2\tomcat d: rem 8787为可用端口,为远程调试监听端口-- cd %CATALINE_HOME%/bin set JPDA_ADDRESS8787 set J…

5G核心网小百科:解锁数字未来的神奇密码

引言&#xff1a; 嘿&#xff0c;大家好&#xff01;今天我们要揭开一个数字魔法的奥秘&#xff0c;那就是5G核心网。这个网络的核心部分&#xff0c;其实蕴含了很多神奇的技术&#xff0c;它们如何点亮我们的数字未来呢&#xff1f;让我们一探究竟。 1. 服务化架构&#xff1…

IDEA必备常用快捷键

IDEA必备常用快捷键 Ctrl 快捷键介绍Ctrl F在当前文件进行文本查找Ctrl R在当前文件进行文本替换Ctrl Z撤销Ctrl Y删除光标所在行或者删除选中的行Ctrl D复制光标所在的行或者复制选中的内容,并把复制内容插到光标位置的下面Ctrl C复制光标所在的行或者复制选中的内容C…

Leetcode—445.两数相加II【中等】

2023每日刷题&#xff08;六十七&#xff09; Leetcode—445.两数相加II 实现代码 /*** Definition for singly-linked list.* struct ListNode {* int val;* struct ListNode *next;* };*/struct ListNode* addTwoNumbers(struct ListNode* l1, struct ListNode* l2…