【问题标题】:Should this pointer be acting this way? Basic C这个指针应该以这种方式运行吗?基础 C
【发布时间】:2020-05-09 08:57:51
【问题描述】:

据我了解,pName 应该是一个指针,其值是 char name 的内存位置的值。
这意味着,当我在第二个printf 语句中取消引用指针变量pName 时,它应该只打印字符串“Cameron”。但它没有!有人可以帮助这个菜鸟吗:)?

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

int main()
{
    char name[] = "Cameron";
    char * pName = &name;

    printf("Printing string of characters: %s\n", name);
    printf("Dereferencing pointer and printing string: %s\n", *pName);
    printf("Printing pointer: %p\n", &name);
    printf("Printing pointer another way %p\n", pName);

    return 0;
}

【问题讨论】:

  • "%s" 需要一个指向字符串的指针。不是char。您的编译器可能已经告诉您“参数与格式说明符不匹配...”
  • @Gerhardh 在此之前,编译器应该在char * pName = &amp;name;处给出转换指针类型的警告
  • @DavidRanieri 为什么你删除了&amp;并写了printf("Printing pointer: %p\n", (void *)name);
  • @MikeCAT 因为%p 说明符必须与void * 的强制转换一起使用
  • @DavidRanieri printf("Printing pointer: %p\n", (void*)&amp;name); 也是有效的,所以我认为这不是&amp; 被丢弃的原因。

标签: c arrays pointers implicit-conversion c-strings


【解决方案1】:

pName 是一个 char*,一个指向 char 的指针。因此,当您执行*pName 时,您会得到一个char,它不是您可以使用%s 打印的字符串。

代替

char *pName = &name;

你需要:

char (*pName)[] = &name; // a pointer to an array of chars.

现在您的取消引用/printf 将按预期工作。

%p 格式也要求它的参数是void* 类型。因此,您需要在 printf 调用中将参数转换为 void*

7.21.6.1 The fprintf function:

p 参数应该是一个指向 void 的指针。指针的值 转换为打印字符序列,在 实现定义的方式。

【讨论】:

  • 谢谢!这正是我一直在寻找的。我没有使用 void* 并且它似乎按预期工作,但是我将从现在开始使用它,因为我确信这是标准做法。
【解决方案2】:

这个字符数组的声明

char name[] = "Cameron";

等价于下面的声明

char name[8] = { 'C', 'a', 'm', 'e', 'r', 'o', 'n', '\0' };

也就是说name的对象类型是char[8]

例如,您可以使用 typedef 进行编写

typedef char T[8];

然后像这样声明数组

T name = { 'C', 'a', 'm', 'e', 'r', 'o', 'n', '\0' };

所以一个指向数组的指针的声明看起来像

T *pName = &name;

上面显示的 T 是char[8]。所以用别名代替它表示你将拥有的类型

char ( *pName )[8] = name;

输出你现在可以写的指针指向的字符串

printf("Dereferencing pointer and printing string: %s\n", *pName);

取消引用指针*pName 给出了数组的左值,该数组又隐式转换为指向其第一个元素的指针,并具有char * 类型。所以要使用转换说明符%s yo 应该提供char * 类型的表达式。

至于这份声明

char * pName = &name;

当它不正确时,因为在左侧有一个 char * 类型的对象,而在右侧有一个 char ( * )[8] 类型的表达式,并且没有从一种类型到另一种类型的隐式转换.

你可以写

char * pName = name;

正如上面所说,数组的左值被隐式转换为指向其第一个元素的指针,并且类型为char *。你可以用这个指针写

printf("Dereferencing pointer and printing string: %s\n", pName);

【讨论】:

    【解决方案3】:

    1.

    char name[] = "Cameron";
    
    char * pName = &name;
    

    通过pName的初始化,name已经衰减为指向数组name的第一个元素的指针,实际上是name[0]

    因此,&amp;name 是指向 8 个字符数组的指针,键入 char (*)[8],而不是 char*。通过char (*)[] 分配char* 是无效的。

    这应该会给你一个诊断。永远不要忽略编译器警告。

    用途:

    char * pName = name;
    

    改为。


    2.

    printf("Dereferencing pointer and printing string: %s\n", *pName);
    

    %s 转换说明符需要 char * 类型的参数,pName 已经是。取消引用pName 得到一个无效的char

    用途:

    printf("Dereferencing pointer and printing string: %s\n", pName);
    

    改为。


    旁注:

    要符合标准,%p 应具有void* 类型的参数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-07-19
      • 2017-12-19
      • 1970-01-01
      • 2014-08-02
      • 2014-01-04
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多