【问题标题】:How two structures can work in this way两种结构如何以这种方式工作
【发布时间】:2016-08-10 11:19:19
【问题描述】:

下面的程序有两个结构。我不明白如何在使用指针时将值从一个结构变量传递到另一个结构变量

#include <stdio.h>

typedef struct {
 int c;
 char d;
}bob;

typedef struct {
int c;
char d;
}anna;

//expecting 'bob' type variable
void fun(bob *var2)
{

printf("var2->c=%d\n",var2->c);
printf("var2->d=%c\n",var2->d);

}

int main()

{
anna var1;
var1.c=2;
var1.d='c';
fun(&var1);//passing 'anna' type pointer
return 0;
}

...但是如果我将程序更改为使用普通变量传递值,则会出现编译错误。

#include <stdio.h>

typedef struct {
 int c;
 char d;
}bob;

typedef struct {
int c;
char d;
}anna;

//expecting a variable of type 'bob'
void fun(bob var2)
{

printf("var2.c=%d\n",var2.c);
printf("var2.d=%c\n",var2.d);

}

int main()

{
anna var1;
var1.c=2;
var1.d='c';
fun(var1);//passing a variable of type 'anna'
return 0;
}

这背后的逻辑是什么?

【问题讨论】:

    标签: c pointers structure


    【解决方案1】:

    首先,第一个版本,警告你。启用适当的编译器选项后,您会看到

    source_file.c:在函数“main”中:
    source_file.c:30:5:警告:从不兼容的指针类型传递“有趣”的参数 1

    fun(&var1);//passing 'anna' type pointer
     ^
    

    source_file.c:16:6:注意:预期为“struct bob *”,但参数类型为“struct anna *”

    void fun(bob *var2)
    

    也就是说,在第一个版本的代码中

    //期待'bob'类型变量

    错了!!它应该是(强调

    //期待一个指向'bob'类型变量的指针

    根据 C 规则,指向类型的指针可以转换为另一种类型,但结果并不总是被定义。所以,第一个版本的代码编译器(带有警告)并运行。

    OTOH,在第二种情况下,annabob 是不同的类型,因此在传递参数和接收参数时无法互换。对于编译器来说,它们是不同的类型,编译器的行为也相应。

    【讨论】:

      【解决方案2】:

      初学者/中级经验者的答案:

      C 中具有不同类型名称的任何两种结构类型都是不兼容的类型。无论它们是否碰巧具有相同的成员变量。同样,指向不同结构类型的指针也不兼容。所以你的类型“bob”和“anna”不兼容,像你尝试的那样使用它们在形式上是不安全的,也不是很好定义的。

      干脆不要做这样的事情,你最终会写出微妙的错误。


      老兵的回答:

      尽管上面提到了类型兼容性规则,C(但不是 C++)允许一些技巧让您以多种不同的方式使用一个内存区域,无论存储在那里的变量的类型如何。这被称为“类型双关语”。大多数情况下,类型双关语是通过union 完成的,例如:

      typedef struct
      {
        bob b;
        anna a;
      } bobanna;
      

      如果您使用指向上述类型的指针,您实际上可以假设这两种类型中的任何一种都可以使用,但这只是因为在这种情况下,所有涉及的结构/联合成员都包含(递归) 相同的类型。例如,这样的代码就可以了:

      void fun (bobanna *var)
      {
        bob* b = var.b;
        b.c = something;
      }
      
      bobanna ba = {.anna.c = 1 };
      fun(&ba);
      

      请注意,类型双关语是一个高级主题。以错误的方式做这样的事情很容易 - 如果你还不知道 pointer aliasingthe strict aliasing rule,我什至不建议考虑上述技巧。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-02-22
        • 2017-04-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-07
        相关资源
        最近更新 更多