【问题标题】:Is C while pointer going to work with any pointer variableC while 指针是否可以与任何指针变量一起使用
【发布时间】: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


【解决方案1】:

之所以有效,是因为传递给the main functionargv 数组被NULL 指针终止。

也就是说,argv[argc] 保证为NULL

NULL 指针在用作条件时被视为false。比如if (*arr)

【讨论】:

    【解决方案2】:

    根据C标准*5.1.2.2.1程序启动)

    2 如果它们被声明,主函数的参数应该服从 以下约束:

    — argc 的值应为非负数。

    argv[argc] 应为空指针

    所以在这个 if 语句中

    if (*arr) {
    

    检查下一个指针*arr(类型为char *)是否等于NULL

    为了更清楚,请考虑以下演示程序,其中使用类似定义的数组代替命令行参数。

    #include <stdio.h>
    
    void print_array( char **arr ) 
    {
        *arr == NULL ? ( void )putchar( '\n' )  : ( printf( "%s", *arr ), print_array( arr + 1 ) );
    }
    
    int main(void) 
    {
        char *s[] =
        {
            "Hello", " ", "World!", NULL 
        };
        
        print_array( s );
        
        return 0;
    }
    

    程序输出是

    Hello World!
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-03-29
      • 1970-01-01
      • 2022-11-11
      • 2018-07-18
      • 2021-10-02
      • 1970-01-01
      • 1970-01-01
      • 2014-06-26
      相关资源
      最近更新 更多