07-指针的概念与引用,索引

指针的概念与引用,索引

一、内存地址

字节

  • 定义: 字节(byte)是内存容量的一个单位,一个字节包含8个位(bit)。

地址

  • 定义: 内存地址是系统为了方便区分每一个字节的数据而对内存进行的逐一编号。该编号就是内存地址。

请添加图片描述

基地址

  • 单字节的数据:char 类型,其所在地址的编号就是该数据的地址。
  • 多字节的数据:int 类型,它占用4个连续的内存地址编号,其中最小的地址编号称为该变量的基地址。

在这里插入图片描述

取地址符号

  • 定义: 每一个变量实际上都对应了一片内存,可以通过取地址符号 &获取其地址

示例

#include <stdio.h>int main() {int a;char c;// 输出变量的地址printf("a的地址为:%p\n", (void*)&a);printf("c的地址为:%p\n", (void*)&c);return 0;
}

运行结果

a的地址为:0x7fffd5595d84
c的地址为:0x7fffd5595d83

在这里插入图片描述

注意事项:

  • 地址大小: 虽然不同的数据类型占用的内存空间不同,但是它们的地址所占用的内存空间(即地址的大小)是恒定的,由系统的位数决定(32位系统或64位系统)。
  • 地址和数据类型: 不同地址在表面上看似相同,但它们所代表的内存尺寸不同(与存放的数据类型相关)。访问这些地址时需要严格区分它们的逻辑关系。

总结:

  • 每个变量在内存中都有一个地址,可以通过取地址符号 & 来获得。
  • 地址的大小取决于系统的位数,而不是数据类型
  • 需要严格区分不同数据类型的地址,以正确访问内存中的数据。

二、 指针基础

2.1 指针的概念

  • 地址: &a 表示变量 a 的地址,这也被称为指针。指针是专门用来存放地址的变量,其大小由系统的位数决定(例如,32位系统中指针大小为4字节,64位系统中为8字节)。
  • 指针变量: 用来存储内存地址的变量,称为指针。

指针的定义语法

int a;         // 定义一个整型变量 a--> 定义一片内存,名字为a,约定好该内存用来存放整型变量
int *p;        // 定义一个指向整型数据的指针 p --> 定义一片内存名字叫p,约定好该内存用来存放整形数据的地址
char *p1;      // 定义一个指向字符数据的指针 p1
double *p2;    // 定义一个指向双精度数据的指针 p2

注意事项

  • 指针类型: 不决定该指针的大写哦,指针的类型用来告诉编译器如何解读和访问指针所指向的内存地址的数据类型和大小。
  • 指针大小: 指针的大小取决于系统的位数,而不是指向的数据类型。

2.2 指针的赋值与初始化

#include <stdio.h>int main() {int a = 100;int *p = &a;  // 定义并初始化指向整型数据的指针 pdouble d = 1024.1234;double *p1 = &d;  // 定义并初始化指向双精度数据的指针 p1float f;float *p2;  // 定义但未初始化指向浮点数据的指针 p2p2 = &f;  // 给指针 p2 赋值// 打印指针和指向的值printf("地址 p 指向的值: %d\n", *p);printf("地址 p1 指向的值: %f\n", *p1);return 0;
}

注意事项

  • 类型匹配: 不同类型的指针应该指向相应类型的变量地址。例如,int * 应该指向 int 类型的变量,double * 应该指向 double 类型的变量。
  • 初始化: 指针在定义时最好初始化,否则其默认值是未定义的,可能会指向不合法的内存地址,导致程序错误。
    在这里插入图片描述
示例代码解析
#include <stdio.h>int main() {int a = 100;int *p = &a;  // p 是指向 a 的指针,存储 a 的地址double d = 1024.1234;double *p1 = &d;  // p1 是指向 d 的指针,存储 d 的地址float f;float *p2;  // p2 是未初始化的指针p2 = &f;  // 给 p2 赋值,使其指向变量 f// 打印地址和指向的值printf("a 的地址: %p, 值: %d\n", (void*)p, *p);printf("d 的地址: %p, 值: %f\n", (void*)p1, *p1);printf("f 的地址: %p\n", (void*)p2);return 0;
}

运行结果:

a 的地址: 0x7ffee4b96f5c, 值: 100
d 的地址: 0x7ffee4b96f58, 值: 1024.123400
f 的地址: 0x7ffee4b96f54

2.3 指针的解引用与索引

**解引用(Dereferencing)**指针是通过指针获得它所指向的数据,即通过指针访问或修改指针所指向的变量的值。解引用操作符是 *

2.3.1 通过指针解引用与索引示例
#include <stdio.h>int main() {int a = 100;  // 定义一个整型变量 a 并赋值为 100int *p = &a;  // 定义一个指针 p,指向变量 a 的地址// 通过指针 p 修改 a 的值*p = 250;  // 解引用 p,将 a 的值修改为 250// 打印解引用指针 p 后的值printf("*p: %d\n", *p);  // 输出 *p 的值,即 a 的新值 250// 打印变量 a 的值printf("a: %d\n", a);  // 输出 a 的值,应该是 250return 0;
}
  1. 定义与初始化:

    int a = 100;
    int *p = &a;
    

    这里定义了一个整型变量 a 并赋值为 100,然后定义一个指针 p,并将 p 初始化为 a 的地址。

  2. 通过指针修改变量的值:

    *p = 250;
    

    解引用指针 p,即访问 p 所指向的内存地址,并将该地址的值修改为 250。这相当于直接将变量 a 的值修改为 250

  3. 打印指针解引用后的值:

    printf("*p: %d\n", *p);
    

    打印 *p 的值,即指针 p 所指向地址的值。因为前一步将 a 的值改为 250,所以 *p 的值也是 250

  4. 打印变量 a 的值:

    printf("a: %d\n", a);
    

    打印变量 a 的值,确认 a 的值已经被修改为 250

运行结果:

*p: 250
a: 250

重要注意事项

  • 指针的类型: 指针的类型决定了解引用时访问内存的方式和数据类型。例如,int *p 表示指向一个整型数据的指针,通过 *p 可以访问到一个整型变量。
  • 指针初始化: 在使用指针前应确保其已经被初始化。如果指针未初始化就解引用,可能会导致未定义行为(访问非法内存)。
  • 解引用操作符 *: 解引用操作符 * 用于获取指针指向地址的值,即通过指针访问内存中存储的数据。

2.4 野指针

野指针指的是一个指向未知或未分配内存区域的指针。使用野指针可能会导致程序崩溃、数据损坏,甚至系统崩溃。通常会出现段错误(Segmentation fault)。

2.4.1 野指针的危害
  • 段错误(Segmentation fault): 程序试图访问非法内存区域,导致崩溃。
  • 数据损坏: 野指针可能修改关键数据,导致数据不一致或程序行为异常。
  • 系统崩溃: 在极端情况下,野指针可能修改系统关键数据,导致系统崩溃。
2.4.2 产生原因
  1. 未初始化指针:

    int *p;
    
  2. 指向已释放的内存:

    int *p = malloc(sizeof(int));
    free(p);
    *p = 10;  // p 已经指向被释放的内存
    
  3. 指针越界:

    int arr[5];
    int *p = arr + 10;  // 越界访问
    
2.4.3 防止野指针的措施
  1. 指针初始化: 定义指针时进行初始化。

    int *p = NULL;
    
  2. 避免访问已释放的内存: 释放指针后,将指针置为 NULL

    free(p);
    p = NULL;
    
  3. 检查数组边界: 确保指针访问不越界。

2.5 空指针

空指针是指保存了地址值为零的指针。使用空指针可以避免一些野指针问题。

2.5.1 空指针的定义和使用
int *p = NULL;  // 定义一个指针并初始化为空指针
  • 访问空指针会导致段错误:

    *p = 250;  // 段错误
    
2.5.2 打印空指针
printf("%p - %d\n", NULL, NULL);  // 输出: (nil) - 0

2.6 指针运算

指针可以进行加法和减法操作,这意味着地址的移动。

2.6.1 指针加法和减法
  • 指针加法: 地址向上移动若干个目标类型的单位。
  • 指针减法: 地址向下移动若干个目标类型的单位。

示例代码

#include <stdio.h>int main() {long l;long *p = &l;int i;int *p1 = &i;printf("p: %p\n", p);printf("p+1: %p\n", p + 1);  // 向上移动一个 long 类型的大小printf("p1: %p\n", p1);printf("p1+1: %p\n", p1 + 1);  // 向上移动一个 int 类型的大小return 0;
}

运行结果

p: 0x7fffcb862610
p+1: 0x7fffcb862618  // p 向上移动 8 字节(long 的大小)
p1: 0x7fffcb86260c
p1+1: 0x7fffcb862610  // p1 向上移动 4 字节(int 的大小)

在这里插入图片描述

注意事项:

  • 指针类型决定了指针运算的单位: 指针在加减运算中,实际移动的大小取决于指针类型。
  • 避免使用未初始化的指针: 未初始化的指针可能指向任意位置,导致不可预测的行为。
  • 指针的类型和数据类型一致: 确保指针类型和所指向的数据类型一致,以避免错误的内存访问。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/23559.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java 主键生成策略之雪花算法

概述 项目中为了缓解数据库服务器压力和提高并发量进行分库分表,在新增数据时,如果此时按照传统方式使用数据库主键自增,那么在并发下ID可能会冲突; 使用UUID的话又因其无序会产生页分裂导致磁盘IO过大使得系统性能降低; 经过了解雪花算法根据其特点可以解决分布式系统中生成…

DockerCompose中部署Jenkins(Docker Desktop在windows上数据卷映射)

场景 DockerJenkinsGiteeMaven项目配置jdk、maven、gitee等拉取代码并自动构建以及遇到的那些坑&#xff1a; DockerJenkinsGiteeMaven项目配置jdk、maven、gitee等拉取代码并自动构建以及遇到的那些坑_jenkins的安装以及集成jdkgitmaven 提示警告-CSDN博客 Windows10(家庭版…

AI学习指南机器学习篇-逻辑回归正则化技术

AI学习指南机器学习篇-逻辑回归正则化技术 在机器学习领域&#xff0c;逻辑回归是一种常见的分类算法&#xff0c;它常用于处理二分类问题。在实际的应用中&#xff0c;为了提高模型的泛化能力和降低过拟合风险&#xff0c;逻辑回归算法通常会使用正则化技术。本文将介绍逻辑回…

待定待定待定

BindingNavigator C# 属性&#xff08;Property&#xff09; get set StringBuilder https://www.bilibili.com/video/BV15u4y1F72C/ C# 高级数据结构有哪些 List - 动态数组&#xff0c;可以动态增长和缩减&#xff0c;提供快速访问、添加和删除元素的功能。Dictionary<TK…

c#vb代码互转工具

下载地址&#xff1a; https://download.csdn.net/download/wgxds/88979921

EN 17104-2021室内用热塑性硬质保护墙板CE认证

室内用热塑性硬质保护墙板是指由同材质或非均质塑料板制成的&#xff0c;表面有或者没有装饰层&#xff0c;用于墙体的保护作用而非起结构作用&#xff0c;通过胶粘剂粘贴安装。 EN 17104-2021室内用热塑性硬质保护墙板CE认证项目 认证项目 测试标准 防火 EN 13501-1 挥发…

stm32中如何实现EXTI线 0 ~ 15与对应IO口的配置呢?

STM32的EXTI控制器支持19 个外部中断/ 事件请求。每个中断设有状态位&#xff0c;每个中断/ 事件都有独立的触发和屏蔽设置。 STM32的19个外部中断对应着19路中断线&#xff0c;分别是EXTI_Line0-EXTI_Line18&#xff1a; 线0~15&#xff1a;对应外部 IO口的输入中断。 线16&…

【MMU】——ARM 一级页表

文章目录 一级页表项即 entry 的格式如下 从上图可以看出 L1 页表项有四种可能类型 产生中止异常的故障条目。这可能是预取或数据中止、取决于访问类型。这实际上表示虚拟地址未映射 bit[1:0] = 00指向 L2 转换表的条目。这样就能将 1MB 的内存分页 bit[1:0] = 01。1MB 段转换…

STM32远程更新

1 IAP 概述 1.1 工作原理 在应用中编程&#xff08; IAP &#xff09;是一种在现场通过 MCU 的通信接口&#xff08;例如 UART,USB,CAN 和以太网 等&#xff09;进行固件升级的方式。 当启动微控制器时&#xff0c;您可以选择让它进入 IAP 模式以执行 IAP 代码&am…

Linux-用户管理与软件管理

用户授权 如果普通用户需要执行特殊操作&#xff0c;有两种方法 1、su - root 切换到root账号进行特殊操作&#xff0c;然后再返回到普通用户 2、sudo命令 命令&#xff1a;su 优点&#xff1a;使用简单 缺点&#xff1a;1、root密码容易泄露&#xff1b;2、普通用…

基于MBD开发汽车软件

MBD 原理及重要性 模型驱动开发(Model-Based Development,简称 MBD)是一种在现代工程领域中日益重要的方法。它的基本原理建立在以模型为核心的理念之上。 MBD 的核心概念包括模型的构建、使用和维护。模型在这里不仅仅是对系统或过程的简单描述,而是包含了丰富的信息和逻…

04-240606Spark笔记

04-240606Spark笔记 1.行动算子-2 save相关算子: 格式: def saveAsTextFile(path: String): Unit def saveAsObjectFile(path: String): Unit def saveAsSequenceFile(path: String,codec: Option[Class[_ <: CompressionCodec]] None): Unit 例子: val rdd sc.makeR…

【Python报错】已解决NameError: name ‘Image‘ is not defined

解决Python报错&#xff1a;NameError: name ‘Image’ is not defined 在使用Python进行图像处理时&#xff0c;我们经常使用Pillow库&#xff08;PIL的一个分支&#xff09;。如果你在尝试创建或处理图像时遇到了NameError: name Image is not defined的错误&#xff0c;这通…

史上最易懂的mysql锁 、mvvc分析

1 mysql中的锁类型&#xff1a; 1) 表锁 表共享锁(S):表级别的读锁&#xff0c;表共享锁之间是兼容的。 表排他锁(X): 表级别的写锁&#xff0c;表排他锁和任何锁(包括表排他锁)都不兼容(不包括意向锁)。 意向排他锁(IX): 获取行排他锁之前必须获取的意向排他锁&#xff0c;这…

关于python包导入问题的重思考

将顶层目录直接设置为一个包 像这样&#xff0c;每一个文件从顶层包开始导入 这样可以解决我的问题&#xff0c;但是要注意的时&#xff0c;要避免使用出现上下级出现同名包的情况&#xff0c;比如&#xff1a; AutoServer--AutoServer--__init__.py--__init__.py这种情况下…

腾讯云的身份证核验,找不到这个类

系统接入腾讯云的sdk&#xff0c;Class ‘TencentCloud\Common\Credential’ not found 以下方法核对一下看有没有做错&#xff0c;如果没有需要重启一下守护一般是能解决问的 这个错误表明PHP代码试图加载一个名为TencentCloud\Common\Credential的类&#xff0c;但是在指定…

绿联云NAS一些探索(1):SSH、包管理器探测、安装docker-compose等

绿联云NAS一些探索SSH、包管理器探测、安装docker-compose等 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at CSDN: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https:…

AI图书推荐:《如何利用ChatGPT在线赚钱》

这本书《如何利用ChatGPT在线赚钱》&#xff08;$100m ChatGPT_ How To Make Money Online With ChatGPT -- Sharp, Biily -- 2023 &#xff09;主要阐述如何利用ChatGPT这一强大的语言模型工具在互联网上创造收入。 以下是各章节内容的概要&#xff1a; **引言** - 介绍了Chat…

STM32F103单片机工程移植到航顺单片机HK32F103注意事项

一、简介 作为国内MCU厂商中前三阵营之一的航顺芯片&#xff0c;建立了世界首创超低功耗7nA物联网、万物互联核心处理器浩瀚天际10X系列平台&#xff0c;接受代理商/设计企业/方案商定制低于自主研发十倍以上成本&#xff0c;接近零风险自主品牌产品&#xff0c;芯片设计完成只…

spring整合kafka

原文链接&#xff1a;spring整合kafka_spring集成kafka-CSDN博客 1、导入依赖 <dependency><groupId>org.springframework.kafka</groupId><artifactId>spring-kafka</artifactId><version>2.5.10.RELEASE</version> </depende…