【发布时间】:2021-01-07 12:10:05
【问题描述】:
我了解通常的while (*pointer) 用例是在使用字符串时。
char str[]= "string";
int i = 0;
while (*(str + i++));
当取消引用的字符为\0时,循环结束。
但是,我有这段代码可以递归地打印出字符串数组。
void print_array(char** arr, bool printComma) {
if (*arr) {
if (printComma) {
printf(", ");
}
printf("%s", *arr);
print_array(arr + 1, true);
}
}
int main(int argc, char **argv) {
print_array(argv, false);
}
它按预期工作并打印出char **arr 中的字符串。
但是,我不明白系统如何知道数组的结尾,因为取消引用指向指针的指针会给出一个指向内存的值,我也不确定该值是什么。
另外,如果我将此样式与任何指针变量一起使用,循环是否保证结束?
【问题讨论】:
-
没什么神奇的。如果将
*pointer设置为指向包含0的位置,则*pointer将是0。所以在print_array示例中,函数的调用者传入一个指针数组,其中每个指针要么为NULL,要么不为NULL。并且由于argv被传入,我们知道它是一系列指向字符串的指针,最后一个元素为 NULL 指针。 -
为什么我们应该使用显式编码风格的完美例子。
if (*arr)非常混乱,if (*arr != NULL)非常清楚。同样,**arr会同样令人困惑,**arr != '\0'将是可读的。特别是,NULL和\0具有非常不同的含义,即使它们最终都可能归结为 0。 -
@Lundin 我的口味不同。我不是唯一一个。引用 K&R:“
/* strcpy: copy t to s; pointer version 3 */ void strcpy(char *s, char *t) { while (*s++ = *t++) ; }虽然这乍一看可能有些神秘,但记法上的便利性相当可观,应该掌握成语” -
@Peter-ReinstateMonica 这是一个写得很糟糕的代码示例,每个人(每个老手)都知道它是如何工作的,只是凭经验。而不是通过看一眼代码并立即理解它。
strcpy可以以更易读的方式编写,但当然源代码会变长几行。在最终的机器代码中,这并不重要。 K&R 是在一个需要考虑硬盘驱动器上的源代码大小的时代编写的……这是 1970 年代的历史文本。 -
@Peter-ReinstateMonica(实际库质量 strcpy 无论如何都不会使用那个旧技巧,而是在对齐的基础上工作。)
标签: c pointers recursion command-line-arguments c-strings