动态数组中的数组循环终止

Posted

技术标签:

【中文标题】动态数组中的数组循环终止【英文标题】:Array loop termination in dynamic array 【发布时间】:2020-05-21 18:03:32 【问题描述】:

我正在练习数组中的循环,动态数组的循环不能用空字符终止吗?

for (int i=0; arr[i]!='\0'; i++)

以及如何在不使用这种格式的情况下终止这些循环:

for (const auto& value : arr)

【问题讨论】:

你必须以某种方式知道数组的大小。没有什么神奇的方法可以做到。 Plus for(const auto& value : arr) 不适用于动态数组,原因很简单,无法从数组本身知道动态数组的大小。 【参考方案1】:

对于分配在空闲存储区的数组

int* arr = new int[size];

有两种方法可以知道终点在哪里。最直接的就是记住它有多大:

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

另一种方法是将数组的最后一个元素设置为 sentinel 值——该值不会显示在您正在使用的数据中,因此当您看到你知道你在数组的末尾:

for (int i = 0; i < size; ++i)
    arr[i] = i;
arr[size - 1] = -1;

现在您可以遍历数组查看值:

for (int i = 0; arr[i] != -1; ++i)
    // do something with arr[i]

这就是文字字符串的工作原理(尽管它们不是在免费存储中分配的):

const char *str = "Hello, world!";
for (int i = 0; str[i] != '\0'; ++i)
    std::cout << str[i];
std::cout << '\n';

这里的权衡是,第一种方法你必须传递一个额外的参数来告诉其他代码数组有多大:

void do_something(int* arr, int size) 
    for (int i = 0; i < size; ++i)
        // whatever

另一方面,有一个哨兵意味着你浪费了最后一个元素:

void do_something(int* arr) 
    for (int i = 0; arr[i] != -1; ++i)
        // whatever

最后一个元素没有您正在使用的任何数据;它只是为了标记结束。

当然,对于哨兵,存在您没有选择好的哨兵值的风险。如果您在数据中间的某处发现该值,则代码将停止循环,并且不会处理其余数据。

【讨论】:

谢谢,这不仅帮助我纠正了我的错误,还帮助我清楚地理解了这个概念。【参考方案2】:

你可以这样做:

int* arr = new int[size];
for(int i=0; i< size; ++i)

    //do somtiong;

但不要忘记删除最后的数组:

delete[] arr;

也正如@john 在评论范围中所写,基本循环仅适用于 STL 容器并静态创建了一个这样的容器: int arr[size]; 不支持动态分配数组。

【讨论】:

我认为它们也适用于静态数组,但绝对不适用于动态数组。 你是对的我现在检查它对我来说是新的:) onlinegdb.com/BJSZ8S4i8【参考方案3】:

空字符将根据您的应用程序目的起作用。例如,如果给您一个数组,并且您事先知道数组中的最后一个元素是空字符,那么您可以使用空字符来终止循环。

请注意,如果使用空字符终止,则数组不能保存值 0,因为空字符的 ASCII 值为 0,并且只要数组包含 0,循环就会结束。在标准 C/C++ 中,空终止用于字符串。字符串是字符数组,以空字符标记数组的结尾。

一般情况下,使用数组时,您需要知道数组的大小。如果给你一个像vector 这样的STL 容器,那么你可以使用size() 操作符来访问它的大小。但是对于好的旧数组,您需要以某种方式知道大小。

【讨论】:

【参考方案4】:

如果你有一个动态字符数组:

char* str = new char[size];

除非你把它放在那里,否则没有空终止符。

如果你知道有一个空终止符,你只能依赖它:

char[] str1 = "Hello world"; // null terminated by default
char* str2 = new char[16]; // enough space for copy
strcpy(str2, str1); // strcpy also copies '\0'

// now you can iterate
for(int i = 0; str2[i] != '\0'; i++)

    std::cout << str2[i];

但以上所有内容仅适用于char数组,不能适用于其他数据类型。因此,要遍历数组的所有元素,您需要事先知道它们的计数:

int* arr = new int[size];
for(int i = 0; i < size; i++)

    // do something

【讨论】:

以上是关于动态数组中的数组循环终止的主要内容,如果未能解决你的问题,请参考以下文章

使用VBA根据逻辑动态循环数组元素

利用c++中的vector创建动态二维数组

动态数组分配仅返回所有索引中的最后一个元素 C

C语言实现使用动态数组实现循环队列

循环遍历数组并一次显示单个项目,动态持续时间,如 react js 中的 setTimeout 或 SetInterval

循环遍历Vue.js中的动态数组,然后根据对应的值将每个对象组件添加到单独组件中的div中?