代码之家  ›  专栏  ›  技术社区  ›  Andrew-Dufresne

为什么printf(“%s”,ptr)能够取消对void*的引用?

  •  7
  • Andrew-Dufresne  · 技术社区  · 16 年前

    * 应该用在里面吗?如果我们以其他方式访问指针的referent,是否可以将其视为取消对指针的引用,如:

    char *ptr = "abc" ;
    printf( "%c" , *ptr ); // Here pointer is dereferenced.
    printf( "%s" , ptr );  // What about this one?
    

    这是我问题的第一部分。

    现在如果 printf( "%s" , ptr ) 是一个取消引用的例子,那么请回答我的问题的以下部分也。

    “指向void的指针”用于保持 任何类型的指针,但不能是 取消引用自身

    因此,

    char a = 'c' ;
    char *p = &a ;
    void *k = &a;
    printf( "\n%c\n" , *p );
    printf( "\n%c\n" , *k );
    

    取消引用void*指针错误: void表达式的使用无效

    char *a = "c" ;
    char *p = a ;
    void *k = a;
    printf( "\n%c\n" , *p );
    printf( "\n%s\n" , k );
    

    它编译并运行。这意味着可以取消对void指针的引用-我们得到了对象指针所引用的。

    2 回复  |  直到 16 年前
        1
  •  9
  •   anon anon    16 年前

    不,您所拥有的是“未定义的行为”——C语言标准没有说明应该发生什么。在您的情况下,它“工作”,但对于另一个用户/编译器/平台,它可能不工作。您的声明:

    printf( "\n%s\n" , k );
    

    int k = 42;
    printf( "\n%s\n" , k );
    

    同样没有定义。

        2
  •  0
  •   mukunda    11 年前

    在给出的示例中:

    char *a = "c";
    char *p = a;
    void *k = a;
    printf( "\n%c\n" , *p );
    printf( "\n%s\n" , k );
    

    char 指针, printf 只知道你给了它一个 烧焦 因为 %c 设置标签格式。

    现在,一个 void* 只是一个具有未知类型的原始指针,您不能取消对它的引用,因为编译器不知道要从中读取什么类型,除非您将它转换为其他类型。

    无效* 指针已传入。 打印F 只是把它看作一个普通的数字,直到它读取了给定的格式化标记,才知道它是什么。通过使用 %s char* ,因此它相应地对其进行强制转换,并将其正确地作为字符串读取,即取消对 字符* 指针。

    它是有效的代码,只要 无效* 烧焦 数组。如果 无效* 指针指向不同的东西 打印F 函数仍然会高兴地尝试将其作为 指针(如果指定

    另一个坏例子:

    char *a = "ce";
    int b = (int)a;
    printf( "\n%s\n" , b );
    

    你也不能取消对整数的引用,但我告诉你了 它是一个 字符*