在C中迭代一个数组
嘿,我有这种类型的东西
eph_t *a;
你可以看到类型是eph_t。 它是C中的数组,但我不知道数组的大小,也不知道数组的结束元素是什么。 有没有办法,我可以浏览整个数组,因为我想将数组中每个元素的值赋给某些东西。
我可以选择考虑什么? 如果您无法理解问题中的某些内容,只需发表评论,以便我可以通知您。
如果您不知道数组的大小,则迭代它是不安全的。 每当您尝试读取最后一个元素之外的元素时,您将获得未定义的行为。 除非你知道arrays的大小,否则你无能为力。
正如其他人所说,当你不知道数组的结尾时,迭代数组是不安全的。 这通常以下列方式解决。
- 如果您有权访问数组声明(例如,
int a[10];
)。 您可以使用sizeof
运算符来确定数组的大小。 请注意,将指向数组的指针传递给函数时,这将无效。 - 使用数组的函数通常会采用直接大小或某种方式来推断大小作为函数的额外参数(
memset
是一个很好的例子) - 数组可能有一个特殊的终结符元素(通常在结尾处为NULL或0元素),这意味着您可能不会迭代超出(C字符串是很好的例子)
因此,如果您正在设计一个以数组作为参数的函数,请使用上述模式。 如果您使用的函数不使用上述模式之一,请将问题报告给库设计器作为错误。
C中的指针只是一个地址。 当用作数组时,您必须(通过其他方式)计算出数组的长度。
许多处理数组的库都具有接受指向数组的指针及其大小的函数。 例如, qsort(3)想要第二个nmemb
参数给出要排序的数组base
( qsort
第一个参数)的元素数。
或者,您可以使用灵活的数组成员 (在C99中)并传递(并在相关时返回)指向结构的指针,而不是只传递一个指针。
struct eph_tuple_st { unsigned len; eph_t* ptrtab[]; };
灵活数组ptrtab
字段具有len
元素的约定。
最后,正如其他人所建议的那样,您可以使用sentinel值(即空字)来结束数组。 通常我不建议(缓冲区溢出的风险,计算实际大小的时间复杂度)。
FWIW,最近的C ++有std :: dynarray (C ++ 2014)和std :: vector ,而Ocaml有Array模块。 你可以切换到一些更友好的编程语言。
您可以保留数组的第一个元素来存储大小
#include #include #include 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; }