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

Linux C语言:指针和指针变量

一、指针的作用

  • 使程序简洁、紧凑、高效
  • 有效地表示复杂的数据结构
  • 动态分配内存
  • 能直接访问硬件
  • 能够方便的处理字符串
  • 得到多于一个的函数返回值

二、内存、地址和变量 

1、内存地址 

2、变量和地址 

1)变量用来在程序中保存数据

比如: int k = 58; //声明一个int变量k,CPU为k分配4个字节,
可以存储数值58 

 2)关于变量

  • 输入变量的值
  • 打印变量的地址
  • 打印变量占用的内存空间

三、指针 

  • 指针变量一般形式如下:
<数据类型> * <指针变量名> ;
char * p ;

1. *,指针运算符,表示定义的是一个指针类型的变量
2. 数据类型,指针变量要保存地址,数据类型要和这个地址中保存的数据的数据类型保持一致。 

1、指针的初始化 

指针在说明的同时, 也可以被赋予初值,称为指针的初始化
一般形式:
<数据类型> *<指针变量名> = <地址量> ; 

int main() {
int a = 10; //在内存中开辟一块内存空间
int *p =&a; //使用&(取地址操作符),取出变量a的起始地址
//a变量占4个字节,将a的第一个字节的地址放在p
变量中,p就是一个指针变量
}

 

2、指针和变量 

四、指针的目标和“解引用”

1、指针的目标

  • 指针指向的内存区域中的数据称为指针的目标 
    int a = 126;
    int *p = &a;

2、指针的解引用 

3、关于指针的三种写法 

设p为一个指针,则:

  • p — 指针变量, 它的内容是地址量
  • *p — 指针的目标,它的内容是数据
  • &p — 指针变量占用的存储区域的地址,是个常量 

五、指针的赋值 

  • 指针的赋值运算指的是通过赋值运算符向指针变量送一个地址值
  • 向一个指针变量赋值时,送的值必须是地址常量或指针变量,不能是普通的整数(除了赋零以外)
  • 指针赋值运算常见的有以下几种形式: 

        ① 把一个普通变量的地址赋给一个具有相同数据类型的指针

double x=15, *px;
px=&x;

        ② 把一个已有地址值的指针变量赋给具有相同数据类型的另一个指针变量

float a, *px, *py;
px = &a;
py = px;

         ③ 把一个数组的地址赋给具有相同数据类型的指针。

int a[20], *pa;
pa = a; //等价 pa = &a[0]

六、指针的大小

         对于32位的系统,假设有32根地址线,那么假设每根地址线在寻址的时候产生高电平和低电平。那么32根地址线产生的地址就是32个(1或者0) 

总结:

  • 32位的系统,地址是32个0或者1组成二进制序列,地址需要4个字节的空间来存储,一个指针变量的大小就是4个字节。
  • 64位系统,有64个地址线,一个指针变量的大小就是8个字节
  • uname -m命令,查看系统是多少位 

七、空指针 

  • 不同于没有初始化的指针
  • 在C语言中,NULL本质是0 
#define NULL (void *)0 // 在C中NULL是强制类型转换为void *的0
  •  为什么指向0地址处?2个原因。

         ① 指针如果没有给定初始值,值是不确定的 

         ② 0地址是一个特殊地址,在一般的操作系统中都是不可被访问的,如果C语言程序员不按规矩(不检查是否等于NULL就去解引用)写代码直接去解引用就会触发段错误

八、野指针及成因 

1、什么是野指针

  • 指针指向的位置是不可知的(随机的、不正确的、没有明确指向的)
  • 指向被释放的内存或者没有访问权限的内存的指针(非法访问)。 

2、野指针是怎么造成的 

  • 野指针的错误来源就是指针定义了以后没有初始化,也没有赋值(总之就是指针没有明确的指向一个可用的内存空间),然后去解引用。 

        ① 指针没有初始化 

        ② 指针越界访问 

        ③ 指针指向的空间释放了 

3、野指针的危害 

  • 野指针指向别的变量(指针所指向的那个变量)的地址
  • 即指向了一个地址是不确定的变量,去解引用,结果是不可知的。 

① 段错误
        指向不可访问(操作系统不允许访问的敏感地址,譬如内核空间)的地址,结果是触发段错误 

② 程序错误被掩盖
        指向一个可用的、而且没什么特别意义的空间(譬如我们曾经使用过但是已经不用的空间),这时候程序运行不会出错,也不会对当前程序造成损害这种情况下会掩盖你的程序错误,让你以为程序没问题,其实问题是非常严重的 

③ 程序出现离奇错误
        指向了一个可用的空间,而且这个空间其实在程序中正在被使用(譬如说是程序的一个变量x),那么野指针的解引用就会刚好修改这个变量x的值,导致这个变量莫名其妙的被改变,程序出现离奇的错误。一般最终都会导致程序崩溃,或者数据被损害。 

4、如何避免野指针

        野指针的错误来源就是指针定义了以后没有初始化,也没有赋值(总之就是指针没有明确的指向一个可用的内存空间),然后去解引用。 

        ① 定义指针时,同时初始化为NULL
        ② 在指针使用之前,将其赋值绑定给一个可用地址空间
        ③ 在指针解引用之前,先去判断这个指针是不是NULL
        ④ 小心指针越界
        ⑤ 指针使用完之后,将其赋值为NULL
        ⑥ 避免返回局部变量的地址

int a = 10;
int *p = &a;
int *q = NULL;
if (a > 0){
int b = 20;
q = &b;
a += *q;
}
(*q)++;
*p = *q;

相关文章:

  • 用Python向Word文档添加页眉和页脚
  • Node.js 和 Vue 的区别的基本知识科普
  • 排名前五的 Android 数据恢复软件
  • 第一百零九节 Java面向对象设计 - Java抽象类和方法
  • 动手学深度学习33 单机多卡并行
  • 【 EI会议 | 西南大学主办 | 往届均已实现检索】第三届神经形态计算国际会议(ICNC 2024)
  • hana 中的缓存视图功能,类似ORACLE 中的 物化视图功能
  • Tinymce富文本编辑器在el-dialog中遮挡的问题
  • Jenkins 内置变量 和变量作用域
  • 【成品设计】基于物联网的停车管理系统设计与实现
  • Spring Boot:Java 应用开发高效之道
  • 数据结构之初识泛型
  • idea有这个类却报红,无法用快捷键找到
  • k8s+RabbitMQ单机部署
  • 面试题——Spring
  • [原]深入对比数据科学工具箱:Python和R 非结构化数据的结构化
  • 【mysql】环境安装、服务启动、密码设置
  • CSS3 聊天气泡框以及 inherit、currentColor 关键字
  • CSS实用技巧干货
  • Java IO学习笔记一
  • JavaScript 基础知识 - 入门篇(一)
  • k个最大的数及变种小结
  • Mysql5.6主从复制
  • ReactNativeweexDeviceOne对比
  • springboot_database项目介绍
  • TCP拥塞控制
  • vue的全局变量和全局拦截请求器
  • Vue源码解析(二)Vue的双向绑定讲解及实现
  • zookeeper系列(七)实战分布式命名服务
  • 不上全站https的网站你们就等着被恶心死吧
  • 关于 Linux 进程的 UID、EUID、GID 和 EGID
  • 力扣(LeetCode)56
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 区块链分支循环
  • 微信小程序实战练习(仿五洲到家微信版)
  • 协程
  • 学习笔记DL002:AI、机器学习、表示学习、深度学习,第一次大衰退
  • ​Spring Boot 分片上传文件
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • ###C语言程序设计-----C语言学习(6)#
  • #免费 苹果M系芯片Macbook电脑MacOS使用Bash脚本写入(读写)NTFS硬盘教程
  • #我与Java虚拟机的故事#连载12:一本书带我深入Java领域
  • $().each和$.each的区别
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (2020)Java后端开发----(面试题和笔试题)
  • (70min)字节暑假实习二面(已挂)
  • (C#)Windows Shell 外壳编程系列9 - QueryInfo 扩展提示
  • (C#)一个最简单的链表类
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (PySpark)RDD实验实战——取一个数组的中间值
  • (Redis使用系列) SpringBoot中Redis的RedisConfig 二
  • (二)Optional
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (六) ES6 新特性 —— 迭代器(iterator)
  • (每日持续更新)信息系统项目管理(第四版)(高级项目管理)考试重点整理第3章 信息系统治理(一)