在C中的数组中迭代

时间:2013-08-28 10:23:25

标签: c arrays

嘿,我有这种类型的东西

eph_t *a;

您可以看到类型为eph_t。它是C中的数组,但我不知道数组的大小,也不知道数组的最终元素是什么。 有没有办法,我可以浏览整个数组,因为我想将数组中每个元素的值赋给某些东西。

我可以考虑哪些选择? 如果您无法理解问题中的某些内容,只需发表评论,以便我可以通知您。

4 个答案:

答案 0 :(得分:7)

如果您不知道数组的大小,则迭代它是不安全的。每当您尝试读取最后一个元素之外的元素时,您将获得未定义的行为。除非你知道数组的大小,否则你无法做任何安全

答案 1 :(得分:5)

正如其他人所说,当你不知道数组的结尾时,迭代数组是不安全的。这通常以下列方式解决。

  1. 例如,如果您有权访问数组声明(int a[10];)。您可以使用sizeof运算符来确定数组的大小。请注意,将指向数组的指针传递给函数时,这将无效。
  2. 使用数组的函数通常会采用直接大小或某种方式来推断大小作为函数的额外参数(memset是一个很好的例子)
  3. 数组可能有一个特殊的终结符元素(通常在结尾处为NULL或0元素),这意味着你可能不会迭代(C字符串是很好的例子)
  4. 因此,如果您正在设计一个以数组作为参数的函数,请使用上述模式。如果您使用的函数不使用上述模式之一,请将问题报告给库设计器作为错误。

答案 2 :(得分:1)

C 中的指针只是一个地址。当用作数组时,您必须(通过其他方式)计算出数组的长度。

许多处理数组的库都具有接受指向数组的指针及其大小的函数。例如qsort(3)想要第二个nmemb参数,给出要排序的数组base(第一个参数qsort)的元素数。

或者,您可以使用flexible array members(在C99中)并传递(并在相关时返回)指向

之类的结构的指针,而不是只传递指针。
  struct eph_tuple_st {
     unsigned len;
     eph_t* ptrtab[];
  };

使用灵活数组ptrtab字段具有len元素的约定。

最后,正如其他人所建议的那样,您可以使用标记值(即空字)来结束数组。通常我不建议(缓冲区溢出的风险,计算实际大小的时间复杂度)。

FWIW,最近的C ++有std::dynarray(C ++ 2014)和std::vector,Ocaml有Array模块。你可以切换到一些更友好的编程语言。

答案 3 :(得分:1)

您可以保留数组的第一个元素来存储大小

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct {
    int x, y;
    double z;
} eph_t;

static void temp(eph_t *a)
{
    size_t n;

    memcpy(&n, a - 1, sizeof(size_t)); /* get size (stored in a - 1) */
    printf("Count = %zu\n", n);
}

int main(void)
{
    const size_t n = 5;
    eph_t a[n + 1]; /* allocate space for 1 more element */

    memcpy(&a[0], &n, sizeof(size_t)); /* now the first element contains n */
    temp(a + 1); /* skip first element */
    return 0;
}