C语言:深入理解指针
一.内存和地址
#include<stdio.h>
int main()
{printf("%zd\n", sizeof(char *));printf("%zd\n", sizeof(int *));printf("%zd\n", sizeof(float *));printf("%zd\n", sizeof(double *));return 0;
} 根据我们在上面得出的结论,上图的代码在两种环境中得出的结果就不相同。
三.指针变量类型的意义
指针变量的大小和类型无关,只要是指针变量,在同一个平台下,大小都是⼀样的,为什么还要有各种各样的指针类型呢?我们接下来慢慢分析。
1.指针的解引用
#include<stdio.h>
int main()
{int n = 0x11223344;char* pc = (char *) & n;*pc = 0;return 0;
} #include<stdio.h>
int main()
{int n = 0x11223344;int* pc = & n;*pc = 0;return 0;
}
我们可以看出, char* 类型的指针变量+1跳过1个字节, int* 类型的指针变量+1跳过了4个字节。 这就是指针变量的类型差异带来的变化。指针+1,其实跳过1个指针指向的元素。指针可以+1,那也可以-1。
#include <stdio.h>
int main()
{int m = 0;m = 20;//m是可以修改的const int n = 0;n = 20;//n是不能被修改的return 0;
}
一般来讲const修饰指针变量,可以放在*的左边,也可以放在*的右边,意义是不一样的。
#include<stdio.h>
int main()
{int n = 10;int m = 20;int* pn = &n;*pn = 30;pn = &m;printf("%d", *pn);return 0;
} 这是没有const修饰下的效果。
#include<stdio.h>
int main()
{int n = 10;int m = 20;int const * pn = &n;*pn = 30;pn = &m;printf("%d", *pn);return 0;
} 
当我们将const修饰指针变量放在*左边时,*pn就不能被改变了。
#include<stdio.h>
int main()
{int n = 10;int m = 20;int * const pn = &n;*pn = 30;pn = &m;printf("%d", *pn);return 0;
} 
当我们将const修饰指针变量放在*右边时,pn就不能被改变了。
#include<stdio.h>
int main()
{int n = 10;int m = 20;int const* const pn = &n;*pn = 30;pn = &m;printf("%d", *pn);return 0;
} 
当我们将const修饰指针变量放在*两边边时,*pn和pn就都不能被改变了。
#include<stdio.h>
int my_strlen(char * s)
{char* p = s;while (*p != '\0')p++;return p - s;
}
int main()
{printf("%d", my_strlen("abc"));return 0;
} 在上述代码中,我们就使用了指针-指针实现了strlen函数的效果。
3.指针的关系运算

六、野指针
#include<stdio.h>
int main()
{int* p;*p = 10;return 0;
} 2.指针越界访问
#include<stdio.h>
int main()
{int arr[5] = { 0 };int* p = &arr[0];int sz = sizeof(arr) / sizeof(arr[0]);for (int i = 0; i <= sz; i++){*p = i;p++;}return 0;
} 3.指针指向的空间释放
#include<stdio.h>
int* test()
{int n = 10;return &n;
}
int main()
{int* p=test();printf("%d", *p);return 0;
} 当test()函数运行完时,n作为局部变量,内存将被回收。
七、如何规避野指针
1.指针初始化
#include<stdio.h>
int main()
{int* p= NULL;return 0;
} 2.小心指针越界
#include<stdio.h>
int main()
{int arr[5] = { 0 };int* p= &arr[0];for (int i = 0; i < 5; i++){*(p + i) = i;}//此时p已经越界了,可以把p置为NULLp = NULL;p = &arr[3];//重新让p获得地址//下次使⽤的时候,判断p不为NULL的时候再使⽤if (p != NULL){//......}return 0;
} 4.避免返回局部变量的地址
assert(p != NULL); #define NDEBUG
#include <assert.h> int length(const char* s)//防止*s在函数中被改变
{int count = 0;assert(s);//通过断言防止野指针while (*s){count++;s++;}return count;
} 2.传值调用和传址调用

#include<stdio.h>
void test(int* pa, int* pb)
{int item;item = *pa;*pa = *pb;*pb = item;
}
int main()
{int a = 1, b = 2;int* pa = &a;int* pb = &b;test(pa, pb);printf("%d %d", a, b);return 0;
} 我们将是a,b的地址作为实参传递给test函数,再通过解引用操作符的作用,我们可以将a,b所对应的数值进行交换。这种调用就叫传址调用。传址调用,可以让函数和主调函数之间建立真正的联系,在函数内部可以修改主调函数中的变量;所以未来函数中只是需要主调函数中的变量值来实现计算,就可以采用传值调用。如果函数内部要修改主调函数中的变量的值,就需要传址调用。
相关文章:
C语言:深入理解指针
一.内存和地址 我们知道计算机上CPU(中央处理器)在处理数据的时候,需要的数据是在内存中读取的,处理后的数据也会放回内存中,那我们买电脑的时候,电脑上内存是 8GB/16GB/32GB 等,那这些内存空间…...
【WPF实现RichTextBox添加文本、自动滚动】
前言 使用WPF 中的RichTextBox控件实现添加文本后自动滚动末尾。因为RichTextBox无法直接绑定数据,所以通过引用System.Windows.Interactivity实现(System.Windows.Interactivity.WPF) 代码 MainWindow.xaml <Window x:Class"WPF…...
量化交易系统开发-实时行情自动化交易-8.4.MT4/MT5平台
19年创业做过一年的量化交易但没有成功,作为交易系统的开发人员积累了一些经验,最近想重新研究交易系统,一边整理一边写出来一些思考供大家参考,也希望跟做量化的朋友有更多的交流和合作。 接下来会对于MT4/MT5平台介绍。 MetaT…...
【HarmonyOS】@Observed和@ObjectLink嵌套对象属性更改UI不刷新问题
【HarmonyOS】Observed和ObjectLink嵌套对象属性更改UI不刷新问题 一、问题背景 使用了Observed和ObjectLink,修改嵌套对象的属性,UI还是不刷新,常见的问题有以下三种形式: 1.多级嵌套,嵌套对象的类并没有添加Observ…...
什么是默克尔树(Merkle Tree)?如何计算默克尔根?
默克尔树的概念 默克尔树(Merkle Tree)是一种特殊的二叉树,它的每个节点都存储了一个数据块的哈希值。哈希值是一种可以将任意长度的数据转换为固定长度的字符串的算法,它具有唯一性和不可逆性的特点,即不同的数据块会产生不同的哈希值&…...
眼部按摩仪WT2605音频蓝牙语音芯片方案 单芯片实现语音提示及控制/手机无线音频传输功能
随着科技的快速发展,人们的生活方式也在不断改变,智能化、便捷化的产品逐渐成为市场的主流。眼部按摩仪作为一种结合了现代科技与健康生活理念的产品,受到了广大消费者的青睐。而在众多眼部按摩仪中,采用WT2605音频蓝牙芯片的方案…...
python打包深度学习虚拟环境
今天师兄让我把环境打包发给他,我才知道可以直接打包深度学习虚拟环境,这样另一个人就不用辛辛苦苦的去装环境了,我们都知道有些论文他需要的环境很难装上。比如装Apex,装 DCN,mmcv-full 我现在把3090机子上的ppft虚拟…...
springboot358智慧社区居家养老健康管理系统(论文+源码)_kaic
毕 业 设 计(论 文) 智慧社区居家养老健康管理系统设计与实现 摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此&…...
复杂网络(二)
一、网络的基本静态几何特征 1.1 度分布 节点的度:在网络中,节点的邻边数称为该节点的度 对于网络中所有节点的度求平均,可得到网络的平均度 度分布:大多数实际网络中的节点的度满足一定的概率分布。定义P(k)为网络中度为k的节…...
Kubernetes 01
MESOS:APACHE 分布式资源管理框架 2019-5 Twitter退出,转向使用Kubernetes Docker Swarm 与Docker绑定,只对Docker的资源管理框架,阿里云默认Kubernetes Kubernetes:Google 10年的容器化基础框架,borg…...
node修改文件名称
node修改名称 var fs require(fs); const events require(events); var path require(path);init(); function init() {//要遍历的文件夹所在的路径const dirPath path.resolve(__dirname, "data");//遍历目录fileDisplay(dirPath); }/*** 文件遍历* param dirP…...
ArcGIS 软件中路网数据的制作
内容导读 路网数据是进行网络分析的基础,它是建立网络数据集的数据来源。 本文我们以OSM路网数据为例,详细介绍OSM路网数据从下载,到数据处理,添加属性,完成符合网络分析的网络数据集的全部过程。 01 数据获取 比较…...
transformers microsoft--table-transformer 表格识别
一、安装包 pip install transformers pip install torch pip install SentencePiecepip install timm pip install accelerate pip install pytesseract pillow pandas pip install tesseract 下载模型: https://huggingface.co/microsoft/table-transformer-s…...
【Spark源码分析】规则框架-草稿
规则批:规则集合序列,由名称、执行策略、规则列表组成。一个规则批里使用一个执行规则。 执行策略 FixedPointOnce 规则: #mermaid-svg-1cvqR4xkYpMuAs77 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px…...
迪米特原则的理解和实践
迪米特原则(Law of Demeter,简称LoD),也被称为最少知识原则(Least Knowledge Principle,LKP),是面向对象设计中的一个重要原则。其核心思想是:一个对象应该对其他对象有最…...
jQuery零基础入门速通(中)
大家好,我是小黄。 在上一篇文章中,我们初步了解了jQuery的基本概念、环境搭建、选择器、基本的DOM操作以及事件处理。接下来,我们将继续深入探讨jQuery的DOM操作和事件处理,以及一些实用的技巧和高级用法。 五、高级DOM操作 5…...
【设计模式系列】中介者模式(十八)
一、什么是中介者模式 中介者模式(Mediator Pattern)是一种行为型设计模式,其核心思想是通过一个中介者对象来封装一系列对象之间的交互,使这些对象不需要相互显式引用。中介者模式提供了一个中介层,用以协调各个对象…...
PDF版地形图矢量出现的问题
项目描述:已建风电场道路测绘项目,收集到的数据为PDF版本的地形图,图上标注了项目竣工时期的现状,之后项目对施工区域进行了复垦恢复地貌,现阶段需要准确的知道实际复垦修复之后的道路及其它临时用地的面积 解决方法&…...
小迪安全第四十二天笔记 简单的mysql注入 mysql的基础知识 用户管理数据库模式 mysql 写入与读取 跨库查询
前言 之前的安全开发我们学习了 php联动数据库的模式 ,这个模式是现在常用的模式 这一节来学习 如何 进行数据库的注入和数据库相关知识 1、了解数据库的结构 我们使用 navicate连接数据库之后看一下 一共四层结构 库 》表》字段》数据 这个层级关系…...
11.25.2024刷华为OD
文章目录 HJ76 尼科彻斯定理(观察题,不难)HJ77 火车进站(DFS)HJ91 走格子方法,(动态规划,递归,有代表性)HJ93 数组分组(递归)语法知识…...
SpringBoot-17-MyBatis动态SQL标签之常用标签
文章目录 1 代码1.1 实体User.java1.2 接口UserMapper.java1.3 映射UserMapper.xml1.3.1 标签if1.3.2 标签if和where1.3.3 标签choose和when和otherwise1.4 UserController.java2 常用动态SQL标签2.1 标签set2.1.1 UserMapper.java2.1.2 UserMapper.xml2.1.3 UserController.ja…...
《Qt C++ 与 OpenCV:解锁视频播放程序设计的奥秘》
引言:探索视频播放程序设计之旅 在当今数字化时代,多媒体应用已渗透到我们生活的方方面面,从日常的视频娱乐到专业的视频监控、视频会议系统,视频播放程序作为多媒体应用的核心组成部分,扮演着至关重要的角色。无论是在个人电脑、移动设备还是智能电视等平台上,用户都期望…...
MySQL 隔离级别:脏读、幻读及不可重复读的原理与示例
一、MySQL 隔离级别 MySQL 提供了四种隔离级别,用于控制事务之间的并发访问以及数据的可见性,不同隔离级别对脏读、幻读、不可重复读这几种并发数据问题有着不同的处理方式,具体如下: 隔离级别脏读不可重复读幻读性能特点及锁机制读未提交(READ UNCOMMITTED)允许出现允许…...
AtCoder 第409场初级竞赛 A~E题解
A Conflict 【题目链接】 原题链接:A - Conflict 【考点】 枚举 【题目大意】 找到是否有两人都想要的物品。 【解析】 遍历两端字符串,只有在同时为 o 时输出 Yes 并结束程序,否则输出 No。 【难度】 GESP三级 【代码参考】 #i…...
React Native在HarmonyOS 5.0阅读类应用开发中的实践
一、技术选型背景 随着HarmonyOS 5.0对Web兼容层的增强,React Native作为跨平台框架可通过重新编译ArkTS组件实现85%以上的代码复用率。阅读类应用具有UI复杂度低、数据流清晰的特点。 二、核心实现方案 1. 环境配置 (1)使用React Native…...
MMaDA: Multimodal Large Diffusion Language Models
CODE : https://github.com/Gen-Verse/MMaDA Abstract 我们介绍了一种新型的多模态扩散基础模型MMaDA,它被设计用于在文本推理、多模态理解和文本到图像生成等不同领域实现卓越的性能。该方法的特点是三个关键创新:(i) MMaDA采用统一的扩散架构…...
将对透视变换后的图像使用Otsu进行阈值化,来分离黑色和白色像素。这句话中的Otsu是什么意思?
Otsu 是一种自动阈值化方法,用于将图像分割为前景和背景。它通过最小化图像的类内方差或等价地最大化类间方差来选择最佳阈值。这种方法特别适用于图像的二值化处理,能够自动确定一个阈值,将图像中的像素分为黑色和白色两类。 Otsu 方法的原…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
Rapidio门铃消息FIFO溢出机制
关于RapidIO门铃消息FIFO的溢出机制及其与中断抖动的关系,以下是深入解析: 门铃FIFO溢出的本质 在RapidIO系统中,门铃消息FIFO是硬件控制器内部的缓冲区,用于临时存储接收到的门铃消息(Doorbell Message)。…...
Qemu arm操作系统开发环境
使用qemu虚拟arm硬件比较合适。 步骤如下: 安装qemu apt install qemu-system安装aarch64-none-elf-gcc 需要手动下载,下载地址:https://developer.arm.com/-/media/Files/downloads/gnu/13.2.rel1/binrel/arm-gnu-toolchain-13.2.rel1-x…...
