You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++静态数组与指针:为何这段代码能获取长度?另一段却失效?

关于数组长度计算的两个问题解答

一、为什么*(&A+1)-A能得到数组长度5?

咱们把这段代码的每个操作拆解开,就能明白背后的逻辑:

  • 首先,A是固定大小的数组,实际类型是double[5](因为初始化了5个double元素)。
  • &A取的是整个数组的地址,它的类型是double(*)[5]——简单说就是“指向包含5个double的数组的指针”。
  • 执行&A + 1时,C++的指针算术会根据指针类型计算偏移量:这里指针指向的是5元素的double数组,所以加1会直接跳过整个数组的大小(比如5*8=40字节,假设double占8字节),最终指向数组A末尾之后的第一个内存位置。
  • *(&A+1)对这个指针解引用,得到的是double[5]类型的数组,但在表达式中数组会自动转换成指向其第一个元素的指针(double*类型),这个指针正好指向A最后一个元素的下一个位置(可以理解为A[5]的位置,C++允许指针指向这里,即使该位置不属于数组)。
  • 而A本身在表达式里也会转换成指向A[0]的double*指针。
  • 最后,两个同类型指针相减,结果是它们之间相差的元素个数(不是字节数)。*(&A+1)指向数组末尾后,A指向起始位置,相减自然得到5,也就是数组的元素个数。

至于&A和&A[0]输出结果一致,是因为它们指向的是同一个内存地址(数组的起始位置),但类型完全不同:&A是double(*)[5],&A[0]是double*,只是打印地址值时显示的是同一个数值而已。

二、为什么void test(double B[])里的*(&B+1)...无法运行?

这里的核心坑点是:函数参数中的数组类型会被自动转换成指针类型。你写的void test(double B[])其实和void test(double* B)完全等价——B根本不是数组,而是一个普通的指针变量。

拆解问题原因:

  • B的类型是double*,不是数组类型。
  • &B取的是这个指针变量本身的地址,类型是double**(指向double指针的指针)。
  • &B + 1会偏移一个double*的大小(比如64位系统是8字节),指向的是B这个变量在栈上后面的内存位置,和传入的原数组没有任何关系。
  • *(&B+1)是一个double*,但它指向的是无效内存区域,用它和B相减得到的结果完全没有意义,甚至会触发未定义行为(程序崩溃、输出垃圾值都有可能)。

修复方法

要在函数里正确获取数组长度,有几种常用方案:

方案1:手动传递长度参数

这是最直接的方式,调用函数时把数组长度一起传进去:

#include <iostream>
using namespace std;

void test(double B[], int len) {
    cout << "The array has " << len << " elements." << endl;
}

int main() {
    double A[] = {2.4, 1.2, 4.6, 3.04, 5.7};
    int len = sizeof(A)/sizeof(A[0]); // 先计算长度
    test(A, len);
    return 0;
}

方案2:用模板推导数组大小

利用C++模板自动推导固定大小数组的类型,直接获取长度:

#include <iostream>
using namespace std;

template <size_t N>
void test(double (&B)[N]) {
    // N就是数组的元素个数
    cout << "The array has " << N << " elements." << endl;
}

int main() {
    double A[] = {2.4, 1.2, 4.6, 3.04, 5.7};
    test(A); // 模板会自动推导N=5
    return 0;
}

方案3:改用标准库容器

如果可以的话,直接用std::vector代替原生数组,它自带size()方法获取元素个数,更安全方便:

#include <iostream>
#include <vector>
using namespace std;

void test(const vector<double>& B) {
    cout << "The vector has " << B.size() << " elements." << endl;
}

int main() {
    vector<double> A = {2.4, 1.2, 4.6, 3.04, 5.7};
    test(A);
    return 0;
}

内容的提问来源于stack exchange,提问作者user3112666

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:29:58