首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >数组中的指针。它是如何在记忆中“物理”工作的?

数组中的指针。它是如何在记忆中“物理”工作的?
EN

Stack Overflow用户
提问于 2018-04-10 21:01:09
回答 1查看 56关注 0票数 0

我一直在想关于指针的问题,却找不到一个来源来解释它们的细节。

例如。给定数组int a3,是否有指向4个位置的指针?它以*a+0开头,并指向地址a?那么接下来它会做什么呢?Int至少有16位,所以它需要读取2个字节,但是每个字节都有一个地址。

这是否意味着对于起始地址的指针点,程序读取从给定地址开始的相当大的(Int)字节?

接下来它会做什么?如果它停止阅读,给出结果,对于a1,它会指向&a+1*sizeof(int)的地址吗?它将从地址开始读取(&a+2(作为2表示已经读取的地址为2字节),开始读取,所以它将读取另外的2字节和开始?

我不太明白这些概念。

字符串由无符号字符组成,这是一个字节元素。您提到的post没有解释大于1字节的元素会发生什么。它也没有确切地解释程序在“这是程序从内存中读取的字符串”旁边做了什么。我想我是对的,但你提到的标题与我所问的相去甚远。(既然有人已经写了这个,一个地址就代表一个字节)

代码语言:javascript
代码运行次数:0
运行
复制
  54   55   56   57   58   59   60   61   62   63   64   65   66   67   68   69
+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+----+
|----|----|----|----|----|----|    |    |    |    |    |    |    |    |    |    |
0----+----01---+----12---+----2----+----+----+----+----+----+----+----+----+----+

我特别询问int a2是否意味着指针首先是:在内存地址( 54 )上点,程序从以下两个地址读取数据(54到54作为int取2个字节),然后指针点在地址54+2,程序开始从地址范围<56,57>读取数据。再一次,指针指向58的起始范围,程序读取<58,59>的地址。

这个逻辑正确吗?它不是以NULL结尾的字符串。我对字符串的猜测是,程序将按字节地址访问内存字节的地址,并读取这些值直到找到NULL为止。

数组不是字符串。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-04-10 21:52:09

考虑一下

代码语言:javascript
代码运行次数:0
运行
复制
int a[3] = {};
int b[300] = {};

这两个数组“相似”,因为它们包含int的值,并且在这两个主要方面不同:

  1. 它们具有不同的“大小”--即它们指向的内存为每个内存都保留了不同的数量。第一个数组指向保留用于保存至少3 int值的内存。然而,这是最小分配的内存(在本例中-在堆栈上,因此很可能也是为其分配的精确内存量)。
  2. 它们指向内存中的不同的地址(同样--在本例中,它们都是在堆栈上分配的,但仍然是内存)

您也可以轻松地获取任意一个数组的第一个元素的地址:

代码语言:javascript
代码运行次数:0
运行
复制
int * p = a;
p = &a[0]; // same as above
p = b; // now p points to the first element of the second array

当您执行索引操作时,编译器所做的是:它获取第一个元素的地址,并将其增量为等于索引的值乘以每个元素的大小(当然,如果由于对齐而没有填充)。本质上,编译器就是这样做的:

代码语言:javascript
代码运行次数:0
运行
复制
b[1] = 1;
*(p+1) = 1; // same as above
uint8_t * c = reinterpret_cast<uint8_t*>(p); // WARNING! Explanation follows

最后一行将导致编译器以不同的方式重新解释指针,而“相同的”地址算法“突然”的工作方式不同:

代码语言:javascript
代码运行次数:0
运行
复制
c[1] = 1; // this is NOT the same as b[1] = 1

在这种情况下,编译器只会“移动”指针8位(而不是16位或32位,取决于平台的sizeof(int)),并最终位于数组b的第一个int元素的中间。当然,这可能是有用的(特别是当直接处理硬件),但是超级杜帕普不可移植,你应该避免在任何时候这样做!

诚然,这不是一个全面的答案,但我并不打算提供一个答案,因为这个主题非常广泛,而且网上有大量的资源可以为您提供关于这个主题的更多细节。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49762790

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档