什么是半开范围和结束值

Posted

技术标签:

【中文标题】什么是半开范围和结束值【英文标题】:What is half open range and off the end value 【发布时间】:2012-10-15 12:51:56 【问题描述】:

这些术语在 C++ 中的含义是什么?

1.end 值不同

2. 半开范围 - [begin, off_the_end)

我在阅读 for 循环时遇到了它们。

【问题讨论】:

排除边缘值。它主要用于处理实数/有理数 - 但也可以应用于整数。 感谢大家的回答。得到这个概念。 【参考方案1】:

半开范围是包含第一个元素但不包括最后一个元素的范围。

范围 [1,5) 是半开的,由值 1、2、3 和 4 组成。

"off the end" 或 "past the end" 指的是刚好在序列结尾之后 的元素,并且它的特殊之处在于允许迭代器指向它(但你可能不看实际值,因为不存在)

例如在下面的代码中:

char arr[] = 'a', 'b', 'c', 'd';

char* first = arr
char* last = arr + 4;

first 现在指向数组的第一个元素,而last 指向数组末尾的一个。我们可以 point 指向数组末尾之后的一个位置(但不是 两个 过去的位置),但我们不能尝试访问该位置的元素:

// legal, because first points to a member of the array
char firstChar = *first;
// illegal because last points *past* the end of the array
char lastChar = *last;

我们的两个指针firstlast 共同定义了它们之间所有元素的范围。

如果是半开范围,那么它包含first指向的元素,以及介于两者之间的所有元素,但不包含last指向的元素(这很好,因为它没有实际上指向一个有效的元素)

在 C++ 中,所有标准库算法都在这样的半开范围上运行。例如,如果我想将整个数组复制到其他位置dest,我这样做:

std::copy(first, last, dest)

简单的 for 循环通常遵循类似的模式:

for (int i = 0; i < 4; ++i) 
    // do something with arr[i]

这个循环从 0 到 4,但它不包括结束值,所以覆盖的索引范围是 半开,具体来说是[0, 4)

【讨论】:

【参考方案2】:

这些不是 C++ 特定术语,它们是通用数学术语。

[] 和 () 表示范围是否包含/不包含端点:

[包括端点 (不包括端点 [] = '已关闭',包括两个端点 () = 'Open',不包括两个端点 [) 和 (] 都是“半开”,并且只包含一个端点

大多数 C++ for 循环覆盖半开范围(包括第一个元素:例如 for int i=0;,但不包括最后一个元素:i &lt; foo,而不是 i ≤ foo

【讨论】:

【参考方案3】:

正如其他答案所解释的,半开范围也是一个数学术语,该术语在编程上下文中的用法,暗示起点是包含,终点是排除

在 C/C++ 编程的上下文中它实际上意味着什么?假设您要打印一个整数数组的元素。说到 C 语言,因为您对数组的大小没有任何运行时知识,所以您有两个选择。要么您必须提供数组的大小,因此函数签名将如下所示;

void printArray(int * array, int size);

或者您必须使用半开范围,这意味着您必须同时提供开始和结束指针(并且函数将处理包括开始,不包括结束)附加到数组本身。 函数签名如下:

void printArray(int * array, int * begin, int * end);

为了说明,这里是一个提供数组大小的例子;

#include <stdio.h>

void printArray(int * array, int size)

    printf("Array: ");

    for(int i = 0; i < size; i++)
        printf("%2d ", array[i]);

    printf("\n");


int main()

    int array[5] =  1, 2, 3, 4, 5 ;

    printArray(array, 5);

    return 0;

在上面的示例中,我们向printArray 函数传递了两个参数,因为函数签名、指向数组第一个元素(或数组本身)的指针以及数组的大小很明显.

但是,正如我上面写的,我们也可以在函数签名中使用半开范围,如下所示;

#include <stdio.h>

void printArray(int * array, int * begin, int * end)

    printf("Array: ");

    for(int * index = begin; index != end; index++)
        printf("%2d ", *index);

    printf("\n");


int main()

    int array[5] =  1, 2, 3, 4, 5 ;

    printArray(array, array, array+5);

    return 0;

两个代码将产生相同的输出,如下所示;

Array:  1  2  3  4  5

如您所见,printArray 函数打印范围 [begin, end) 的函数。 index实际上是一个指向整数数组元素的指针,从begin开始,它包括begin,当index等于end指针时,for循环结束,不包括处理end。我称之为半开范围

半开范围C++约定

【讨论】:

以上是关于什么是半开范围和结束值的主要内容,如果未能解决你的问题,请参考以下文章

mysql 查询时间范围内的数据该怎么写select语句,如果结束时间为空则不判断结束时间

10.3 定位连续值范围的开始点和结束点

10.3 定位连续值范围的开始点和结束点

为啥范围(开始,结束)不包括结束?

pandas读取csv数据index_col参数指定作为行索引的数据列索引列表形成复合(多层)行索引loc基于行层索引元组范围筛选数据(指定起始元组和结束元组其中结束元组只包含最外侧索引值)

pandas读取csv数据index_col参数指定作为行索引的数据列索引列表形成复合(多层)行索引loc基于行层索引元组范围筛选数据(指定起始元组和结束元组其中结束元组只包含最外侧索引值)