【问题标题】:How can I test the -> C operator using a struct that allows me to access a struct's field?如何使用允许我访问结构字段的结构来测试 -> C 运算符?
【发布时间】:2017-02-17 09:29:59
【问题描述】:

我正在尝试测试 -> 运算符,但我似乎无法做到这一点,因为当我执行以下程序并使用流提供输入时,程序停止工作。

注意1:我在编译之前收到警告,它说:

格式“%s”需要“char *”类型的参数,但参数 2 具有类型 'int' [-Wformat=]

注意 2:如果我省略了 printf("%s\n", *(&home1)->name ) 行,它可以正常工作,并且实际上会打印我写的任何内容。

#include <stdio.h>
#include <string.h>

typedef struct home_type {
    char name[30] ;
}home;

int main (void) {
    home home1 ;
    char name[30] ;
    scanf ("%[^\n]%*c", name);
    strcpy( home1.name, name) ;
    printf("%s\n", home1.name ) ;
    printf("%s\n", *(&home1)->name ) ;
    return 0 ;
}

【问题讨论】:

  • printf("%s\n", &amp;(&amp;home1)-&gt;name[0]);........ ;)
  • 注意:scanf ("%[^\n]%*c", name); 如果他们事先没有任何其他内容就按 Enter 键,则会失败,您将遇到 strcpy 未初始化的字符串
  • 请记住,-&gt; 已经内置了 *,因此您不需要另一个。

标签: c pointers dereference


【解决方案1】:

删除 * 即可。您的代码*(&amp;home1)-&gt;name 类似于*(home1.name),例如它不是将指针传递给第一个字符,而是传递name 中第一个char 的值;由于默认参数提升,该值被转换为int

因此:

printf("%s\n", (&home1)->name );

应该有效;但是这里不需要-&gt;-&gt; 现在只是更方便地使用指向结构的指针的快捷方式;即(*ptr).name 变成更可口的ptr-&gt;name;由于home 已经是struct 而不仅仅是指向结构的指针,因此您应该改用.

【讨论】:

  • 是的,谢谢,我只是想看看-&gt; 运算符在一个简单的例子中是如何工作的。
【解决方案2】:

您只需删除*(即不取消引用):

printf("%s\n", (&home1)->name );

成员name 是一个数组,它在传递给printf() 时被转换为指针(char*)。但是,当您取消引用它时,您传递的只是一个 char。 显然,它与printf()%s 格式的期望不匹配。

见:What is array decaying?

【讨论】:

  • 成员名 name 是一个数组,它被转换成一个指针 (char*)
    char* 是什么?我只知道 * 作为访问内存地址内容的解引用运算符,为什么解引用运算符将​​其转换为单个字符?我的意思是,我理解*(&amp;home1)-&gt;name 中的* 是多余的(谢谢)...是因为我正在访问的实际内容是向量name 的第一个元素吗?
  • @newbie char* 传递的第二个参数的类型(在 decay 之后 - 请参阅链接)。 -&gt; 暗示结构是一个指针 (&amp;home)。但是*(dereference) 应用于成员name,它是一个数组。取消引用它会得到name[0]name 中的第一个字符)。可能是,如果这样更容易理解,请尝试不使用结构体:char name[30]; scanf("%s", name);,然后查看 printf("%s", name);printf("%s", *name);
  • 非常感谢...我只是在检查那个链接,直到 10 秒前我才看到它。实际上将 * 与 name 一起使用并在您和其他人的帮助下,帮助我更好地理解了 -&gt;* 运算符,甚至了解了 printf() 函数的实际作用。
  • OMG... 我刚刚意识到 * 的从右到左的关联性,并且包裹 &amp;home 的括号使优先级更高,-&gt; 的优先级高于*,所以* 会影响实际的 char[],我猜默认情况下它是第一个 ([0]) 元素。
  • @newbie 或者,array of N 类型的值在大多数情况下(包括,如果前面有 *,或作为参数传递给函数)衰减为 @ 987654355@ 指向数组的第一个元素。
【解决方案3】:

运算符-&gt;. 可以互换:

  • obj.field(&amp;obj)-&gt;field 相同
  • ptr-&gt;field(*ptr).field 相同

请注意,您在(&amp;home1)-&gt;name 的结果中添加了一个星号,这将产生char。由于printf 是一个可变参数函数,因此在调用过程中char 被提升为int,解释了警告。

当您为期望指针的参数传递int 时,会发生未定义的行为;在您的情况下,程序崩溃。删除取消引用运算符* 将解决此问题。

【讨论】:

    【解决方案4】:

    (&amp;home1)-&gt;name 是成员数组。 *(&amp;home1)-&gt;name 是对成员数组的取消引用,由于数组衰减,它等同于 (&amp;home1)-&gt;name[0]。这有类型char。将char 传递给printf 等可变参数函数的... 会将其提升为int... 导致default argument promotions 应用)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-07-03
      • 2014-11-03
      • 1970-01-01
      • 2010-11-03
      • 2013-02-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多