C/C++的指针、万能指针、常量指针和指针常量

C/C++的指针

1、 指针的概念:

指针是一个变量,它存储的是另一个变量的内存地址,而不是变量的值。
指针变量的声明:在C/C++等语言中,我们通过使用星号*来声明一个指针变量。例如,int *ptr; 这行代码声明了一个名为ptr的指针变量,它指向一个整数类型的内存地址。
指针变量的赋值:我们需要将一个变量的地址赋值给指针变量。这可以通过使用取地址运算符&来实现。例如,int x = 10; ptr = &x; 这段代码将变量x的地址赋值给了指针变量ptr。
接下来,我们详细讲解指针变量的定义和使用:

2、指针变量的定义和使用

定义指针变量

在C/C++中,我们可以这样定义一个指针变量:

// 定义一个指向整数的指针变量  
int *ptr;  
  
// 定义一个指向字符的指针变量(通常用于字符串)  
char *str;  
  
// 定义一个指向浮点数的指针变量  
float *fptr;

使用指针变量

使用指针变量主要包括以下几个步骤:

初始化指针:在将指针用于访问或修改数据之前,必须确保它指向了一个有效的内存地址。这可以通过将某个变量的地址赋值给指针来实现。

int x = 10;  
int *ptr = &x;  // ptr现在指向变量x的内存地址

通过指针访问数据:一旦指针指向了一个有效的内存地址,我们就可以通过解引用指针(使用星号*)来访问或修改该地址中的数据。

// 通过指针访问x的值  
printf("Value of x: %d\n", *ptr);  // 输出: Value of x: 10  
  
// 通过指针修改x的值  
*ptr = 20;  
printf("Value of x after modification: %d\n", x);  // 输出: Value of x after modification: 20

指针的运算:指针可以进行一些基本的算术运算,如加法、减法,但这些运算的结果是基于指针所指向的数据类型的大小来计算的。

// 假设int类型占4个字节  
int arr[5] = {1, 2, 3, 4, 5};  
int *p = arr;  // p指向arr的第一个元素  
  
// p + 1将指向arr的第二个元素  
printf("Value at p + 1: %d\n", *(p + 1));  // 输出: Value at p + 1: 2

空指针和野指针:空指针(NULL)是一个特殊的指针值,它不指向任何有效的内存地址。野指针是指已经被释放或从未被初始化的指针,它们指向的内存地址是不确定的,使用它们可能导致程序崩溃或数据损坏。因此,在使用指针之前,一定要确保它指向了一个有效的内存地址。
动态内存分配:除了使用已经存在的变量地址外,我们还可以使用如malloc、calloc、realloc等函数来动态地分配内存,并将返回的地址赋值给指针。这种方式可以让我们在运行时根据需要分配或释放内存。

3、void*万能指针

void* 是一种通用指针类型,它允许你存储任何数据类型的地址,但是你不能直接通过 void* 类型的指针来访问或修改它所指向的数据,因为编译器不知道这个地址处的数据是什么类型。

当你需要将 void* 指针转换为其他类型的指针以进行解引用或操作时,你需要进行显式的类型转换(也称为强制类型转换)。在 C/C++ 中,这通常使用类型转换运算符(如 (int*)、(char*) 等)来完成。

下面是一个简单的例子,展示如何使用 void* 指针并在需要时将其转换为其他类型的指针:

#include <stdio.h>  
#include <stdlib.h>  
  
void print_int(void* ptr) {  
    // 将 void* 转换为 int*  
    int* int_ptr = (int*)ptr;  
    // 现在可以安全地解引用 int_ptr  
    printf("The value is: %d\n", *int_ptr);  
}  
  
int main() {  
    int x = 42;  
    // 将 int 变量的地址传递给 void* 类型的函数  
    print_int(&x);  
    return 0;  
}

在这个例子中,print_int 函数接受一个 void* 类型的参数,并在函数内部将其转换为 int* 类型的指针,然后解引用该指针以打印整数的值。

注意,虽然 void* 提供了灵活性,但使用它时也需要谨慎,因为它可能隐藏类型错误,导致程序在运行时出现错误。在使用 void* 时,最好确保你明确知道指针所指向的数据类型,并在使用前进行正确的类型转换。

4、常量指针和指针常量的概念

*const (号)左边放,是指针变量指向常量 - 常量指针

指的是当const关键字出现在指针声明中的星号*左边时,该指针是一个指向常量的指针,即你不能通过这个指针去修改它所指向的数据,但你可以改变这个指针指向的地址。例如:

const int *p; // p 是一个指向 int 类型常量的指针

在这个例子中,p 是一个指针,它可以指向一个 int 类型的变量,但是你不能通过 p 来修改那个变量的值(因为它是常量的)。但是,你可以让 p 指向另一个地址。

*const (号)右边放,是指针常量指向变量 - 指针常量

指的是当const关键字出现在指针声明中的星号*右边时,该指针是一个指针常量,即你不能改变这个指针指向的地址,但你可以通过这个指针去修改它所指向的数据。例如:

int *const q; // q 是一个指向 int 类型变量的指针常量

在这个例子中,q 是一个指针常量,你不能改变 q 指向的地址,但是你可以通过 q 来修改它所指向的 int 类型的变量的值。

*const (号)两边放,是指针常量指向常量 - 常量指针常量

指的是当const关键字在指针声明中既出现在星号左边又出现在星号右边时,该指针是一个指向常量的指针常量,即你不能改变这个指针指向的地址,也不能通过这个指针去修改它所指向的数据。例如:

const int *const r; // r 是一个指向 int 类型常量的指针常量

在这个例子中,r 是一个指针常量,你不能改变 r 指向的地址。同时,r 指向的是一个常量,所以你也不能通过 r 来修改它所指向的 int 类型的变量的值。

总结

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

揭秘抖音快速涨10000粉的方法:巨量千川投流让你轻松快速增粉

抖音已经成为了当今社交平台的热门之一&#xff0c;而如何快速涨粉已经成为了很多人关注的焦点。本文将揭秘一种高效的方式——巨量千川投流&#xff0c;通过官方真实流量和真实粉丝&#xff0c;每天快速涨关注&#xff0c;实现快速增粉1000~10万。 巨量千川投流是一种专业的抖…

Python-VBA函数之旅-pow函数

目录 一、pow函数的常见应用场景 二、pow函数使用注意事项 三、如何用好pow函数&#xff1f; 1、pow函数&#xff1a; 1-1、Python&#xff1a; 1-2、VBA&#xff1a; 2、推荐阅读&#xff1a; 个人主页&#xff1a;神奇夜光杯-CSDN博客 一、pow函数的常见应用场景 Py…

中小学校活动向媒体投稿报道宣传有哪些好方法

作为一所中小学校的教师,我肩负着向外界展示学校风采、宣传校园文化活动的重要使命。起初,每当学校举办特色活动或取得教学成果时,我都会满怀热情地撰写新闻稿,希望通过媒体的平台让更多人了解我们的故事。然而,理想丰满,现实骨感,我很快发现,通过电子邮件向媒体投稿的过程充满…

如何进行资产梳理

前言 为什么要进行资产梳理&#xff1f; 资产梳理方式一: 一、安全防护设备资产 二、对外开放服务项目资产 三、项目外包业务流程资产 资产梳理方式二: 一、业务资源梳理 二、设备资产梳理 三、第三方的服务信息梳理 风险梳理 风险有哪些&#xff1f; 一,账号权限风…

在此计算机上找不到autocad20*你需要安装autocad20*才可以安装此语言包,安装不成功的解决办法

因为AutoCAD2020未卸载干净导致&#xff0c;需要把AutoCAD2020的注册表清理干净&#xff0c;才可以安装 注册表打开&#xff0c;HKEY LOCAL MACHINE SOFTWARE Classesinstaller Products\7D2F3875100F0000102000060BECB6AB AHKEY LOCAL MACHINE SOFTWARE Classesinstaller Pro…

2024.5.9

#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);this->resize(1000,600);this->setFixedSize(1000,600);//设置按钮大小位置完成btn1 new QPushButton(&…

安卓开发--按键跳转页面,按键按下变色

前面已经介绍了一个空白按键工程的建立以及响应方式&#xff0c;可以参考这里&#xff1a;安卓开发–新建工程&#xff0c;新建虚拟手机&#xff0c;按键事件响应。 安卓开发是页面跳转是基础&#xff01;&#xff01;&#xff01;所以本篇博客介绍利用按键实现页面跳转&#…

随手笔记-GNN(朴素图神经网络)

自己看代码随手写的一点备忘录&#xff0c;自己看的&#xff0c;不喜勿喷 GNN (《------ 代码) 刚开始我还在怀疑为什么没有加weigth bias&#xff0c;已经为什么权重才两个&#xff0c;原来是对node_feats进行的network的传播&#xff0c;而且自己内部直接进行了。 下面是一…

Linux|进程地址空间

Linux|内存地址空间 现象基本概念理解如何理解地址空间什么是划分区域&#xff1f;地址空间的理解为什么要有地址空间&#xff1f;如何进一步理解页表和写时拷贝如何理解虚拟地址 Linux真正的进程调度方案 现象 #include <stdio.h> #include <string.h> #include …

兔子繁衍问题<C语言>

问题&#xff1a;一对兔子&#xff0c;从出生后第3个月起每个月都生一对兔子。小兔子长到第3个月后每个月又生一对兔子。假如兔子都不死&#xff0c;请问第1个月出生的一对兔子&#xff0c;至少需要繁衍到第几个月时兔子总数才可以达到N对&#xff1f; 分析&#xff1a; 可以观…

HTML5 Canvas发光Loading动画源码

源码介绍 之前我们分享过很多基于CSS3的Loading动画效果&#xff0c;相信大家都很喜欢。今天我们要来分享一款基于HTML5 Canvas的发光Loading加载动画特效。Loading旋转图标是在canvas画布上绘制的&#xff0c;整个loading动画是发光3D的视觉效果&#xff0c;HTML5非常强大。 …

Docker入门指南:Docker镜像的使用(二)

&#x1f340; 前言 博客地址&#xff1a; CSDN&#xff1a;https://blog.csdn.net/powerbiubiu &#x1f44b; 简介 在本章节中&#xff0c;将深入探讨 Docker 镜像的概念&#xff0c;以及如何使用镜像的一系列操作。 &#x1f4d6; 正文 1 什么是镜像 1.1 Docker镜像的简…

C++对象引用作为函数参数

使用对象引用作为函数参数最常见&#xff0c;它不但有指针作为参数的优点&#xff0c;而且比指针作为参数更简单、更方便。 引用方式进行参数传递&#xff0c;形参对象就是实参对象的“别名”&#xff0c;对形参的操作其实就是对实参的操作。 例如:用对象引用进行参数传…

每日Attention学习4——Spatial Attention Module

模块出处 [link] [code] [MM 21] Complementary Trilateral Decoder for Fast and Accurate Salient Object Detection 模块名称 Spatial Attention Module (SAM) 模块作用 空间注意力 模块结构 模块代码 import torch import torch.nn as nn import torch.nn.functional a…

新能源汽车动力电池热管理方案直冷方案原理简介

前言 随着新能源汽车的快速发展&#xff0c;动力电池作为其核心部件之一&#xff0c;对于其性能和寿命具有重要影响。动力电池在工作过程中会产生大量的热量&#xff0c;如果不能有效地进行热管理&#xff0c;将会导致电池温度升高、性能下降甚至损坏。因此&#xff0c;热管理…

论文阅读:Real-Time 3D Model Acquisition

前言&#xff1a; 本文为记录自己在NeRF学习道路的一些笔记&#xff0c;包括对论文以及其代码的思考内容。 小编目前在探索3DAIGC和3D打印交叉研究&#xff0c;在这方面有想法、经验的朋友都可以在b站留言交流下&#xff01;欢迎&#xff01; 公众号&#xff1a; AI知识物语…

QT--4

QT 使用定时器完成闹钟 #include "widget.h" #include "ui_widget.h"void Widget::timestart() {timer.start(1000); }void Widget::timeend() {timer.stop(); }Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(t…

OSPF NSSA区域

原理概述 OSPF 协议定义了 Stub 区域和 Totally Stub 区域这两种特殊的非骨干区域&#xff0c;为的是精简 LSDB 中 LSA 的数量&#xff0c;同时也精简路由表中的路由条目数量&#xff0c;实现优化设备和网络性能的目的。根据定义&#xff0c; Stub 区域或 Totally Stub 区域中是…

C++进阶:map与set简单自实现

目录 1. map与set封装红黑树的方式1.1 大概实现思路1.2 红黑树模板抽象1.3 红黑树的迭代器 2. 红黑树模板的实现2.1 结点结构的定义2.2 红黑树迭代器的实现2.2.1 迭代器的结构2.2.2 迭代器的方法实现 2.3 树结构的定义2.4 红黑树接口实现2.4.1 插入2.4.2 查找2.4.3 迭代器相关 …

HTML4(二)

文章目录 1 开发者文档2 基本标签2.1 排版标签2.2 语义化标签2.3 行内元素与块级元素2.4 文本标签2.5 常用标签补充 3 图片标签4 超链接标签4.1 跳转页面4.2 跳转文件4.3 跳转锚点4.4 唤起指定应用 5 列表5.1 有序列表5.2 无序列表5.3 自定义列表 6 表格6.1 基本结构6.2 表格标…
最新文章