通过指针算法计算数组长度
Calculate array length via pointer arithmetic
我想知道*(&array + 1)
实际上是如何工作的。我认为这是一种计算数组长度的简单方法,并希望在使用之前正确理解它。我对指针算术不是很有经验,但根据我的理解&array
给出了数组第一个元素的地址。(&array + 1)
将在地址方面转到数组的末尾。但是*(&array + 1)
不应该给出这个地址的值。相反,它会打印出地址。我非常感谢您的帮助,以使指针内容在我脑海中清晰。
这是我正在处理的简单示例:
int numbers[] = {5,8,9,3,4,6,1};
int length = *(&numbers + 1) - numbers;
(这个答案是针对C++的。
&numbers
是指向数组本身的指针。它具有类型int (*)[7]
.&numbers + 1
是指向数组后面的字节的指针,其中将位于另一个 7int
s 的数组。它仍然有类型int (*)[7]
.*(&numbers + 1)
取消引用此指针,生成一个类型为int[7]
的左值,引用数组后面的字节。*(&numbers + 1) - numbers
:使用-
运算符强制两个操作数进行数组到指针的转换,因此可以减去指针。*(&numbers + 1)
将转换为指向数组后面的字节的int*
。numbers
将转换为指向数组第一个字节的int*
。它们的区别在于两个指针之间的int
s 数---即数组中的int
s 数。
编辑:虽然没有&numbers + 1
指向的有效对象,但这就是所谓的"过去结束"指针。如果p
是指向T
的指针,指向类型为T
的有效对象,那么计算p + 1
总是有效的,即使*p
可能是单个对象,或者是数组末尾的对象。在这种情况下,你会得到一个"超过终点"指针,它不指向有效对象,但仍然是一个有效的指针。您可以使用此指针进行指针算术,甚至可以取消引用它以生成左值,只要您不尝试读取或写入该左值。请注意,您只能经过对象的末尾一个字节;试图走得更远会导致未定义的行为。
表达式&numbers
给你数组的地址,而不是第一个成员(尽管它们在数字上是相同的(。 这个表达式的类型是int (*)[7]
,即指向大小为 7 的数组的指针。
表达式&numbers + 1
将sizeof(int[7])
个字节添加到array
的地址。 生成的指针指向数组之后。
但是,问题是当您随后使用*(&numbers + 1)
取消引用此指针时。 取消引用指向一个元素经过数组末尾的指针将调用未定义的行为。
获取数组元素数的正确方法是sizeof(numbers)/sizeof(numbers[0])
。 这假定数组是在当前作用域中定义的,并且不是函数的参数。
但根据我的理解,数组给出了数组第一个元素的地址。
这种理解具有误导性。&array
给出数组的地址。当然,该地址的值与第一个元素相同,但表达式的类型不同。表达式&array
的类型是"指向 T 类型的 N 个元素数组的指针"(其中 N 是您要查找的长度,T 是int
(。
但是
*(&array + 1)
不应该给出值,它在这个地址。
是的。。。但正是在这里,表达式的类型变得很重要。将指针定向到数组(而不是指向数组元素的指针(将导致数组本身。
在减法表达式中,两个数组操作数都衰减为指向第一个元素的指针。由于减法使用衰减指针,因此指针算术的单位是元素大小。
我认为这是计算数组长度的简单方法
有更简单的方法:
std::size(numbers)
在 C 中:
sizeof(numbers)/sizeof(numbers[0])
- cpp二进制搜索问题,计算给定数组中输入元素的出现次数
- C++数据文件、数组和计算赋值
- 如何计算数组中元素的位数?(不是数组的长度),并计算其数字的总和
- 我的目标是编写一个程序来计算和存储字符串在字符数组中出现的位置
- 从另一个静态常量数组初始化静态常量数组(只需少量计算)
- 有效地计算多维数组的累积和?
- 通过指针算法计算数组长度
- 计算数组重复次数的组合的有效算法,加起来达到给定的总和
- 给定一个单词数组和一个字符串,如何计算给定字符串中的所有单词
- 使用结构数组计算文本文件中单词的出现次数C++
- 使用 2D 数组计算总计、最高价和最低价
- 二维数组:计算行的总和和列的乘积
- 从字符数组计算平均数
- 练习:使用数组计算方差
- 二维数组计算公式
- 从导入的二维数组计算平均值
- 从数组计算数据的c++问题
- 通过二维数组计算文件中的特定记录
- Python模拟显示慢性能,如何加快数组计算速度
- 通过数组计算文本文件数值数据