C++017-C++指针及其应用

news2025/4/28 2:53:49

文章目录

  • C++017-C++指针及其应用
    • C++指针及其应用
      • CSP-J目标
        • 1. 指针
          • 1.指针变量的定义、赋值
          • 2.指针的引用与运算
        • 2. 基于指针的数组访问
        • 3. 指针与字符串
          • 4. 结构体与指针
    • 在练习:
    • 总结

C++017-C++指针及其应用

在这里插入图片描述

在线练习:
http://noi.openjudge.cn/
https://www.luogu.com.cn/

C++指针及其应用

参考:

CSP-J目标

【 4 】指针
【 4 】基于指针的数组访问
【 4 】字符指针
【 4 】指向结构体的指针

1. 指针

C/C++指针是一种变量,其值为另一个变量的地址。指针可以通过解引用操作符(*)用于存储和检索地址所指向的值。通过指针,可以在函数之间传递和操作内存中的数据。指针在C/C++语言中是非常重要的概念。

1.指针变量的定义、赋值

在使用指针之前要先定义指针,对指针变量的类型说明,一般形式为:

 类型说明符 *变量名; 

其中,*表示这是一个指针变量,变量名即为定义的指针变量名,类型说明符表示该指针变量所指向的变量的数据类型。先通过例子看看指针与普通的变量有什么不同。
1、普通变量定义

 int a=3; 

定义了变量 a,是 int 型的,值为 3。内存中有一块内存空间是放 a 的值,对 a 的存取操作就是直接到这个内存空间存取。内存空间的位置叫地址,存放 3 的地址可以用取地址操作符“&”对 a 运算得到:&a。

#include <iostream>

using namespace std;

int main()
{
    int a=3;
    cout<<a<<endl;
    cout<<&a<<endl;
    return 0;
}

在这里插入图片描述

2、指针变量定义

 int *p=NULL; 

定义了一个指针变量 p,p 指向一个内存空间,里面存放的是一个内存地址。现在赋值为 NULL(其实就是 0,表示特殊的空地址)。

#include <iostream>

using namespace std;

int main()
{
    int a=NULL;
    cout<<a<<endl; // 0
    cout<<&a<<endl; // 0x61fe1c
    int *p=NULL;
    cout<<p<<endl; // 0
    cout<<&p<<endl; // 0x61fe10
    return 0;
}

在这里插入图片描述

3、给指针变量 p 赋值

 P=&a; 

即把 a 变量的内存空间地址(比如:XXX)给了 p。显然,直接对 p 存取,操作的是地址。通过这个地址间接地操作,才是整数 3。P 的间接操作
要使用指针操作符*, 即*p 的值才是 3。设有指向整型变量的指针变量 p,如要把整型变量 a 的地址赋予 p 可以有以下两种方式:
①指针变量初始化的方法

 int a; 
 int *p=&a; 

②赋值语句的方法

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

不允许把一个数赋予指针变量,故如下的赋值是错误的:

 int *p;
 p=1000

。被赋值的
指针变量前不能再加“*”说明符,故如下的赋值也是错误的:

*p=&a;

完整代码:

#include <iostream>

using namespace std;

int main()
{
    int a; int *p; p=&a;
    // *p = &a; // invalid conversion from 'int*' to 'int' [-fpermissive]|
    // p=1000;  invalid conversion from 'int' to 'int*' [-fpermissive]|
    cout<<&a<<" -- "<<p<<endl; //
    return 0;
}

指针的几个相关操作说明表

说明样例
指针定义: 类型说明符 *指针变量名;int a=10; int *p;
取地址运算符: &;p=&a;
间接运算符: *指针变量名;*p=20;
指针变量直接存取的是内存地址;cout<<p; 结果可能是:0x4097ce;
间接存取的才是储存类型的值;cout<<*p; 结果是:20

指针变量同普通变量一样,使用之前不仅要定义说明,而且必须被赋值具体的值,未经赋值的指针变量不能使用。如定义了

int a; int *p=&a;
// 则*p 表示 p 指向的整型变量

而p 中存放的是变量 a 占用单元的起始地址,所以*p 实际上访问了变量 a,也就是说*p 与 a等价。

2.指针的引用与运算

在这里插入图片描述

【例 2】输入 N 个整数,使用指针变量访问输出。

#include<cstdio>
using namespace std;
int a[101],n;
int main()
{
    scanf("%d",&n);
    for (int i=1; i<=n; i++)
        scanf("%d",&a[i]);
    int *p=&a[1]; //定义指针变量 int *p,初始化为数组开始元素的地址,即 a[1];
    printf("&a[1] %d \n",&a[1]);
    for (int i=1; i<=n; i++)
    {
        printf("%d --> %d \n",*p,p);
        p++; //p 指向下一个数,详见说明
    }
    return 0;
}

在这里插入图片描述
【说明】

“p++”的意思是“广义的加 1”,不是 p 的值(地址)加 1,而是根据类型 int 增加 sizeof(int),即刚好“跳过”一个整数的空间,达到下一个整数。
类似的:
①、“p–”就是向前“跳过”一个整数的空间,达到前一个整数。
②、(p+3)就是指向后面第 3 个整数的地址。

【例 3】无类型指针运用举例。
有时候,一个指针根据不同的情况,指向的内容是不同类型的值,我们可以先不明确定义它的类型,只是定义一个无类型的指针,以后根据需要再用强制类型转换的方法明确它的类型。

#include<iostream>
using namespace std;
int a=10;
double b=3.5;
void *p;
int main()
{
    p=&a; //p 的地址赋值
    cout<<*(int*)p<<endl; //必须明确 p 指向的空间的数据类型,详见说明
    p=&b;
    cout<<*(double*)p<<endl;
    p=&b;
    cout<<*(long long*)p<<endl;
    return 0;
}

在这里插入图片描述

必须明确 p 指向的空间的数据类型,类型不一样的不仅空间大小不相同,储存的格式也不同。如果把

cout<<*(double*)p<<endl;

改成

cout<<*(long long*)p<<endl;

输出的结果将
是:4615063718147915776。

2. 基于指针的数组访问

在这里插入图片描述

#include<cstdio> 
using namespace std; 
int main() 
{ 
 int a[5],i,*pa=a; //定义整型数组和指针,*pa=a 可以在下一行 pa=a; 
 for (i=0;i<5;i++) 
 scanf("%d",a+i); //可写成 pa+i 和 &a[i] 
 for (i=0;i<5;i++) 
 printf("a[%d]=%d\n",i, *(a+i)); //指针访问数组,可写成*(pa+i)或 pa[i]或 a[i] 
 return 0; 
}

在这里插入图片描述
在这里插入图片描述

【例 6】动态数组,计算前缀和数组。b 是数组 a 的前缀和的数组定义:
b[i]=a[1]+a[2] +…+a[i],即 b[i]是 a 的 i 个元素的和。

#include<cstdio>
using namespace std;
int n;
int *a; //定义指针变量 a,后面直接当数组名使用
int main()
{
    scanf("%d",&n);
    a=new int[n+1]; //向操作系统申请了连续的 n+1 个 int 型的空间
    for (int i=1; i<=n; i++)
        scanf("%d",&a[i]);
    for (int i=2; i<=n; i++)
        a[i]+=a[i-1];
    for (int i=1; i<=n; i++)
        printf("%d ",a[i]);
    return 0;
}

在这里插入图片描述

【说明】
动态数组的优点:在 OI 中,对于大数据可能超空间的情况是比较纠结的事,用小数组只的部分分,大数组可能爆空间(得 0 分)。使用“动态数组”,可以在确保小数据没问题的前提下,尽量满足大数据的需求。

3. 指针与字符串

在这里插入图片描述

#include<cstdio>
using namespace std;
int n;
int *a; //定义指针变量 a,后面直接当数组名使用
int main()
{
    char str1[]="I love China!";
    printf("%s\n", str1);
    char *str="I love China!";
    printf("%s\n", str);
    return 0;
}

二、字符串指针作函数参数
将一个字符串从一个函数传递到另外一个函数,可以用地址传递的方法,即用字符数组名作参数或用指向字符的指针变量做参数。在被调用的函数中可以改变字符串内容,在主调函数中可以得到改变了的字符串。

【例 8】输入一个长度最大为 100 的字符串,以字符数组的方式储存,再将字符串倒序储存,输出倒序储存后的字符串。(这里以字符指针为函数参数)

#include<cstdio>
#include<cstring>
using namespace std;
void swapp(char &a,char &b) //交换两个字符的位置
{
    char t;
    t=a;
    a=b;
    b=t;
}
void work(char* str)
{
    int len=strlen(str); //strlen(str)这个函数返回的是 str 的长度,
//需包含头文件 cstring
//这个函数的原型是"size_t strlen(const char* str)"
    for (int i=0; i<=len/2; ++i)
        swapp(str[i],str[len-i-1]);
}
int main()
{
    char s[110];
    char *str = s;
    gets(s);
    work(str);
    printf("%s",s);
    return 0;
}

在这里插入图片描述

4. 结构体与指针

在这里插入图片描述

#include<cstdio>
using namespace std;
struct student
{
    char name[20];
    char sex;
    int score;
} s[3]= {{"xiaoming",'f',356},
    {"xiaoliang",'f',350},
    {"xiaohong",'m',0}
};
int main()
{
    student *p;
    printf("Name Sex Score\n");
    for (p=s; p<s+3; p++)
        printf("%-9s%3c%7d\n",p->name,p->sex,p->score);
    return 0;
}

在这里插入图片描述

在这里插入图片描述

在练习:

http://noi.openjudge.cn/

总结

本系列为C++学习系列,会介绍C++基础语法,基础算法与数据结构的相关内容。本文为C++指针及其应用案例,包括相关案例练习。

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

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

相关文章

设计师都在用的6个免费设计素材网站~

本期给大家推荐几个设计师都在用的素材网站&#xff0c;免费下载&#xff0c;赶紧收藏起来吧~ 1、菜鸟图库 https://www.sucai999.com/?vNTYwNDUx 菜鸟图库是我推荐过很多次的网站&#xff0c;主要是站内素材多&#xff0c;像平面、UI、电商等设计素材都能找到&#xff0c;还…

零售数据可视化|人、货、场、供、财报表分享

有没有零售数据可视化的例子&#xff0c;让大家看看BI零售数据可视化的效果&#xff1f;有&#xff0c;奥威BI零售标准方案提供了数十张BI数据可视化报表&#xff0c;覆盖人、货、场、供、财等核心业务&#xff0c;既可以让大家一次性体验零售数据可视化报表效果&#xff0c;也…

vLive带你走进虚拟直播世界

虚拟直播是什么&#xff1f; 虚拟直播是基于5G实时渲染技术&#xff0c;在绿幕环境下拍摄画面&#xff0c;通过实时抠像、渲染与合成&#xff0c;再推流到直播平台的一种直播技术。尽管这种技术早已被影视工业所采用&#xff0c;但在全民化进程中却是困难重重&#xff0c;面临…

GEE:Gmeans

G-means是一种聚类算法,它是基于K-means算法的改进版本。K-means算法的一个主要缺点是需要事先指定聚类的数量,而G-means算法则可以自动确定聚类的数量。 G-means算法使用了类似于K-means的迭代过程,但在每次迭代时,它会检查每个聚类是否可以继续细分为两个子聚类。这个检…

怎么免费制作logo?logo免费设计在线生成,从此设计不求人

你有没有因为Logo制作而烦恼过&#xff1f;对于很多人来说&#xff0c;logo制作是一项比较大的工程&#xff0c;需要专门的设计师才能完成。但是请人设计费用高还很费时间&#xff0c;还需多次沟通修改。其实&#xff0c;我们可以自己免费制作logo&#xff0c;下面&#xff0c;…

pytorch2.0 起步

参考&#xff1a;https://pytorch.org/get-started/pytorch-2.0/#ask-the-engineers-20-live-qa-series 总览 特性 fastermore pythonicas dynamic as ever torch.compile&#xff0c;部分零件由C迁移到Python,加强torch.compile的新技术有TorchDynamo, AOTAutograd, PrimT…

第十八章 React中的样式模块化处理

在React中组件如何使用本地的样式&#xff0c;而不对其他组件产生影响呢&#xff1f;我们这里需要使用样式的模块化处理&#xff0c;使得组件的样式只在该组件内部起作用。 这里我们通过两个组件应用说明。 定义组件 定义Hello组件与自定义样式 Hello/index.css .title{co…

Win 11 上在VMware 15安装时Ubuntu20.04注意事项(避坑必看)

遇到的问题 https://zhuanlan.zhihu.com/p/141033713 win11不兼容vm–VMware Workstation 与 Device/Credential Guard 不兼容。 https://zhuanlan.zhihu.com/p/428362751 打开控制面板-程序-启用或关闭Windows功能&#xff0c;发现win11没有Hyper-V&#xff0c;别慌&#xf…

算法设计 - 二分法和三分法,洛谷P3382

二分法 二分查找&#xff1a;找目标值位置 二分法是一种适用于特殊场景下的分治算法。 这里的特殊场景指的是&#xff0c;二分法需要作用在一个具有单调性的区间内。 比如&#xff0c;我们熟知的二分查找&#xff0c;就是一种二分法的具体实现&#xff0c;二分查找必须在一…

【云原生】阿里云ACK部署MySQL 数据持久化存储

思路图 一、概述 ACK介绍 阿里云容器服务Kubernetes版(Alibaba Cloud Container Service for Kubernetes,简称容器服务ACK)是全球首批通过Kubernetes一致性认证的服务平台,提供高性能的容器应用管理服务,支持企业级Kubernetes容器化应用的生命周期管理,轻松高效地在云端…

MAE论文阅读《Masked Autoencoders Are Scalable Vision Learners》

文章目录动机方法写作方面参考Paper: https://arxiv.org/pdf/2111.06377.pdf 动机 首先简要介绍下BERT&#xff0c;NLP领域的BERT是基于Transformer架构&#xff0c;并采取无监督预训练的方式去训练模型。它提出的预训练方法在本质上是一种masked autoencoding&#xff0c;也就…

【CSS】定位 ⑤ ( 子元素绝对定位 父元素相对定位 | 代码示例 )

文章目录一、子元素绝对定位 父元素相对定位二、代码示例一、子元素绝对定位 父元素相对定位 绝对定位 要和 带有定位 的 父容器 搭配使用 ; 子元素 使用绝对定位 , 父元素要使用 相对定位 ; 子元素使用 绝对定位 , 在布局中不会保留其位置 , 子元素完全依赖 父容器 的位置 ,…

阿里巴巴春招的后端面经来啦~

操作系统 一个操作系统&#xff0c;我们在衡量它的内存占用的时候&#xff0c;它一般会有哪些内存的部分&#xff1f; 读者答&#xff1a;堆和栈 补充&#xff1a; 这个其实是问你对free命令的理解。 主机的内存做一些清理的动作。你知道这里面会涉及到对哪些内存区域进行操…

大数据任务调度器 —— Azkaban 3.0 进阶应用

文章目录任务依赖任务重试JavaProcess 进程任务提交条件执行自定义条件预定义条件定时执行邮件警告前言&#xff1a;Azkaban 搭建以及基础介绍&#xff0c;查看这篇博客 —— 大数据任务调度器 —— Azkaban 3.0 部署与简单应用 任务依赖 Azkaban 中的任务依赖设置十分简单&…

OpenCV中的相机标定

之前在https://blog.csdn.net/fengbingchun/article/details/130039337 中介绍了相机的内参和外参&#xff0c;这里通过OpenCV中的接口实现对内参和外参的求解。 估计相机参数的过程称为相机标定(camera calibration)。相机标定是使用已知的真实世界模式(例如棋盘)来估计…

从风靡全球到风口,他们是如何做到的?

大家好&#xff0c;我是湖北鑫优尚电子商务。我们是从2019年下半年就注意到了TikTok的风口&#xff0c;并在2020年初&#xff0c;团队就开始投入TikTok的运营及商业变现。从2019年起&#xff0c;围绕TikTok一系列的产品功能迭代和商业模式开放的声音一直不绝于耳&#xff0c;直…

零基础可以学习数据分析吗,有没有好的培训机构推荐?

数据分析从沿海火到了中西部的软件园&#xff0c;从传统互联网企业火到了新经济领域&#xff0c;火到了第一二产业。数字化成为这个时代的标签&#xff0c;而数据也成为了最有价值的资源&#xff0c;更多企业重视数据&#xff1b;因为有了真实数据的支撑&#xff0c;所有的决策…

快速排序(挖坑法 前后指针法 非递归版本)

上一次我们说了快速排序的hoare的版本&#xff0c;但是该版本有很多问题&#xff0c;首先是需要控制很多边界&#xff0c;比较复杂一点 其次就是上一次的快速排序还是有很多的其他问题 我们试着想一下&#xff0c;如果我们用快速排序拍有序数组&#xff0c;那会怎么样&#x…

数字化和自动化的潮流:外贸企业如何应对?

当今世界正面临着数字化和自动化的浪潮&#xff0c;这些技术的应用正在深刻地改变着各个领域的生产、交易和管理方式。尤其在外贸行业&#xff0c;数字化和自动化的应用已成为一种趋势和必然。在本文中&#xff0c;我们将探讨数字化和自动化对外贸行业的影响和挑战&#xff0c;…

Windows环境下实现设计模式——解释器模式(JAVA版)

我是荔园微风&#xff0c;作为一名在IT界整整25年的老兵&#xff0c;今天总结一下Windows环境下如何编程实现解释器模式&#xff08;设计模式&#xff09;。 不知道大家有没有这样的感觉&#xff0c;看了一大堆编程和设计模式的书&#xff0c;却还是很难理解设计模式&#xff…