C++:指针和引用

news2024/11/20 17:39:48

指针的基础

数据在内存当中是怎么样被存储的

数据在内存中的存储方式取决于数据的类型和计算机的体系结构

基本数据类型
整数类型:整数在内存中以二进制补码的形式存储。对于有符号整数,最高位为符号位,0 表示正数,1 表示负数。例如,在一个 32 位的系统中,int类型的整数5的二进制表示为00000000 00000000 00000000 00000101,而-5的二进制补码表示为11111111 11111111 11111111 11111011。不同大小的整数类型(如char、short、int、long等)所占用的内存字节数不同,其取值范围也不同。
浮点类型:浮点数在内存中的存储遵循 IEEE 754 标准。以单精度浮点数(float)为例,它占用 32 位内存,其中包括 1 位符号位、8 位指数位和 23 位尾数位。浮点数通过科学计数法的形式表示,指数部分采用偏移码存储,尾数部分则是二进制小数的有效数字。例如,浮点数3.14在内存中的存储形式是经过一系列转换后得到的二进制编码。
字符类型:字符类型通常占用 1 个字节的内存空间,其存储的是字符对应的 ASCII 码值或 Unicode 码值。例如,字符’A’的 ASCII 码值为 65,在内存中存储的二进制形式为01000001。
数组
数组是相同类型数据的集合,其元素在内存中是连续存储的。例如,一个包含 5 个int类型元素的数组int arr[5],在内存中会依次存储这 5 个整数,每个整数占用相应的字节数(如在 32 位系统中为 4 字节)。数组名可以看作是指向数组首元素的指针,通过指针的偏移可以访问数组中的各个元素。
结构体
结构体是不同类型数据的组合,其成员在内存中的存储顺序与结构体定义中的顺序一致。结构体的大小通常是其成员大小的总和,但由于内存对齐的要求,可能会存在一些额外的填充字节,以保证结构体的每个成员都能在适当的内存地址上对齐,从而提高访问效率。例如,定义一个结构体struct Student { char name[20]; int age; float score; };,其成员name、age和score会依次存储在内存中,并且可能会根据编译器的对齐规则进行适当的填充。
指针
指针存储的是内存地址,其大小通常与计算机的字长相同。例如,在 32 位系统中,指针占用 4 字节,而在 64 位系统中,指针占用 8 字节。指针所指向的数据类型决定了通过指针访问内存时所读取或写入的数据大小和格式。
字符串
在 C 语言中,字符串是以字符数组的形式存储的,并且以’\0’作为字符串的结束标志。例如,字符串"Hello"在内存中实际上存储为’H’、‘e’、‘l’、‘l’、‘o’、'\0’这 6 个字符的 ASCII 码值,占用 6 个字节的内存空间。而在一些高级语言中,字符串可能会有更复杂的存储结构和管理方式,但本质上也是存储字符序列的一种数据类型。

访问方式

直接访问
定义:直接访问是指通过变量名或地址直接对数据进行操作,即直接使用变量名来访问和修改其对应内存地址中的数据值。
示例:在大多数编程语言中,定义一个变量后,可以直接使用该变量名来进行赋值、读取等操作。例如在 C 语言中,int num = 10; 定义了一个整型变量 num 并初始化为 10,之后可以直接通过 num 来访问和修改这个值,如 num = 20; 就直接将变量 num 的值修改为 20。
优点:简单直观,易于理解和使用,代码的可读性较高,能够直接反映出对哪个变量进行了何种操作。
缺点:对于一些复杂的数据结构或需要动态分配内存的情况,直接访问可能不够灵活,难以对数据进行有效的组织和管理。
间接访问
定义:间接访问是指通过指针或引用等方式来访问数据,即先获取数据的地址,然后通过该地址来访问和操作数据。
示例:在 C 语言中,可以定义一个指针变量来存储另一个变量的地址,然后通过指针来间接访问该变量的值。例如,int num = 10; int *ptr = # 这里定义了一个指针变量 ptr,并将它指向变量 num 的地址,通过 *ptr 就可以间接访问和修改 num 的值,如 *ptr = 30; 此时 num 的值就被修改为 30 了。
优点:更加灵活,可以动态地分配和管理内存,方便地操作复杂的数据结构,如链表、树等。通过指针或引用,可以在不同的函数或模块之间共享和传递数据,而无需将数据本身进行复制,提高了程序的效率和内存的利用率。
缺点:使用间接访问需要对指针和内存管理有更深入的理解,否则容易出现指针错误,如空指针引用、野指针等,导致程序出现错误甚至崩溃。


#include <iostream>
using namespace std;

int main() {
    int i = 0;
    cout << "请输入i的值"  << endl;
    cin >> i;
    cout << "i = " << i << endl;//直接访问
    cout << "i在内存当中的地址是" << &i << endl;

    int* p = &i;

    cout << *p << endl;//间接访问
    cout << p << endl;
    cout << &p << endl;
    return 0;
}

在这里插入图片描述

指针变量作为函数参数传输


#include <iostream>
using namespace std;

int swapNumbers(int * numPtr1, int* numPtr2)
{
    int tmp;
    tmp = *numPtr1;
    *numPtr1 = *numPtr2;
    *numPtr2 = tmp;
    return 0;
}

int main() {
    int num1 = 90;
    int num2 = 88;
    swapNumbers(&num1,&num2);
    cout << "num1 = " << num1 << endl;
    cout << "num2 = " << num2 << endl;


    return 0;
}

在这里插入图片描述

指向数组的指针变量


#include <iostream>
using namespace std;



int main() {
    int arr[] = {1,2,3,4};
    int* ptr = arr;
    int* ptr1 = &arr[0];

    for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
    {
        cout << *(ptr + i) << " ";

    }
    cout << endl;

    for (int i = 0; i < sizeof(arr) / sizeof(int); i++)
    {
        cout << *(ptr1 + i) << " ";
    }
 


    return 0;
}

数组的第一个元素和数组名称指向的是同一个地址空间
在这里插入图片描述

引用


#include <iostream>
using namespace std;

int add(int& a, int& b)
{
    cout << a + b << endl;
    return 0;
}

int main() {
    int a = 99; 
    int b = 1;
    add(a, b);


    return 0;
}

在这里插入图片描述

const关键字

常量变量定义

#include <iostream>

int main() {
    // 定义一个常量整数,使用const关键字
    const int MAX_VALUE = 100;

    // 试图修改常量的值,会导致编译错误
    // MAX_VALUE = 200;

    std::cout << "常量MAX_VALUE的值为: " << MAX_VALUE << std::endl;

    return 0;
}

在这里插入图片描述

常量指针

#include <iostream>

int main() {
    int num = 50;

    // 定义一个常量指针,指针指向的内容不能通过该指针修改
    const int* ptr = &num;

    // 下面这行代码会导致编译错误,因为不能通过常量指针修改所指向的值
    // *ptr = 100;

    std::cout << "通过常量指针获取的值为: " << *ptr << std::endl;

    return 0;
}

在这里插入图片描述

指针常量

#include <iostream>

int main() {
    int num = 50;
    int num2 = 99;

    // 定义一个指针常量,指针本身的地址不能改变,但可以通过它修改所指向的值
    int* const ptr = &num;

    // 下面这行代码会导致编译错误,因为指针本身的地址不能改变
     //ptr = num2;

    *ptr = 100;

    std::cout << "修改后的值为: " << num << std::endl;

    return 0;
}![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/04721be84a0043bdb55e54457ad22754.png)
## 常引用

```c
#include <iostream>

int main() {
    int num = 50;

    // 定义一个常引用,引用所指向的内容不能通过该引用修改
    const int& ref = num;

    // 下面这行代码会导致编译错误,因为不能通过常引用修改所指向的值
    // ref = 100;

    std::cout << "通过常引用获取的值为: " << ref << std::endl;

    return 0;
}

在这里插入图片描述

函数参数中的 const

#include <iostream>

// 函数声明,参数为常引用,保证函数内部不会修改传入的值
void printValue(const int& value) {
    std::cout << "传入的值为: " << value << std::endl;
}

int main() {
    int num = 50;

    // 调用函数,传递变量的常引用
    printValue(num);

    return 0;
}

在这里插入图片描述

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

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

相关文章

MySQL更换瀚高语法更换

MySQL更换瀚高语法更换 一、前言二、语句 一、前言 水一篇,mysql更换瀚高之后&#xff0c;一些需要更换的语法介绍 > 二、语句 MySQL瀚高MySQL用法瀚高用法说明ifnull(x,y)coalesce(x,y)相同相同用于检查两个表达式并返回第一个非空表达式。如果第一个表达式不是 NULL&…

亚马逊云服务器(AWS):功能、优势与使用指南

亚马逊云服务器&#xff08;AWS&#xff09;概述 亚马逊云服务器&#xff08;Amazon Web Services&#xff0c;简称AWS&#xff09;是全球领先的云计算平台&#xff0c;提供一系列强大且灵活的云服务&#xff0c;帮助企业和开发者通过云基础设施实现数据存储、计算、分析和机器…

国产三维CAD 2025新动向:推进MBD模式,联通企业设计-制造数据

本文为CAD芯智库原创整理&#xff0c;未经允许请勿复制、转载&#xff01; 上一篇文章阿芯分享了影响企业数字化转型的「MBD」是什么、对企业优化产品设计流程有何价值——这也是国产三维CAD软件中望3D 2024发布会上&#xff0c;胡其登先生&#xff08;中望软件产品规划与GTM中…

小试牛刀-Anchor安装和基础测试

目录 一、编写目的 二、安装步骤 2.1 安装Rust 设置rustup镜像 安装Rust 2.2 安装node.js 2.3 安装Solana-CLI 2.4 安装Anchor CLI 三、Program测试 四、可能出现的问题 Welcome to Code Blocks blog 本篇文章主要介绍了 [Anchor安装和基础测试] 博主广交技术好友&…

如何在 Ubuntu 上安装 Emby 媒体服务器

Emby 是一个开源的媒体服务器解决方案&#xff0c;它能让你整理、流媒体播放和分享你的个人媒体收藏&#xff0c;包括电影、音乐、电视节目和照片。Emby 帮你集中多媒体内容&#xff0c;让你无论在家还是在外都能轻松访问。它还支持转码&#xff0c;让你能够播放各种格式的内容…

php交友源码交友系统源码相亲交友系统源码php社交系统php婚恋源码php社区交友源码vue 仿交友社交语聊技术栈

关于PHP交友、相亲、婚恋、社区交友系统的源码以及Vue仿交友社交语聊技术栈&#xff0c;以下是一些详细信息和建议&#xff1a; 一、PHP交友系统源码 系统架构设计 前端展示层&#xff1a;负责向用户提供直观友好的界面&#xff0c;包括注册登录页面、个人资料页面、匹配页面、…

【装饰珠——分组背包】

题目 代码 #include <bits/stdc.h> using namespace std; const int N 1e410; int cnt[5]; // 存兼容i等级及以下的孔的数目的桶 int l[N], p[N]; // l[i] i号珠子等级 p[i] i号珠子的上限 int w[N][8], f[N]; // w[i][j] i号珠子镶嵌j个的值 f[i] 孔数为i的最大值…

数据库审计工具--Yearning 3.1.9普民的使用指南

1 页面登录 登录地址:18000 &#xff08;不要勾选LDAP&#xff09; 2 修改用户密码 3 DML/DDL工单申请及审批 工单申请 根据需要选择【DML/DDL/查询】中的一种进行工单申请 填写工单信息提交SQL检测报错修改sql语句重新进行SQL检测&#xff0c;如检测失败可以进行SQL美化后…

Misc_01转二维码(不是二进制)

例题ctfhub/隐写v2.0 打开是一张图片 文件分离得到zip&#xff0c;爆破密码得到7878 打开得到0和1&#xff0c; !!!不是二进制转图片&#xff0c;直接是二维码 缩小能看到 000000000000000000000000000000000000000000000000000000000000000000000 000000000000000000000000…

AI工具百宝箱|任意选择与Chatgpt、gemini、Claude等主流模型聊天的Anychat,等你来体验!

文章推荐 AI工具百宝箱&#xff5c;使用Deep Live Cam&#xff0c;上传一张照片就可以实现实时视频换脸...简直太逆天&#xff01; Anychat 这是一款可以与任何模型聊天 &#xff08;chatgpt、gemini、perplexity、claude、metal llama、grok 等&#xff09;的应用。 在页面…

[论文阅读] 异常检测综述 Deep Learning for Anomaly Detection: A Review(一)

深度学习在异常检测中的应用&#xff1a;综述 摘要 异常检测&#xff0c;又称离群点检测或新奇性检测&#xff0c;在各个研究领域中数十年来一直是一个持续且活跃的研究领域。仍然存在一些独特的问题复杂性和挑战&#xff0c;需要先进的方法来解决。近年来&#xff0c;基于深…

PaddlePaddle 开源产业级文档印章识别PaddleX-Pipeline “seal_recognition”模型 开箱即用篇(一)

AI时代到来&#xff0c;各行各业都在追求细分领域垂直类深度学习模型&#xff0c;今天给大家介绍一个PaddlePaddle旗下&#xff0c;基于PaddleX Pipeline 来完成印章识别的模型“seal_recognition”。 官方地址&#xff1a;https://github.com/PaddlePaddle/PaddleX/blob/relea…

Ubuntu 22.04 上快速搭建 Samba 文件共享服务器

Samba 简介 Samba 是一个开源软件&#xff0c;它扮演着不同操作系统间沟通的桥梁。通过实现 SMB&#xff08;Server Message Block&#xff09;协议&#xff0c;Samba 让文件和打印服务在 Windows、Linux 和 macOS 之间自由流动。 以下是 Samba 的特点&#xff1a; 跨平台兼…

语义分割(semantic segmentation)

语义分割(semantic segmentation) 文章目录 语义分割(semantic segmentation)图像分割和实例分割代码实现 语义分割指将图片中的每个像素分类到对应的类别&#xff0c;语义区域的标注和预测是 像素级的&#xff0c;语义分割标注的像素级的边界框显然更加精细。应用&#xff1a…

QT基础 UI编辑器 QT5.12.3环境 C++环境

一、UI编辑器 注意&#xff1a;创建工程时&#xff0c;要勾上界面按钮 UI设计师界面的模块 UI编辑器会在项目构建目录中自动生成一个ui_xxx.h&#xff08;构建一次才能生成代码&#xff09;&#xff0c;来表示ui编辑器界面的代码&#xff0c;属于自动生成的&#xff0c;一定不…

Jmeter的后置处理器(二)

5--JSR223 PostProcessor 功能特点 自定义后处理逻辑&#xff1a;使用脚本语言编写自定义的后处理逻辑。支持多种脚本语言&#xff1a;支持 Groovy、JavaScript、BeanShell 等脚本语言。动态参数传递&#xff1a;将提取的数据存储为变量&#xff0c;供后续请求使用。灵活性高…

高阶C语言之五:(数据)文件

目录 文件名 文件类型 文件指针 文件的打开和关闭 文件打开模式 文件操作函数&#xff08;顺序&#xff09; 0、“流” 1、字符输出函数fputc 2、字符输入函数fgetc 3、字符串输出函数fputs 4、 字符串输入函数fgets 5、格式化输入函数fscanf 6、格式化输出函数fpr…

【Android、IOS、Flutter、鸿蒙、ReactNative 】实现 MVP 架构

Android Studio 版本 Android Java MVP 模式 参考 模型层 model public class User {private String email;private String password;public User(String email, String password) {this.email = email;this.password = password;}public String getEmail() {return email;}…

如何管理服务中的 “昂贵” 资源

如果接触过实际大型业务系统&#xff0c;就能体会到许多业务的正常运行都依赖于各种昂贵的第三方接口&#xff0c;调用一次都是要花元子的&#xff0c;例如 大语言模型nlp 服务&#xff1a;信息提取、分类等cv 服务&#xff1a;定位、信息提取、分类等 然而经常可能由于各种无…

蓝桥杯每日真题 - 第16天

题目&#xff1a;&#xff08;卡牌&#xff09; 题目描述&#xff08;13届 C&C B组C题&#xff09; 解题思路&#xff1a; 题目分析&#xff1a; 有 n 种卡牌&#xff0c;每种卡牌的现有数量为 a[i]&#xff0c;所需的最大数量为 b[i]&#xff0c;还有 m 张空白卡牌。 每…