在C语言中,类型化的结构是如何工作的?

bvhaajcl  于 2022-12-17  发布在  其他
关注(0)|答案(3)|浏览(150)

带标签的结构允许你创建一个示例(或者任何在c中被调用的示例)。那么typedef结构呢?如果typedef是为了用类型名替换struct关键字,那么每次你使用typename不就是在说你用类型名替换了struct关键字吗?例如:

typedef struct {
    int x;
    int y;
}TypeName;

int main()
{

    TypeName instance; // isn't this the same as writing struct instance; ?

    return 0;
}

那么,在结构体上使用typedef时,它是如何工作的呢?

k7fdbhmy

k7fdbhmy1#

它定义了一个没有名称的结构体,然后将TypeName作为该结构体的名称。
如果愿意,可以想象编译器为您创建了一个随机名称(有些编译器确实是这样做的):

typedef struct __TOTALLY_RANDOM_NAME_wieryweuoi3u4t23423cogh234283 {
    int x;
    int y;
}TypeName;

int main()
{
    struct __TOTALLY_RANDOM_NAME_wieryweuoi3u4t23423cogh234283 instance;

    return 0;
}
rnmwe5a2

rnmwe5a22#

如果结构定义没有标记,则每次显示时其类型都不同。例如:

int main(void)
{
    struct { double a, b; } x;
    struct { double a, b; } y = { 0, 0 };
    x = y;
}

将收到错误消息,因为xy是不兼容的类型。
当使用typedef时,它为类型起了一个新的名字。它不像宏替换那样重复以前的源代码;它是概念类型的名称,而不是源代码的名称。因此,此源代码不会收到错误消息:

int main(void)
{
    typedef struct { double a, b; } T;
    T x;
    T y = { 0, 0 };
    x = y;
}

相同的结构定义被认为具有不同类型的一个原因是,我们可能希望将它们用于不同的目的,例如,我们可能使用typedef struct { double v[2]; } Point;来表示平面中使用两个坐标的点,使用typedef struct { double v[2]; } Complex;来表示使用真实的部和虚部的复数,并且我们希望在程序中将它们作为单独的类型处理。

hyrbngr7

hyrbngr73#

struct { int x; int y; }是一个匿名结构类型,它与任何其他具有完全相同成员的结构类型都不同(即使它们共享相同的二进制布局)。
在下列声明之后:

struct {
   int x;
   int y;
} a, b;

struct {
   int x;
   int y;
} c;

则变量a与变量b具有相同的类型,但与变量c具有不同的类型。出于同样的原因,以下代码对于变量d具有冲突的类型:

extern struct {
    int x;
    int y;
} d;  // external declaration of `d`.

extern struct {
    int x;
    int y;
} d;  // INVALID: conflicting external declaration of `d`.

struct {
    int x;
    int y;
} d = { 23, 42 }; // INVALID: conflicting definition of `d`.

类型定义(使用typedef关键字声明)对于将标识符定义为指定类型的同义词“typedef名称”很有用。typedef声明不创建任何新类型,它只为现有类型创建同义词。2在其他声明中出现typedef名称表示原始类型。这对于捕获匿名类型以便可以在多个声明中使用它们特别有用。例如,在以下声明之后:

typedef struct {
   int x;
   int y;
} TypeName;

TypeName a, b;

TypeName c;

extern TypeName d;

extern TypeName d;

TypeName d = { 23, 42 };

typedef名称TypeName表示匿名结构类型。变量abcd都具有相同的匿名结构类型。变量d的外部声明与其定义之间没有冲突。
再举一个例子,在下列声明之后:

typedef struct {
   int a;
   int b;
} Type1, Type2, TypeArr1[10];

typedef Type2 TypeArr2[10];

typedef struct {
   int a;
   int b;
} Type3;

extern Type1 a;
extern Type2 a; // no conflict with previous declaration of variable `a`.
extern Type3 a; // INVALID! conflicting types for variable `a`.

extern TypeArr1 arr;
extern TypeArr2 arr; // no conflict with previous declaration of variable `arr`.
  • Type1Type2表示彼此相同的类型。
  • TypeArr1表示长度为10的数组类型,其元素类型与由Type1表示的元素类型相同。
  • TypeArr1TypeArr2表示彼此相同的数组类型(具有相同的数组长度和元素类型)。
  • Type1Type3表示不同的类型,因此它们在变量a声明中的使用是冲突的。

相关问题