C++中数组和指针的关系(区别)详解

C++中数组和指针的关系(区别)详解

本文转自:http://c.biancheng.net/view/1472.html

博主在阅读后将文中几个知识点提出来放在前面:

  1. 没有方括号和下标的数组名称实际上代表数组的起始地址,这意味着数组名称实际上就是一个指针。
  2. 在数学语句中使用指针时,它不像常规变量那样工作。
  3. 向指针添加值时并要解引用时,括号非常重要。
  4. array[index] 相当于 *(array + index)。
  5. C++ 不会对数组执行边界检查。
  6. 不仅指针符号可以与数组名称一起使用,而且下标符号也可以与指针一起使用。
  7. 可以使用地址运算符来获取数组中单个元素的地址。
  8. 数组名称和指针变量的唯一区别是,不能改变数组名称指向的地址,即数组名称可视为一个指针常量。

我们知道,没有方括号和下标的数组名称实际上代表数组的起始地址,这意味着数组名称实际上就是一个指针。下面程序通过显示与间接运算符一起使用的数组名称来说明这一点。

// This program shows an array name being dereferenced with the * operator.
#include <iostream>
using namespace std;
int main()
{short numbers[] = {10, 20, 30, 40, 50};cout << "The first element of the array is ";cout << *numbers << endl;return 0;
}

程序输出结果:

The first element of the array is 10

numbers 在上面程序中的作用类似于指向数组起始地址的指针,所以当 numbers 被解引用时,第一个元素被检索出来。那么,如何使用间接运算符来检索数组的全部内容呢?请记住,数组元素是一起存储在内存中的,如图 1 所示。
在这里插入图片描述

既然 numbers 是 numbers[0] 的地址,那么给 numbers 添加值岂不是就可以获得数组中其他元素的地址了?这样想当然很有道理,但是,这里有一个知识点非常重要,即:在数学语句中使用指针时,它不像常规变量那样工作

在 C++ 中,当给一个指针添加一个值的时候,实际上添加的值是把这个值乘以指针引用的数据类型的大小。换句话说,如果给 numbers 加 1,实际上就是给 numbers 加上 1 X sizeof(short);如果给 numbers 加 2,实际上就是给 numbers + 2 X sizeof(short),以此类推。在 PC 上,这意味着以下说法是真实的,因为 short(短整数)通常使用 2 个字节:

  • *(numbers +1)是指地址 numbers + 1X2 处的值。
  • *(numbers + 2)是指地址 numbers + 2X2 处的值。
  • *(numbers + 3)是指地址numbers + 3X2 处的值。

以此类推。

这种自动转换意味着数组中的元素可以通过使用其下标或通过将下标添加到指向数组的指针来检索。既然表达式 *numbers 与 *(numbers + 0) 相同,它可以检索数组中的第一个元素,那么*(numbers + 1) 就可以检索第二个元素。同样,*(numbers+2) 即可检索第三个元素,以此类推。图 2 显示了下标表示法和指针表示法的等价性。

在这里插入图片描述

注意,向指针添加值时,括号非常重要。* 运算符优先于 + 运算符,所以表达式 *numbers + 1 不等于 *(numbers + 1)。表达式 *numbers + 1 的意思是将数组的第一个元素的内容加 1, 而 *(numbers + 1) 则是先给 numbers 加 1,然后对其进行解引用。

下面的程序使用指针符号显示了被访问数组的整个内容:

//This program processes an array using pointer notation.
#include <iostream>
using namespace std;
int main()
{const int SIZE = 5; // Size of the arrayint numbers[SIZE]; // Array of integers// Get values to store in the array// Use pointer notation instead of subscriptscout << "Enter " << SIZE << " numbers: ";for (int count = 0; count < SIZE; count++)cin >> *(numbers + count);// Display the values in the array// Use pointer notation instead of subscriptscout << "Here are the numbers you entered:\n";for (int count = 0; count < SIZE; count++)cout << * (numbers + count) << " ";cout << endl;return 0;
}

程序输出结果:

Enter 5 numbers: 5 10 15 20 25
Here are the numbers you entered:
5 10 15 20 25

在使用数组时,请记住一个规则,即**array[index] 相当于 *(array + index) **。

另外,请注意C++ 不会对数组执行边界检查。当使用指针遍历一个数组时,有可能会给指针一个越出数组边界的地址。

要理解数组名称和指针之间的密切关系,请看下面的程序。它定义了一个 double 数组和一个 double 指针,该指针分配了数组的起始地址。随后,不仅指针符号可以与数组名称一起使用,而且下标符号也可以与指针一起使用

// This program uses subscript notation with a pointer
// variable and pointer notation with an array name.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{const int NUM_COINS = 5;double coins[NUM_COINS] = {0.05, 0.1, 0.25, 0.5, 1.0};double *doublePtr; // Pointer to a double// Assign the address of the coins array to doublePtrdoublePtr = coins;// Display the contents of the coins array// Use subscripts with the pointer!cout << setprecision (2);cout << "Here are the values in the coins array:\n";for (int count = 0; count < NUM_COINS; count++)cout << doublePtr [count] << " ";// Display the contents of the coins array again, but this time use pointer notation with the array name!cout << "\nAnd here they are again:\n";for (int count = 0; count < NUM_COINS; count++)cout << *(coins + count) << " ";cout << endl;return 0;
}

程序输出结果:

Here are the values in the coins array:
0.05 0.1 0.25 0.5 1
And here they are again:
0.05 0.1 0.25 0.5 1

注意,当一个数组的地址分配给一个指针时,就不需要地址运算符了。由于数组的名称已经是一个地址,所以使用 & 运算符是不正确的。但是,可以使用地址运算符来获取数组中单个元素的地址

例如,&numbers[1] 得到 numbers[1] 的地址。在程序下面程序中就使用了该技巧。

// This program uses the address of each element in the array.
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{const int NUM_COINS = 5;double coins[NUM_COINS] = {0.05, 0.1, 0.25, 0.5, 1.0};double *doublePtr; // Pointer to a double//Use the pointer to display the values in the arraycout << setprecision (2);cout << "Here are the values in the coins array:\n";for (int count = 0; count < NUM_COINS; count++){doublePtr = &coins[count];cout << *doublePtr << " ";}cout << endl;return 0;
}

程序输出结果:

Here are the values in the coins array:
0.05 0.1 0.25 0.5 1

数组名称和指针变量的唯一区别是,不能改变数组名称指向的地址。例如,假定存在以下定义:

double readings[20], totals[20];
double *dptr;

那么以下语句是合法的:

dptr = readings; // 使 dptr 指向 readings
dptr = totals; // 使 dptr 指向 totals

但是以下语句则是非法的:

readings = totals; // 非法!不能改变 readings
totals = dptr; // 非法!不能改变 totals

数组名称是指针常量。不能让它们指向除了它们所代表的数组之外的任何东西

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

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

相关文章

安装php独立环境,0507-php独立环境的安装与配置 Web程序 - 贪吃蛇学院-专业IT技术平台...

1.在一个纯英文目录下新建三个文件夹2.安装apache(选择好版本)过程中该填的按格式填好&#xff0c;其余的只更改安装目录即可如果报错1901是安装版本的问题。检查&#xff1a;安装完成后localhost打开为It works!添加到电脑属性环境变量&#xff1a;3.将php文件解压文档放到AMP…

linux中PATH变量-详细介绍

转自&#xff1a;https://blog.csdn.net/haozhepeng/article/details/100584451 转载者勘误 原文最后提到的 echo 命令对于环境变量的修改无影响。这是肯定的&#xff0c;echo 命令相当于只是一个打印的函数&#xff08;比如 Python 中的 print&#xff09;。这里要修改环境变…

php assert eval,代码执行函数之一句话木马

前言大家好&#xff0c;我是阿里斯&#xff0c;一名IT行业小白。非常抱歉&#xff0c;昨天的内容出现瑕疵比较多&#xff0c;今天重新整理后再次发出&#xff0c;修改并添加了细节&#xff0c;另增加了常见的命令执行函数如果哪里不足&#xff0c;还请各位表哥指出。eval和asse…

显卡、显卡驱动、CUDA、CUDA Toolkit、cuDNN 梳理

显卡、显卡驱动、CUDA、CUDA Toolkit、cuDNN 梳理 转自&#xff1a;https://www.cnblogs.com/marsggbo/p/11838823.html#nvccnvidia-smi GPU型号含义 显卡&#xff1a; 简单理解这个就是我们前面说的GPU&#xff0c;尤其指NVIDIA公司生产的GPU系列&#xff0c;因为后面介绍的…

VS Code的Error: Running the contributed command: ‘_workbench.downloadResource‘ failed解决

VS Code的Error: Running the contributed command: _workbench.downloadResource failed解决 转自&#xff1a;https://blog.csdn.net/ibless/article/details/118610776 1 问题描述 此前&#xff0c;本人参考网上教程在VS Code中配置了“Remote SSH”插件&#xff08;比如这…

Oracle闪回报错,oracle 闪回区满了,ORA-19815

oracle 闪回区满了&#xff0c;查看日志报错&#xff1a;ORA-19815&#xff0c;命令行输入&#xff1a;sqlplus / as sysdbastartup mount //如果你的数据库出现了无法连接的情况时&#xff0c;可以加上这句select file_type, percent_space_used as used,percent_space_rec…

[2021-ICCV] MUSIQ Multi-scale Image Quality Transformer 论文简析

[2021-ICCV] MUSIQ: Multi-scale Image Quality Transformer 论文简析 论文&#xff1a;https://arxiv.org/abs/2108.05997 代码&#xff1a;https://github.com/google-research/google-research/tree/master/musiq 概述 当前SOTA的IQA&#xff08;图像质量评估&#xff0…

安装oracle不动了,windows2008安装ORACLE到2%不动的问题 | 信春哥,系统稳,闭眼上线不回滚!...

最近又有网友遇到在windows2008服务器上安装ORACLE软件时到2%就卡住不动的问题&#xff0c;下面是该网友的描述&#xff1a;oralce 11g r2 windows server 2008 R2安装到最后一步复制数据文件时卡到2% 不走了内存一直飙升求解决这个问题前段时间也有人遇到过&#xff0c;但是他…

手把手教你入门Git --- Git使用指南(Linux)

手把手教你入门Git — Git使用指南&#xff08;Linux&#xff09; 系统&#xff1a;ubuntu 18.04 LTS 本文所有git命令操作实验具有连续性&#xff0c;git小白完全可以从头到尾跟着本文所有给出的命令走一遍&#xff0c;就会对git有一个初步的了解&#xff0c;应当能做到会用并…

php数据关系图,如何利用navicat查看数据表的ER关系图

文章背景&#xff1a;(相关推荐&#xff1a;navicat)由于工作需要&#xff0c;现在要分析一个数据库&#xff0c;然后查看各个表之间的关系&#xff0c;所以需要查看表与表之间的关系图&#xff0c;专业术语叫做ER关系图。默认情况下&#xff0c;Navicat显示的界面是这样的&…

Linux中g++与gcc的区别

转自&#xff1a;https://blog.csdn.net/bit_clearoff/article/details/53965514 Windows中我们常用vs来编译编写好的C和C代码&#xff1b;vs把编辑器&#xff0c;编译器和调试器等工具都集成在这一款工具中&#xff0c;在Linux下我们能用什么工具来编译所编写好的代码呢&#…

从C源代码到可执行文件的四个过程:预处理、编译、汇编、链接

从C源代码到可执行文件的四个过程&#xff1a;预处理、编译、汇编、链接 总览 我们将在Linux操作系统中&#xff0c;以C语言的Hello World程序为例&#xff0c;用gcc编译器分步执行这四个步骤。 我们有再熟悉不过的HelloWorld程序&#xff0c;hello.c&#xff1a; #include …

linux内核中cent文件夹,Centos 中如何快速定制二进制的内核 RPM 包

1、rpm 制作前的环境准备&#xff1a;yum install -y ncurses-devel qt-devel rpm-build redhat-rpm-config asciidoc hmaccalc perl-ExtUtils-Embed xmlto audit-libs-devel binutils-devel elfutils-devel elfutils-libelf-devel newt-devel python-devel zlib-devel bc2、准…

TabError- inconsistent use of tabs and spaces in indentation 查验及解决方法

TabError: inconsistent use of tabs and spaces in indentation 查验及解决方法 报错代码 def eccv16(pretrainedTrue):model ECCVGenerator()if(pretrained):import torch.utils.model_zoo as model_zoomodel.load_state_dict(torch.load(/home/ps/.cache/torch/hub/check…

linux用xshell编辑文件,Linux远程管理器xshell和xftp使用教程

Xshell 是一个强大的安全终端模拟软件&#xff0c;它支持SSH1, SSH2, 以及Microsoft Windows 平台的TELNET 协议。Xftp 是一个基于 MS windows 平台的功能强大的SFTP、FTP 文件传输软件。安装完毕后打开xshell设置网站帐号信息设置主机信息设置服务器帐号设置字符集编码设置好了…

FLOPs、FLOPS、Params的含义及PyTorch中的计算方法

FLOPs、FLOPS、Params的含义及PyTorch中的计算方法 含义解释 FLOPS&#xff1a;注意全大写&#xff0c;是floating point operations per second的缩写&#xff08;这里的大S表示second秒&#xff09;&#xff0c;表示每秒浮点运算次数&#xff0c;理解为计算速度。是一个衡量…

科普 | 单精度、双精度、多精度和混合精度计算的区别是什么?

科普 | 单精度、双精度、多精度和混合精度计算的区别是什么? 转自&#xff1a;https://zhuanlan.zhihu.com/p/93812784 我们提到圆周率 π 的时候&#xff0c;它有很多种表达方式&#xff0c;既可以用数学常数3.14159表示&#xff0c;也可以用一长串1和0的二进制长串表示。 …

linux设备驱动之串口移植,Linux设备驱动之UART驱动结构

一、对于串口驱动Linux系统中UART驱动属于终端设备驱动&#xff0c;应该说是实现串口驱动和终端驱动来实现串口终端设备的驱动。要了解串口终端的驱动在Linux系统的结构就先要了解终端设备驱动在Linux系统中的结构体系&#xff0c;一方面自己了解的不够&#xff0c;另一发面关于…

NVIDIA英伟达的Multi-GPU多卡通信框架NCCL

NVIDIA英伟达的Multi-GPU多卡通信框架NCCL 笔者注&#xff1a;NCCL 开源项目地址&#xff1a;https://github.com/NVIDIA/nccl 转自&#xff1a;https://www.zhihu.com/question/63219175/answer/206697974 NCCL是Nvidia Collective multi-GPU Communication Library的简称&…

C语言n个坐标点间的最大距离,c语言已知两点坐标,求另一点到穿过这两点的直线最短距离。...

c语言已知两点坐标&#xff0c;求另一点到穿过这两点的直线最短距离。以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;c语言已知两点坐标&#xff0c;求另一点到穿过这两点的直线最短距离。#…