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

Linux系统中指针的详细分析与操作

 

文章目录

一、指针

二、指针的初始化

三、指针的运算

四、指针与数组

五、指针与字符串

六、函数指针

七、NULL 指针

八、对复杂指针的解释

C 语言指针真正精髓的地方在于指针可以进行加减法,这一点极大的提升了程序的对指针使用的灵活性,同时也带来了不小的学习负担。正是因为 C 语言指针可运算,才奠定了如今 C 语言的地位。

一、指针

对于内存,我们可以简单地认为它就是大小相同、连续排布的格子,每一个格子的大小为一字节。为了更方便地找到某一个格子,我们通过对内存进行编号,通过编号来找到某一个具体的内存格子。


这样的编号通常称之为内存地址,如果程序想要获取某一块内存存放的数据,必须通过内存地址定位,再取出对应内存的数据。

 

一个指针变量存储着另一块内存的起始地址,相较于直接寻址的方式,如果想要通过一个指针获取指向的内存变量的话,首先需要获取到指针变量存储的内存地址,再通过这个地址来获取变量,所以这种方式又称为间接寻址。

在 C 函数实现中,所传入的参数均为原有变量的一个拷贝,在函数中对参数进行修改是无法影响到原有变量的值的,若需要对参数进行修改,可向函数传递该变量的内存地址。如此一来,即使对参数(地址)进行了拷贝,也可以通过地址对其进行修改,而变量的地址就保存在指针当中。


二、指针的初始化

操作符 &表示取一个变量的地址,并将该地址赋给变量 pointer,由此一来指针中的地址就是正确且合法的。

void main() {int number = 100;int *pointer;pointer = &number;
}

三、指针的运算

C 语言中的指针支持运算,不过仅支持加减法,并不支持乘除法。在前面我们已经提到过了,一元运算符 * 表示间接寻址,即取出指针的地址,根据该地址找到指针指向的变量。而对于指针的加减法而言,与指针指向的类型密切相关。


可以看到,对一个指向 int 的指针加 1,其地址增加了 4,正好是一个整型的大小。其原因在于如果仅仅是增加 1 的话,那么指针将会指向该整型的第二个字节,那么此时指针所指向的“整型”值将会变得非常奇怪,因为最后一个字节是其它数据的。


 

四、指针与数组

我们经常听到数组名称其实就是一个指针,数组名表示数组的首地址。但是这并不正确,数组名称和指针绝不等价,我们可以认为数组名称具有指针的特性,但不能说数组和指针等价。一个最为典型的例子就是使用 sizeof 求数组的长度。

#include <stdio.h>void main() {int number[] = {1, 2, 3};int *pointer = number;printf("number's size: %ld \n", sizeof(number));printf("pointer's size: %ld \n", sizeof(pointer));
}// number's size: 12 
// pointer's size: 4 

在上述代码中我们明确地表示了 number 是一个整型数组,表示整型的集合,所以 sizeof 的结果为数组占用内存的总大小。而 pointer 仅仅只是一个整型指针,编译器并不知道它到底是指向一个整型,还是一坨整型,那么 sizeof 的结果自然而然的是指针占用内存空间的大小。

所以,数组名称所代表的含义要高于指针,但是这并不改变数组名是一个指针的事实。数组在内存中连续分布,再结合前面所提到的指针的运算,使得我们可以通过指针的方式访问数组中的元素。


五、指针与字符串

C 语言中字符串并非像其它语言一样,将其设置为基本数据类型,而是构建于数组之上,并在数组末尾添加 \0 表示结尾,这也是为什么数组和字符串经常成对出现的原因。

int main() {char *hello = {"Hello"};char world[] = {"World"};printf("hello: %s \n", hello);printf("world: %s \n", world);
}

如上述代码所示,我们既可以使用数组初始化一个字符串,也可以使用字符指针来初始化一个字符串,只不过使用字符指针初始化的字符串具有只读特性,使用数组初始化的字符串具有读写特性。


六、函数指针

在函数式编程中我们经常需要将一个函数作为参数传递给另外一个函数,其中比较经典的例子线程的创建与执行。不同于 fork 或者 vfork 调用,pthread_create 调用以一个函数指针作为参数,创建的线程转而执行该函数。

int filterArray(int *array, int size);

上述代码是一个简单的函数原型,接收一个整型数组和其长度,并返回一个整型。一个函数总是占用一段连续的内存区域,函数名称在某些情况下会被转换成该函数所在内存区域的首地址,这一点和数组非常的相似。也就是说,函数名称 filterArray 可以被替换成 (*pointerName),这样一来就得到了一个指向函数入口的指针:

int (*pointerName)(int *array, int size);

所以,函数指针其实就是对函数原型的稍加修改而已。


七、NULL 指针

标准定义了 NULL 指针,它作为一个特殊的指针变量,表示不指向任何东西,当我们在定义一个指针变量,并且不知道该指针指向何处时,就应该将其初始化为 NULL。其次,当我们使用 free 函数释放堆内存时,也应该将指针指向为NULL,防止出现内存访问错误。

#include <stdlib.h>int main() {char *s = NULL;s = (char *)malloc(sizeof(char) * 5);strcpy(s, "hello");free(s);s = NULL;return 0;
}

NULL 指针进行解引用是非法的,因为 NULL指针从定义上来看不指向任何东西。因此,当我们对指针进行解引用时应该对其进行检查,能显著减少 DEBUG 的时间。


八、对复杂指针的解释

有时候我们会看到诸如 char *(*name[124])(int **p) 这种看起来非常复杂的指针,对于此类复杂指针,我们只需要牢记两个关键点即可。

  • 对于一个符号定义而言,找到其名称,然后再按照优先级顺序进行解析。

  • 牢记 C 语言中操作符的优先级。

操作符描述
()聚组,例如5 / (2 + 3),和数学中的()语义相同
()函数调用,例如 3 + foo(),首先调用函数,而后执行加法操作
[]下标引用,例如 foo()[2],首先调用函数,根据函数返回的结果进行下标引用
.访问结构体成员,如 student[1].name 首先获取数组索引为1的元素,而后访问name成员
->访问结构指针成员,和 . 作用相同
++后缀自增,如 struct.name++,首先获取结构体成员再对其进行自增
后缀自减,同后缀自增
!逻辑反
~按位取反
++前缀自增
前缀自减
*间接访问,如 *p++ 首先对指针 p 进行自增,然后对自增后的指针进行间接访问
&取变量地址

可以看到,* 间接访问操作的优先级要远远低于()[]++ 以及 . 等常用操作符,也就是说,* 在复杂指针中就是个弟弟。

接下来就对 char *(*name[124])(int **p) 这个指针做一个具体的分析。首先得找到变量名称,上面有两个: name 以及 p,结合外面两对括号可知这是个函数指针,p 为函数参数。再来看 *name[124][]的优先级高于 *,所以 name 是一个数组,数组中保存了某种类型的指针。将所有的信息整合起来,就可以得到:name 是一个指针数组,保存了原型为 char *funcName(int **p) 的函数指针。

相关文章:

Linux系统中指针的详细分析与操作

文章目录 一、指针 二、指针的初始化 三、指针的运算 四、指针与数组 五、指针与字符串 六、函数指针 七、NULL 指针 八、对复杂指针的解释 C 语言指针真正精髓的地方在于指针可以进行加减法&#xff0c;这一点极大的提升了程序的对指针使用的灵活性&#xff0c;同时也…...

工程(十一)——NUC11+D435i+VINS-FUSION+ESDF建图(github代码)

博主的合并代码gitgithub.com:huashu996/VINS-FUSION-ESDFmap.git一、D435i深度相机配置1.1 SDKROS参考我之前的博客&#xff0c;步骤和所遇见的问题已经写的很详细了https://blog.csdn.net/HUASHUDEYANJING/article/details/129323834?spm1001.2014.3001.55011.2 相机标定参数…...

第十四届蓝桥杯三月真题刷题训练——第 4 天

目录 题目 1 &#xff1a;九数算式_dfs回溯(全排列) 题目描述 运行限制 代码&#xff1a; 题目2&#xff1a;完全平方数 问题描述 输入格式 输出格式 样例输入 1 样例输出 1 样例输入 2 样例输出 2 评测用例规模与约定 运行限制 代码&#xff1a; 题目 1 &am…...

Hadoop 运行环境搭建(开发重点)

文章目录Hadoop 运行环境搭建&#xff08;开发重点&#xff09;一、安装JDK二、安装配置 Hadoop1、安装 hadoop2、hadoop 目录结构3、设置免密登录4、完全分布式模式&#xff08;开发重点&#xff09;1&#xff09;分发jdk2&#xff09;集群配置(1) 集群部署规划(2) 配置文件说…...

在社交媒体上行之有效的个人IP趋势

如果您认为无论是获得一份工作、建立一家企业还是推动个人职业发展&#xff0c;社交媒体都是帮助您实现目标的可靠工具&#xff0c;那么个人IP就是推动这一工具前进的燃料。个人IP反映了您是谁&#xff0c;您在所处领域的专业程度&#xff0c;以及您与他人的区别。社交媒体将有…...

Java网络编程

网络编程 什么是网络编程&#xff1f; 可以让设备中的程序与网络上其他设备中的程序进行数据交互&#xff08;实现网络通信&#xff09; Java.net. 包下提供了网络编程的解决方案* 基本的通信架构 基本的通信架构有两种方式&#xff1a;CS架构&#xff08;Client客户端/Se…...

PTA:L1-001 Hello World、L1-002 打印沙漏、L1-003 个位数统计(C++)

目录 L1-001 Hello World 问题描述&#xff1a; 实现代码&#xff1a; L1-002 打印沙漏 问题描述&#xff1a; 实现代码&#xff1a; 原理思路&#xff1a; L1-003 个位数统计 题目描述&#xff1a; 实现代码&#xff1a; 原理思路&#xff1a; 过于简单的就不再写题…...

构造HTTP请求

使用formform使用如下:<body><!-- 表单标签,允许用户和服务器之间交互数据 --><form action"https://www.sogou.com" method"get"><!-- 要求提交的数据以键值对的结构来组织 --><input type"text" name"stduent…...

转速/线速度/角速度计算FC

工业应用中很多设备控制离不开转速、线速度的计算,这篇博客给大家汇总整理。张力控制的开环闭环方法中也离不开转速和线速度的计算,详细内容请参看下面的文章链接: PLC张力控制(开环闭环算法分析)_plc的收卷张力控制系统_RXXW_Dor的博客-CSDN博客里工业控制张力控制无处不…...

学习笔记:Java并发编程(补)ThreadLocal

【尚硅谷】学习视频&#xff1a;https://www.bilibili.com/video/BV1ar4y1x727【黑马程序员】学习视频&#xff1a;https://www.bilibili.com/video/BV15b4y117RJ 参考书籍 《实战 JAVA 高并发程序设计》 葛一鸣 著《深入理解 JAVA 虚拟机 | JVM 高级特性与最佳实践》 周志明 著…...

HashMap底层实现原理及面试题

文章目录1. 常见的数据结构有三种结构1.1 各自数据结构的特点2. HashMap2.1 概述2.2 底层结构2.2.1 HashMa实现原理&#xff1a;2.2.1.1 map.put(k,v)实现原理2.2.1.2 map.get(k)实现原理2.2.1.3 resize源码2.2.2 HashMap常用的变量2.2.3 HashMap构造函数2.3 JDK1.8之前存在的问…...

【STM32】进阶(二):DMA+ADC实现模拟量检测

1、简述 DMA&#xff1a;Direct Memory Access&#xff0c;直接内存访问 ADC&#xff1a;Analog to Digital Converter&#xff0c;模数转换器&#xff0c;模拟信号转换成数字信号的电路&#xff08;采样-量化-编码&#xff09; 参考博客&#xff1a; STM32DMA功能详解 STM32…...

Lab2_Simple Shell_2020

Lab2: 实验目的&#xff1a;给xv6添加新的系统调用 并理解系统调用是如何工作的&#xff0c;并理解xv6内核的一些内部特征 实验准备&#xff1a; 阅读xv6的第2章以及第4章的4.3,4.3小节熟悉下面的源码 用户态相关的代码&#xff1a;user/user.h和user/usys.pl内核态相关的代…...

2023最全电商API接口 高并发请求 实时数据 支持定制 电商数据 买家卖家数据

电商日常运营很容易理解&#xff0c;就是店铺商品维护&#xff0c;上下架&#xff0c;评价维护&#xff0c;库存数量&#xff0c;协助美工完成制作详情页。店铺DSR&#xff0c;好评率&#xff0c;提升客服服务等等&#xff0c;这些基础而且每天都必须做循环做的工作。借助电商A…...

MySQL 的索引类型

1. 按照功能划分 按照功能来划分&#xff0c;索引主要有四种&#xff1a; 普通索引唯一性索引主键索引全文索引 普通索引就是最最基础的索引&#xff0c;这种索引没有任何的约束作用&#xff0c;它存在的主要意义就是提高查询效率。 普通索引创建方式如下&#xff1a; CREATE…...

< Linux > 进程信号

目录 1、信号入门 生活角度的信号 技术应用角度的信号 前台进程 && 后台进程 信号概念 用kill -l命令察看系统定义的信号列表 信号处理的方式 2、信号产生前 用户层产生信号的方式 3、产生信号 3.1、通过终端按键产生信号 3.2、核心转储core dump 3.3、调用系统函数…...

Pyspark基础入门7_RDD的内核调度

Pyspark 注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kafka Hbase Hi…...

C/C++每日一练(20230307)

目录 1. 国名排序 ★★ 2. 重复的DNA序列 ★★★ 3. 买卖股票的最佳时机 III ★★★ &#x1f31f; 每日一练刷题专栏 C/C 每日一练 ​专栏 Python 每日一练 ​专栏 1. 国名排序 小李在准备明天的广交会&#xff0c;明天有来自世界各国的客房跟他们谈生意&#xff0c…...

一条SQL查询语句是如何执行的?

平时我们使用数据库&#xff0c;看到的通常都是一个整体。比如&#xff0c;你有个最简单的表&#xff0c;表里只有一个ID字段&#xff0c;在执行下面这个查询语句时&#xff1a; mysql> select * from T where ID10&#xff1b; 我们看到的只是输入一条语句&#xff0c;返…...

tcsh常用配置

查看当前的shell类型 在 Linux 的世界中&#xff0c;有着许多 shell 程序。常见的有&#xff1a; Bourne shell (sh) C shell (csh) TC shell (tcsh) Korn shell (ksh) Bourne Again shell (bash) 其中&#xff0c;最常用的就是bash和tcsh&#xff0c;本次文章介绍tcsh的…...

GeoServer实战:如何用MBTiles扩展包发布高德/谷歌多层级地图(含WPS扩展配置)

GeoServer高级应用&#xff1a;MBTiles与WPS扩展包深度整合实战指南 引言 在当今地理信息系统(GIS)领域&#xff0c;高效发布多层级地图数据已成为开发者面临的常见挑战。无论是商业地图服务如高德、谷歌地图&#xff0c;还是自定义的矢量切片&#xff0c;都需要一套稳定可靠的…...

从OpenWrt到iStoreOS:在VMware里体验‘小白友好型’软路由的存储与路由功能

从OpenWrt到iStoreOS&#xff1a;虚拟化环境下的软路由进化体验 当第一次接触OpenWrt时&#xff0c;很多人会被它强大的功能所吸引——从防火墙规则到QoS流量控制&#xff0c;从VPN服务到多WAN负载均衡&#xff0c;这个开源路由系统几乎能满足你对网络管理的所有想象。但随之而…...

【带AI】基于SpringBoot+Vue图书管理系统设计与实现+文档+指导搭建视频

特色实现QQ邮箱注册/找回密码&#xff0c;WebSocket实时推送&#xff0c;协同过滤算法图书推荐&#xff0c;接入DeepSeek大模型技术栈 1.后端&#xff1a;Spring Boot2、MyBatis、Java Mail&#xff08;QQ SMTP&#xff09;、WebSocket、DevTools、Spring Security Crypto&…...

5G NR新手必看:PBCH中的MIB数据解析与UE接入实战指南

5G NR新手必看&#xff1a;PBCH中的MIB数据解析与UE接入实战指南 在5G新空口&#xff08;NR&#xff09;技术中&#xff0c;物理广播信道&#xff08;PBCH&#xff09;承载的主信息块&#xff08;MIB&#xff09;是用户设备&#xff08;UE&#xff09;实现初始接入的关键。对于…...

3步突破语言壁垒:学术研究者的PDF翻译效率工具

3步突破语言壁垒&#xff1a;学术研究者的PDF翻译效率工具 【免费下载链接】zotero-pdf2zh PDF2zh for Zotero | Zotero PDF中文翻译插件 项目地址: https://gitcode.com/gh_mirrors/zo/zotero-pdf2zh 学术文献翻译是科研工作者日常研究中的重要环节&#xff0c;但传统翻…...

GetQzonehistory:QQ空间说说完整导出工具使用指南

GetQzonehistory&#xff1a;QQ空间说说完整导出工具使用指南 【免费下载链接】GetQzonehistory 获取QQ空间发布的历史说说 项目地址: https://gitcode.com/GitHub_Trending/ge/GetQzonehistory GetQzonehistory是一款开源工具&#xff0c;专注于将QQ空间历史说说完整导…...

seo优化员如何提高网站的流量

SEO优化员如何提高网站的流量 在当今竞争激烈的互联网环境中&#xff0c;网站的流量直接关系到企业的业务拓展和品牌影响力。对于SEO优化员来说&#xff0c;如何有效提高网站的流量是一个必须面对和解决的问题。本文将从问题分析、原因说明、解决方法、注意事项和实用建议几个…...

为何说逻辑回归是分类任务的“最佳基石”?

提到“回归”&#xff0c;你可能先想到房价预测。但有一个名字里带“回归”、实际却用来做分类的算法&#xff0c;在机器学习界地位极高——逻辑回归&#xff08;Logistic Regression&#xff09;。 医学诊断、金融风控、垃圾邮件识别……到处都有它的身影。 原因很简单&#…...

抖音批量下载终极解决方案:免费无水印工具快速上手指南

抖音批量下载终极解决方案&#xff1a;免费无水印工具快速上手指南 【免费下载链接】douyin-downloader A practical Douyin downloader for both single-item and profile batch downloads, with progress display, retries, SQLite deduplication, and browser fallback supp…...

突破限制的文档获取:kill-doc开源工具让信息获取效率提升70%的实战指南

突破限制的文档获取&#xff1a;kill-doc开源工具让信息获取效率提升70%的实战指南 【免费下载链接】kill-doc 看到经常有小伙伴们需要下载一些免费文档&#xff0c;但是相关网站浏览体验不好各种广告&#xff0c;各种登录验证&#xff0c;需要很多步骤才能下载文档&#xff0c…...