C语言指针
1,指针是什么
- 指针是内存中一个最小内存单元(一个字节)的编号,也就是地址
- 通常口语中说的指针,通常是指指针变量也就是用来存放内存中地址的变量
每个内存单元都有一个地址,这个地址不需要存起来,除非把它放到一个指针变量里时。指针变量里面存放的是地址,而通过这个地址,就可以找到一个内存单元。
指针变量:
我们可以通过&(取地址操作符)去除变量的内存其实是地址,把地址存放到一个变量里,这个变量就是指针变量。
int a=10;//在内存中开辟一块空间
int* pa=&a;//这里我们对变量a,取出它的地址,可以使用&操作符。
//a变量(整型变量)占四个字节,这里是将a的四个字节中的第一个字节的地址存放在pa变量中,pa就是一个指针变量,用来存放a的地址
总结:指针变量就是用来存放地址的变量(存放在指针中得值都被当作地址处理)
对于32位的机器,假设有32根地址线,那么每个地址线在寻址的时候产生高电平(高电压)和低电平(低电压)就是1(或者0);
那么32跟地址线产生的地址就是:
00000000000000000000000000000000
00000000000000000000000000000001
……
11111111 11111111 11111111 11111111
这里就有2的32次方个地址
每个地址表示一个字节,那么我们就可以给4G的空间进行编址。(2^32Byte==2^32/1024KB==2^32/1024/1024MB==2^32/1024/1024/1024GB==4GB)
这里我们就明白:
- 在32位机器上,地址是32个0或1组成的二进制序列,(32个比特位,8个比特位等于1个字节)那地址就得用4个字节的空间来存储,所以一个指针变量的大小就是4个字节。
- 在64位机器上,一个指针变量的大小就是8个字节。
sizeof的返回值类型时unsiged int (无符号整型)可以用%u打印,但sizeof有自己专属的打印%zu
2,指针和指针类型
我们知道变量有不同的类型,整形,浮点型等,指针也有不同的类型。
指针定义的方式type+*
char*类型的指针就是为了存放char类型变量的地址;
short*类型的指针就是为了存放short类型变量的地址;
int*类型的指针就是为了存放int;欸型变量的地址。
类型决定了指针的访问权限
指针类型的意义:
1.指针类型决定他被解引用时访问了多少个字节(解引用时有几个字节的访问权限),如果是int*解引用时访问四个字节,如果是char*解引用时访问1个字节。
char*类型的指针变量解引用时,只问了一个字节,只改变了一个内存单元的数据的值。
2.指针类型决定了指针+-1操作时,跳过了几个字节(决定了指针的步长)
我们知道int和float类型都是占四个字节,那他们的解引用是否可以通用呢?不能。
原因是浮点数和整数本身在内存中的存储是有差异的,对内存的解读方式有所差异,就是存在内存中的数不相同。
3,野指针
野指针就是指针指向的位置是不可知道(随机的,不正确的,没有明确限制的)
1.野指针的成因:
- 指针未初始化
int* p;//p没有初始化,就意味着没有明确的指向
//一个局部变量不初始化放的是随机值:0xcccccccc
*p=10;//非法访问内存了,这里的p就是野指针。
- 指针的越界访问
int arr[10];
int *p=arr;
int i=0;
for(i=0;i<=10;i++)
{
*(p++)=i;//当指针的指向超出数组arr的范围时,p就是野指针。}
- 指针指向的空间释放
出了test()函数这部分空间,a销毁,将这部分空间还给操作系统。p存储着地址,能找到这部分空间,但不能返回使用这块空间。(空间销毁是这块空间不属于当前程序,不属于当前权限,但是内存中的这块空间还在)
防止野指针的出现:
- 指针初始化
- 小心指针越界
- 指针指向空间释放,即使置NULL
- 避免返回局部变量的地址
- 指针是用之前检查有效性
p3!=NULL表示不是空指针,指向有效空间。
但是p!=NULL,也不能避免野指针。
例如:
内存空间不属于我,但是通过解引用还可以找到,可以访问。
若将栈帧覆盖,结果可能发生改变。
4,指针运算
- 指针+-整数
后置++,先使用这个数再++,与上面一种表达意思相同,与不加括号效果相同,++的优先级比解引用高;但如果时(*p)++:表示的意思就是先通过*p找到p指向的元素,在对这个元素进行++。
这种方法是依次将下标位i的元素赋值为1;(p+i)就是下标为i的元素的地址。
- 指针-指针
指针-指针得到指针和指针之间的元素个数,不是所有指针都能相减,只有指向同一块空间的两个指针才能相减(比如一个存放char类型数据的指针变量和一个存放int类型数据的指针变量相减就没有任何意义)
写一个my_strlen函数(之前我们用的是新定义了一个变量count 数进行的次数)
#include<stdio.h>//指针运算
int my_strlen(char* str)
{int count = 0;while (*str++ != '\0'){count++;}return count;
}
int main()
{char arr[] = "abcdef";int ret = my_strlen(arr);printf("%d", ret);
}
在这里我们可以不创建这个中间变量,用指针-指针进行计算
#include<stdio.h>//指针运算
int my_strlen(char* str)
{char* start = str;while (*str != '\0'){str++;}return (str - start);
}
int main()
{char arr[] = "abcdef";int ret = my_strlen(arr);printf("%d", ret);
}
这里不能像上次一样将str++放到while判断里面去,否则判断到等于0的时候str会再自增一次,而我们后面计算的返回值算的是一共增加几次的值。
这里我们还需要说一下:指针+指针的运算没有实际意义,我们就不考虑指针的加法运算
- 指针的关系运算
#define N_VALUES 5
float values[N_VALUES];
float *vp;
for(vp=&values[ N_VALUES];vp>&values[0];)
{
*--vp = 0;}
前置--,先--,后使用,依次将下标为4,3,2,1,0的元素赋值为0;
上面代码是否可以简化成
for(vp=&values[ N_VALUES-1];vp>=&values[0];vp--)
{
*vp = 0;}
这个代码也是依次将下标为4,3,2,1,0的元素赋值为0;但是将下标为0的元素赋值为0后还要进行一次vp--,这时候vp指向的是数组首元素的前一个元素,判断不是>&values[0]的,代码不再进行。
这个代码在绝多数编译器上都是可以顺利完成任务的,但是我们应该避免这样写,因为标准并不保证它可行。
标准规定:允许指向数组元素的指针与指针数组最后一个元素后面那个内存位置的指针比较,但是不允许与指向第一个元素之前的那个内存位置指针进行比较。
5,指针和指针数组
数组名是首元素地址(2种情况除外,具体看数组章节)
既然我们可以把数组名当成首元素地址存放到一个指针中,那么用指针来访问数组就成为可能
arr[i]-->*(p+i)-->*(arr+i)-->i[arr]
6,二级指针
二级指针变量是用来存放一级指针变量的地址的
#include<stdio.h>
//二级指针
int main()
{int a = 10;int* pa = &a;int** ppa = &pa;**ppa = 20;printf("%d", a);return 0;
}
int *pa;中*表示pa是指针变量,int表示指向的对象是int类型;
int** pa;中*表示ppa是指针变量,int*表示指向的对象是int*类型。
7,指针数组
指针数组的本质是数组,是用来存放指针的数组
#include<stdio.h>
//指针数组
int main()
{int a = 10;int b = 20;int c = 30;int arr[10];int* pa = &a;int* pb = &b;int* pc = &c;int* parr[10] = { &a,&b,&c };int i = 0;for (i = 0;i < 3;i++){printf("%d ", *(parr[i]));}return 0;
}
我们知道存储相同类型的元素可以创建一个数组;那么存储相同类型的指针变量也就可以创建一个指针数组。如上。
我们还可以通过指针数组模拟出一个二维数组。
普通二维数组的创建:
通过指针数组模拟一个二维数组:
parr[0]-->arr1(首元素的地址)
parr[0][0]-->arr1[0],是arr1里面的第一个元素就是1;
相关文章:
C语言指针
1,指针是什么 指针是内存中一个最小内存单元(一个字节)的编号,也就是地址通常口语中说的指针,通常是指指针变量也就是用来存放内存中地址的变量 每个内存单元都有一个地址,这个地址不需要存起来࿰…...
前端(async 和await)
1 async async 将 function 变为成为 async 函数 ●async 内部可以使用 await,也可以不使用,因此执行这个函数时,可以使用 then 和 catch 方法 ●async 函数的返回值是一个 Promise 对象 ●Promise 对象的结果由 async 函数执行的返回值决…...
打造高效的HIS与DAT文件解析工具
在工业数据采集和存储中,HIS 和 DAT 文件是非常常见的二进制数据格式。然而,解析这些固定块大小的二进制文件并将其转换为易读的 CSV 格式并非易事。本文将深入讲解如何使用 Python 和 PyQt5 打造一款图形化工具,轻松解析和转换这些文件&…...
YOLO系列:二、基于yolov8和labelme制作数据集及模型训练
YOLO系列:二、基于yolov8和labelme制作数据集及模型训练 1.新建一个项目1.数据集标注及类型转换1. 1 使用labelme进行数据标注1.1.1打开labelme1.1.2图像标注及存储 1. 2 将数据集转换成yolo类型 2.模型训练的配置文件2. 1打开labelme标注图像2.1.1三级目录 3.模型训…...
PHP搭建环境
一、安装apache 1、获取Apache安装软件 2、双击安装即可:指定对应的路径:E:server/apache 3、选择安装模式:使用自定义模式 4、选择安装位置 二、Apache的目录结构说明 三、Httpd.exe的详细应用 1、服务器进程:运行之后才能够工作...
LeetCode hot100-69-N
https://leetcode.cn/problems/valid-parentheses/description/?envTypestudy-plan-v2&envIdtop-100-liked 20. 有效的括号 已解答 简单 相关标签 相关企业 提示 给定一个只包括 (,),{,},[,] 的字符串 s &#x…...
14:00面试,14:06就出来了,问的问题有点变态。。。
从小厂出来,没想到在另一家公司又寄了。 到这家公司开始上班,加班是每天必不可少的,看在钱给的比较多的份上,就不太计较了。没想到5月一纸通知,所有人不准加班,加班费不仅没有了,薪资还要降40%…...
ubuntu20.04复现 Leg-KILO
这里写目录标题 opencv版本问题下载3.2.0源代码进入解压后的目录创建构建目录运行 CMake 配置 配置时指定一个独立的安装目录,例如 /opt/opencv-3.2:出错: 使用多线程编译错误1: stdlib.h: 没有那个文件或目录错误2:er…...
Redis应用—1.在用户数据里的应用
大纲 1.社区电商的业务闭环 2.Redis缓存架构的典型生产问题 3.用户数据在读多写少场景下的缓存设计 4.热门用户数据的缓存自动延期机制 5.缓存惊群与穿透问题的解决方案 6.缓存和数据库双写不一致问题分析 7.基于分布式锁保证缓存和数据库双写一致性 8.缓存和数据库双写…...
MySQL InnoDB 中的数据页
文章目录 1. 数据库的存储结构概述1.1 表空间(Tablespace)1.2 段(Segment)1.3 区(Extent)1.4 页(Page) 2. InnoDB 数据页的深入解析2.1 数据页的物理结构2.2 数据页中的行存储2.3 数…...
React Fiber
React Fiber 是 React 16 引入的全新重写的协调(Reconciliation)算法的实现,旨在改善 React 的更新机制和性能,尤其是在复杂应用和大量更新的场景下。它使得 React 更加灵活、可调度,能够实现优先级控制和中断更新等特…...
hive 小文件分析
1、获取fsimage文件: hdfs dfsadmin -fetchImage /data/xy/ 2、从二进制文件解析: hdfs oiv -i /data/xy/fsimage_0000000019891608958 -t /data/xy/tmpdir -o /data/xy/out -p Delimited -delimiter “,” 3、创建hive表 create database if not exists…...
大模型运用-Prompt Engineering(提示工程)
什么是提示工程 提示工程 提示工程也叫指令工程,涉及到如何设计、优化和管理这些Prompt,以确保AI模型能够准确、高效地执行用户的指令,如:讲个笑话、java写个排序算法等 使用目的 1.获得具体问题的具体结果。(如&…...
Linux(网络协议和管理)
后面也会持续更新,学到新东西会在其中补充。 建议按顺序食用,欢迎批评或者交流! 缺什么东西欢迎评论!我都会及时修改的! 在这里真的很感谢这位老师的教学视频让迷茫的我找到了很好的学习视频 王晓春老师的个人空间…...
前端项目打包部署
打包和部署前端项目是将开发环境中的代码转化为生产环境可直接运行的静态文件,并将其部署到服务器上的过程。 # 项目打包 pnpm run build# 上传文件至远程服务器 将本地打包生成的 dist 目录下的所有文件拷贝至服务器的 /usr/share/nginx/html 目录。# nginx.cofig…...
Linux驱动开发(12):中断子系统–按键中断实验
本章我们以按键为例讲解在驱动程序中如何使用中断, 在学习本章之前建议先回顾一下关于中断相关的裸机部分相关章节, 这里主要介绍在驱动中如何使用中断,对于中断的概念及GIC中断控制器相关内容不再进行讲解。 本章配套源码和设备树插件位于“…...
C语言(函数指针与指针函数)
函数指针 定义:函数指针本质上是指针,它是函数的指针(定义了一个指针变量,变量中存储了函数的地 址)。函数都有一个入口地址,所谓指向函数的指针,就是指向函数的入口地址。这里函数名就代 表入…...
中国计算机学会计算机视觉专委会携手合合信息举办企业交流活动,为AI安全治理打开“新思路”
近期,《咬文嚼字》杂志发布了2024年度十大流行语,“智能向善”位列其中,过去一年时间里,深度伪造、AI诈骗等话题屡次登上热搜,AI技术“野蛮生长”引发公众担忧。今年9月,全国网络安全标准化技术委员会发布了…...
MacOs 日常故障排除troubleshooting
1. 关闭开机自启动 app X macOs 15.1 System settings -> General -> Login Items & Extensions->Open at Login -> Select app X and click -...
ArcGIS字符串补零与去零
我们有时候需要 对属性表中字符串的补零与去零操作 我们下面直接视频教学 下面看视频教学 ArcGIS字符串去零与补零 推荐学习 ArcGIS全系列实战视频教程——9个单一课程组合 ArcGIS10.X入门实战视频教程(GIS思维) ArcGIS之模型构建器(Mod…...
【FLASH、SRAM和DRAM、CISC和RISC、冯诺依曼和哈佛】单片机内存结构的了解
【FLASH、SRAM和DRAM、CISC和RISC、冯诺依曼和哈佛】单片机内存结构的了解 一、单片机概念 单片机:Single-Chip Microcomputer,单片微型计算机,是一种集成电路芯片 1.1RAM里的SRAM和DRAM SRAM(Static Random Access Memory&…...
ionic capacitor JSValueEncodingContainer报错
try to clean the build folder. exit Xcode. upgrade your capacitor core libraries update cocoapods to 1.13.0 do “pod install --repo-udpdate” after that: ionic build --prodnpx cap updatenpx cap syncnpx cap open ios capacitor ios最低版本要求13 [Bug]:…...
pdf merge
在 Ubuntu 22.04 上,你可以使用以下命令行工具来合并多个 PDF 文件: 1. pdftk pdftk 是一个强大的 PDF 工具,支持合并、拆分和其他操作。安装和使用方法如下: sudo apt install pdftk pdftk file1.pdf file2.pdf cat output me…...
【Trouble Shooting】Oracle ADG hung,出现ORA-04021
异常问题: 突然收到告警,ADG实例状态异常。 环境: 版本:Oracle 11.2.0.4.201020 状态:Active Dataguard 问题: 查看Oracle实例alert日志,发现有异常报错: Thu Dec 12 22:15:23 …...
奇怪的知识又增加了:ESP32下的Lisp编程=>ULisp--Lisp for microcontrollers
ESP32下有MicroPython,那么我就在想,有Lisp语言支持吗?答案是果然有!有ULisp,专门为MCU设计的Lisp! 网址:uLisp - Lisp for microcontrollers 介绍:用于微控制器的 Lisp 适用于 Ar…...
什么是CRM系统?CRM系统的功能、操作流程、生命周期
CRM系统作为企业管理和维护客户关系的重要工具,在商业活动中扮演着越来越重要的角色。今天,就让我们一起揭开它的神秘面纱,看看这个“幕后英雄”到底是怎么工作的。 什么是CRM系统? 首先,我们要了解什么是CRM。简单来…...
[每日一练]转换日期格式
#该题目来源于力扣: 1853. 转换日期格式 - 力扣(LeetCode) 题目要求: 表: Days------------------- | Column Name | Type | ------------------- | day | date | ------------------- day 是这个表的主键。给定一个Da…...
LSM Tree 底层设计理念
场景:设计一个海量读写的的kv数据库,优先保证写入速度,但是读取速度也不能很慢 因为海量数据存储,不能使用内存,得存到文件里。 Q:对已经落盘的文件,怎么根据key修改value A:读取文件…...
面向对象设计规则和各类设计模式
面向对象设计(Object-Oriented Design, OOD)是一种软件设计方法论,它使用对象、类、继承、封装、多态等概念来组织代码。面向对象设计的核心目标是提高软件的可维护性、可扩展性和复用性。在面向对象设计中,遵循一定的设计原则和模…...
Artec Leo3D扫描仪在重型机械设备定制中的应用【沪敖3D】
挑战:一家加拿大制造商需要有效的方法,为富于变化且难度较高的逆向工程,快速、安全、准确地完成重型机械几何采集。 解决方案:Artec Leo, Artec Studio, Geomagic for SOLIDWORKS 效果:Artec Leo三维扫描代替过去的手动…...
Linux下socket广播通讯的实现
概念大家都很清楚,不赘述。 广播必然用UDP这套东西。 setsockopt() 函数及其在广播中的应用: 在 C 网络编程中,setsockopt() 函数用于设置套接字选项,这些选项可以控制套接字的各种行为。对于广播通信,我们特别关心…...
Tiptap,: 富文本编辑器入门与案例分析
Tiptap 是一个现代的富文本编辑器,基于 ProseMirror 打造,旨在提供一个灵活且功能强大的文本编辑解决方案。它具有开箱即用的能力,同时也允许开发者根据业务需求进行高度定制化扩展。与传统的富文本编辑器相比,Tiptap 提供了更精细…...
数智读书笔记系列002 埃隆·马斯克传
书名:埃隆马斯克传 作者:【美】沃尔特艾萨克森 译者:孙思远;刘家琦 出版社:中信出版集团 出版时间:2023年9月 ISBN:9787521758399 这本书是关于特斯拉CEO埃隆马斯克的传记,作者…...
linux环境一句话后门
原文地址:linux环境一句话后门 – 无敌牛 欢迎参观我的个人博客:无敌牛 – 技术/著作/典籍/分享等 注意:本文章只做网络安全技术交流使用,切莫用来做坏事。 也可以叫一句话木马,一个意思。 设置监听 回连端口可以…...
django——admin后台管理1
一、admin后台管理 访问url进入: http://127.0.0.1:8000/admin 创建超级管理用户 终端输入以下命令: python manage.py createsuperuser (py36_pingping) E:\django学习\day03-django入门\demo>python manage.py createsuperuser Username: mo…...
QT图形/视图架构详解(一)
场景、视图与图形项 图形/视图架构主要由 3 个部分组成,即场景、视图和图形项,三者的关系如图所示: 场景、视图和图形项的关系 场景(QGraphicsScene 类) 场景不是界面组件,它是不可见的。场景是一个抽象的…...
h5 区分ios和安卓
h5 区分ios和安卓 const systemInfo uni.getSystemInfoSync(); if (systemInfo.platform "ios" || systemInfo.platform "android") {}h5 区分微信小程序与app用条件编译条件编译 js #ifdef MP-WEIXIN #endif...
爬虫基础知识点
最近看了看爬虫相关知识点,做了记录,具体代码放到了仓库,本文仅学习使用,如有违规请联系博主删除。 这个流程图是我使用在线AI工具infography生成的,这个网站可以根据url或者文本等数据自动生成流程图,挺…...
golang 实现简单redis服务3(实现多类型数据结构支持)
redis各种数据类型的工作原理stringlisthashset(集合)zset(有序集合)(思考1):为什么redis使用跳跃表而不是红黑树?(思考2): 都可以范围取值,为什么mysql使用b树不用跳跃表,为什么redis使用跳跃表不用b树? 之前的redis只实现了基本数据string类型的操作,那能不能实现多种数据类…...
【硬件测试】基于FPGA的4ASK调制解调通信系统开发与硬件片内测试,包含信道模块,误码统计模块,可设置SNR
目录 1.算法仿真效果 2.算法涉及理论知识概要 3.Verilog核心程序 4.开发板使用说明和如何移植不同的开发板 5.完整算法代码文件获得 1.算法仿真效果 本文是之前写的文章: 《基于FPGA的4ASK调制解调系统,包含testbench,高斯信道模块,误码率统计模块,可以设置不同SNR》 的…...
配置mysqld(读取选项内容,基本配置),数据目录(配置的必要性,目录下的内容,具体文件介绍,修改配置)
目录 配置mysqld 读取选项内容 介绍 启动脚本 基本配置 内容 端口号 数据目录的路径 配置的必要性 配置路径 mysql数据目录 具体文件 修改配置时 权限问题 配置mysqld 读取选项内容 介绍 会从[mysqld] / [server] 节点中读取选项内容 优先读取[server] 虽然服务…...
【roadMap】我转行软件测试的经历
软件测试这行咋样? 如果你简单了解过「软件测试工程师」这个岗位,就会知道它的基本特点: 待遇比开发低,比其他行业高入门丝滑,算是技术岗最简单的一类测试行业有细分领域:功能、性能、自动化… 每个行业…...
回归任务与分类任务应用及评价指标
能源系统中的回归任务与分类任务应用及评价指标 一、回归任务应用1.1 能源系统中的回归任务应用1.1.1 能源消耗预测1.1.2 负荷预测1.1.3 电池健康状态估计(SOH预测)1.1.4 太阳能发电量预测1.1.5 风能发电量预测 1.2 回归任务中的评价指标1.2.1 RMSE&…...
半导体制造全流程
半导体制造是一个极其复杂且精密的过程,主要涉及将硅片加工成功能强大的芯片。以下是半导体制造的全流程概述: 1. 硅材料制备 硅提纯: 使用冶金级硅,进一步提纯为高纯度硅(电子级硅),纯度可达 …...
Mac m2电脑上安装单机Hadoop(伪集群)
1. 引言 本教程旨在介绍在Mac 电脑上安装Hadoop 2. 前提条件 2.1 安装JDK Mac电脑上安装Hadoop,必须首先安装JDK,并配置环境变量(此处不做详细描述) 2.2 配置ssh环境 关闭防火墙 在Mac下配置ssh环境,防止后面启…...
React 第十六节 useCallback 使用详解注意事项
useCallback 概述 1、useCallback 是在React 中多次渲染缓存函数的 Hook,返回一个函数的 memoized的值; 2、如果多次传入的依赖项不变,那么多次定义的时候,返回的值是相同的,防止频繁触发更新; 3、多应用在 父组件为函…...
悬赏任务源码(悬赏发布web+APP+小程序)开发附源码
悬赏任务源码是指一个软件或网站的源代码,用于实现悬赏任务的功能。悬赏任务是指发布方提供一定的奖励,希望能够找到解决特定问题或完成特定任务的人。悬赏任务源码通常包括任务发布、任务接受、任务完成和奖励发放等功能的实现。搭建悬赏任务源码是一个…...
Collection接口
目录 一. Collection基本介绍 二. Collection中的方法及其使用 1. 添加元素 (1) 添加单个元素 (2) 添加另一集合中的所有元素 2. 删除元素 (1) 删除单个元素 (2) 删除某个集合中包含在其他集合中的元素 (3) 保留两个集合中的交集部分, 删除其他元素. 3. 遍历元素 (1) …...
电机驱动模块L9110S详解
电机驱动模块是一种用于控制和驱动电机的设备,它能够将控制信号转化为适合电机操作的电流和电压。通过电机驱动模块,可以实现对电机的速度、方向等参数进行精确控制。 今天我们要介绍的 L9110S 电机驱动适合大学生、工程师、个人DIY、电子爱好者们学习和…...
路由之间是怎么跳转的?有哪些方式?
1. React 路由跳转方式(React Router) 在 React 中,路由跳转通常使用 React Router 来管理。React Router 提供了不同的跳转方式。 <Link> 组件跳转 使用 <Link> 组件来进行路由跳转,它会渲染为一个 HTML <a> …...