C++中使用accumulate处理原生数组时,程序如何识别尾后指针?
其实程序不会主动校验a+3是不是某个数组的尾后指针,这里的合法性需要你作为开发者来保证,背后的逻辑可以拆解成这几点:
数组名的退化与编译期类型信息
当你在数组int a[3]的定义作用域中写a+3时,编译器知道a的类型是int[3](而非单纯的int*)。根据C的指针运算规则,对数组名做加法时,编译器会基于数组的元素类型和大小计算指针偏移:a+3等价于&a[3],也就是数组最后一个元素的下一个位置——这是C标准明确允许的合法尾后指针(注意:只能指向这个位置,不能解引用它)。accumulate的区间要求
accumulate只要求传入的两个指针构成一个左闭右开的有效区间[first, last),它不会验证这个区间是否属于某个数组,也不会检查指针的合法性。只要你保证last是first指向序列的尾后位置,它就会从first开始遍历,直到last停止完成累加计算。你的例子中[a, a+3)正好覆盖数组的3个元素,所以能得到正确结果。和vector::end()的区别
vector的end()成员函数靠自身维护的内部状态(比如存储的尾指针或元素个数)返回尾后位置;而原生数组没有这样的内置机制,必须由你手动计算尾后位置——要么像你那样直接写a+3,要么用std::end(a)(C++11及以后支持),后者会在编译期推导数组大小,返回正确的尾后指针,比手动写数字更安全。风险提示
如果你写错了偏移量(比如写成a+4),编译器可能会给出越界警告(取决于编译选项),但不会强制阻止。此时a+4是非法指针,用它作为accumulate的last参数会导致未定义行为(可能计算错误、程序崩溃等)。
内容的提问来源于stack exchange,提问作者lamc

