news 2026/10/19 12:02:40

【C语言】 指针知识

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
【C语言】 指针知识

一、指针是什么

1.指针的定义

由于通过地址能找到所需的变量单元,可以说,地址指向该变量单元。因此,将地址形象化的称为“指针”。但平常我们所说的指针指的是指针变量。

int val=10; int *p; p=&val; *p=20;

2.指针的意义

分析上述代码:

定义一个常量val

int*p:表示声明一个指针变量p用于存储变量地址。

p=&val:表示p指向变量val,存储val的地址。

*p=20:解引用,修改该指针指向的值。

二、指针与const的结合

const int a=10; int b=20; //定义P指向a const int *p=&a;//*p具有常性 //p指向的值具有常性 *p=30//err int *const q=&b;//权限缩小 //p指向具有常性 q=&a;//err *q=50;//right

指针指向变量时,变量不被修改

void(const char*arr,conse*char brr) { assert(arr&&brr) if(arr==brr) return 0; while(*arr==*brr) { if(*arr=='\0') return 0; *arr++; *brr++; } return *arr>*brr?1:-1; }

修饰变量—>常变量—>变量居有常性特征(不可改变的量)

eg. const double PI=3.14 与double const PI=3.14完全相同(PI具有常性,不可被改变)

若PI=3.24//err

三、野指针与空指针

1.野指针与空指针定义

野指针就是指针指向的位置是不可知的(随机的、不正确的、没有明确限制的),指向一个非法的或已销毁的内存的指针,对系统造成不可预知的危险错误。也叫悬挂指针、空悬指针。

每一个指针类型都有一个特殊的值-----“空指针”。空指针与同类型的其他指针值都不同,它“保证与任何对象或函数的指针值都不相等”,也就是说空指针不会指向任何地方,它不是任何对象或函数的地址。简单点说,一个指针不指向任何数据,我们就称之为空指针,空指针用NULL表示。

2.造成野指针与空指针的原因

1.)指针未初始化

int main() { char*p; return 0; }

没有对指针p进行初始化

2.)指针越界访问

int main() { int arr[10] = {0}; int i = 0; int* p = arr; for (i = 0; i <= 10; i++) { *p = i; p++; } return 0; }

因为这里非法访问内存的同时试图改变空间的值,所以程序崩溃.

3.)指针指向的空间已经释放

char* fun() { char arr[] = "abc"; return arr; } int main() { char* p = fun(); printf("%s\n",p); return 0; } AI运行代码 c

运行上述代码,有以下警告:

虽然程序没有崩溃,但是这种写法是非法的,arr是局部变量,函数调用结束,栈帧销毁,局部变量空间归还给操作系统,我们没有使用权限,此时p就是野指针,*p属于非法访问内存。

//空指针 NULL

#define NULL 0; int *p=NULL;//0号地址空间不具有访问权限,(内存前128M禁止访问) *p=1; //崩

四、指针运算

1.指针+整型

int val = 10; int* p = &val; //*p解析4B空间 *p 解析的内存大小 取决于*p的类型 char num = 'a'; char* pn = &num; *pn -- 解析 1字节内存空间 *pn类型 *pn = 'b';

2.数据在内存中的存储方式

int val = 0x12345678 存储模式: 大端模式(大端字节序): 高位数据存储低地址位置(高低/低高) 低地址 高地址 0x12 0x34 0x56 0x78 --- > 0x12345678 小端模式(小端字节系): 低地址位置存储低位数据(低低/高高) 低地址 高地址 0x78 0x56 0x34 0x12 // ---> 0x12345678

大端模式,指数据的高字节保存在内存的低地址中,而数据的低字节保存在内存的高地址中。

小端模式,指数据的高字节保存在内存的高地址中,而数据的低字节保存在内存的低地址中。

验证大小端模式:

int val = 0x12345678; char* p = (char*)&val; // *p --> 0x12345678 if(*p == 0x78) 小 else 大端

3.指针+1

指针加1表示将指针的值增加1个单位。

int arr[] = {1,2,3,4,5}; int* p = arr; //数组名数组首元素地址 &arr[0] --- int* [1] [2] [3] [4] [5] | | p | | p+1 p+2 p+3 p+4 ---- 所指向的地址位置 int* 通过p访问每个元素值 | *p *(p+1) *(p+2) *(p+3) *(p+4) | *arr *(arr+1) *(arr+2) *(arr+3) *(arr+4) | arr[0] arr[1] arr[2] arr[3] arr[4] // arr+n 地址 等价于 &arr[n] // *(arr+n) arr[n] //arr[0] = 6; // *p = 6; // arr[0] p[0] *(p+0) p+1 能力 指针偏移量 从p所指地址开始 +1 指向1*sizeof(*p)位置 类型不变 p+1 类型 int*

eg:

int mystrlen(const char* str) { int count=0; for(int i=0;str[i]!='\0';i++) { count++; return 0; } }

利用指针更简便实现求字符串长度。

4.指针++,指针--

指针++是指针指向的内存地址向后移动一个所指数据类型的大小,指针--则是向前移动一个所指数据类型的大小,并非简单增减1.

int arr[]={1,2,3,4,5,6,7,8,9,10}; int *p=arr+2; *p++ ---->3 //p后置++先与其他运算符结合再自增1,值为3,指向4; *++p ---->5 //p前置++先自增1,再与其他运算符结合 指向5,值为5; ++(*p) ----> 6 //等价于 ++arr[4] (*p)++ ---->arr[4]++ 6

五、指针与数组

1.指针数组

元素为指针的数组 核心格式: 数据类型 数组名[数组长度]

int a,b,c; int *pa=&a,*pb=&b,*pc=&c; int *arr[]={&a,&b,&c}; const char* srr[]={"hello","abc","def"};

1.指针数组,是一维数组,每个元素都是int *;
2.指针数组经常结合二维数组使用,存储每行首元素的地址;
3.指针数组的本质是数组,这个数组中存储内容是指针;
4.定义 int *p[n];,[ ] 优先级高,先与 p 结合成为一个数组,再由 int*说明这是一个整型指针数组,它有 n 个指针类型的数组元素。

typedef long long(*PLLINT_2)[2]; PLLINT_2 P=&arr; PLLINT_2 q=&arr;//此时数组名为类型名

2.数组指针

指向整个数组的指针

核心格式:*数据类型(指针名)[数组长度];()优先级高强制让*先结合指针名,明确其为指针;

六、void*

x86下占四个字节

无类型指针,可以指向任何数据类型的内存地址,但无法直接解引用或进行指针运算。

//brr拷贝到arr void Copy(void* arr,const void* brr,size_t size) { char* pa=(char *)arr;//强转为char* const char* pb=(const char *)brr; for(int i=0;i<size;i++) { pa[i]=pb[i]; } }

int *q=&val; *q=1;q+1 ------>偏移量4B

void*p; 存储地址 p+1 ---->无法知道偏移量,void所占字节数不知;

void*变量名=任意类型的地址;

函数指针 不能解引用,不能加等

七、str系列函数

1.strlen求字符串长度,返回‘\0’前的字符个数(不含‘\0’);

2. strcpy(char*arr, const char *brr):将src指向的字符串复制到dest,需保证dest空间足够,会复制'\0'。

3. strcat(char *arr, const char *brr):将src指向的字符串追加到dest末尾,dest需有足够空间,会合并'\0'。

4. strcmp(const char *s1, const char *s2):比较两字符串,相等返回0;s1>s2返回1;s1<s2返回-1(按ASCII值比较)。

八、mem系列函数

1.memcpy 不考虑内存重叠问题 前提条件:另个内存独立

void mymemcpy(void* aim,void* src,size_t size) { char* paim=(char*)aim; const char*psrc=(const char*) src; while(size--) { *paim++=*src++; } }

2.memmove 考虑内存重叠问题 指针判断是否有重叠

void mymemove(void*aim,const void*src,size_t size) { if(src+size-1<aim) { mymemcpy(aim,src,size); } char* pendaim=(char*)aim+size-1; const char* pendsrc=(const char*)src+size-1; while(size--) { *pendaim--=*pendsrc--; } }

九、指针与函数

1.形参是指针

指针作为形参设计 ,形参修改影响实参,必须传递实参的地址,解引用

void changsize(int *psize) { (*psize)++; } int main() { int size=10; changsize(&size); return 0; }

2.返回值是指针(指针函数)

局部变量地址禁止返回,将arr设计为全局变量

int *operate(int a,int b) { int arr[]={a+b,a*b};//普通局部变量生存周期函数调用结束销毁 return arr;// 局部变量地址禁止返回 }

局部变量地址禁止返回,将arr设计为静态变量

//将arr设计为全局变量 int arr[2]; void operate(int a,int b) { arr[0]=a+b; arr[1]=a*b; return a+b; }
//arr设计为静态变量 int *operate(int a,int b) { static int arr[]={a+b,a*b};//延长局部变量的生存周期 该局部变量前方+static return arr; }

3.函数指针

是个指针,指向一个函数

long* funn1(){} //定义指针 指向funn1并完成函数调用 long*(*p1)()=funn1; p1();调用funn1函数
void (*signal(int sig, void (*func)(int)))(int); typedef void (*PFun)(int); PFun signal(int sig,PFun pfun); 调用: void func1(int a){ 如何复制操作 } void func2(int b){ 如何粘贴操作 } signal(CTRLC, func1); signal(CTRLV,func2);

不能解引用,不能加等

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/19 12:01:47

YOLOv5+DeepSORT车辆检测与跟踪项目全解析:数据集、训练与避坑指南

简介&#xff1a;一套融合YOLOv5与DeepSORT的车辆检测与追踪项目资源&#xff0c;面向计算机视觉开发者、算法研究人员以及智能交通应用工程师&#xff0c;适用于实时交通监控、停车场管理、无人驾驶环境感知等场景&#xff0c;能有效降低目标检测与多目标跟踪的技术门槛。压缩…

作者头像 李华
网站建设 2026/10/19 11:48:27

MySQL增删改查核心操作详解:INSERT SELECT UPDATE DELETE实战

MySQL这玩意儿&#xff0c;干开发的绕不开&#xff0c;做运维的绕不开&#xff0c;搞数据分析的同样绕不开。你去看招聘要求&#xff0c;十个岗位里八个写着"熟悉MySQL"&#xff0c;但真正问起来&#xff0c;很多人对增删改查的理解还停留在"会写几条SQL"的…

作者头像 李华
网站建设 2026/10/19 11:46:28

Python构建可审计算法决策系统:让每次决策有迹可循

算法决策系统这几年越来越常见&#xff0c;从信贷审批、价格调整到内容推荐&#xff0c;后台都是代码在替业务拿主意。可“拿主意”这三个字&#xff0c;通常在系统上线前没人仔细琢磨&#xff0c;等出了问题&#xff0c;比如某批用户被误伤、决策结果解释不清、监管或业务方要…

作者头像 李华
网站建设 2026/10/19 11:46:20

MySQL锁机制详解:并发控制与死锁优化策略

明白&#xff0c;这个标题确实值得好好展开。我准备了大量关于锁机制、并发控制、死锁排查与优化的实战内容&#xff0c;但需要你补全以下输入信息&#xff0c;我才能按你的具体要求输出完整博文&#xff1a; 项目标题: MySQL--》理解锁机制中的并发控制与优化策略 项目正文:…

作者头像 李华
网站建设 2026/10/19 11:42:45

嵌入式AI语音识别:在Cortex-M4上实现本地化语音控制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/19 11:40:01

VC++6.0 MFC计算器完整实现与答辩级调试指南

简介&#xff1a;本资源是一份基于VC6.0与MFC框架开发Windows桌面计算器的完整实践项目&#xff0c;面向C初学者及Windows GUI编程入门者&#xff0c;解决从零构建带消息响应、控件交互与数值运算功能的MFC对话框应用这一典型学习痛点。压缩包共31个文件&#xff0c;含6个头文件…

作者头像 李华