在C编程中使用Struct Tag名称有什么用?

时间:2017-05-25 12:01:15

标签: c struct

我想知道在C编程中实际使用struct tag_name。如果不使用tag_name,我也会使用tag_name获取输出。我想知道这个过程背后的确切原因。

例如:

//With tag_name st1
struct st1 { int x; char c;}x={100,'a'},y={70,'e'};

//Without any tag_name
struct { int x; char c;}x={100,'a'},y={70,'e'};

printf("x.x= %d \t x.c= %c \n",x.x,x.c);   //Output: x.x=100    x.c=a
printf("y.x= %d \t y.c= %c \n",y.x,y.c);   //Output: y.x=70     y.c=e

3 个答案:

答案 0 :(得分:6)

在第一种情况下:

struct st1 { 
    int x; 
    char c;
} x = {100, 'a'}, y = {70, 'e'};

您声明了名为struct st1的类型,并且您还创建了两个此类型的对象xy。因此,您可以随时创建此类型的对象,如下所示:

struct st1 obj1;

然而在第二种情况下:

struct { 
    int x; 
    char c;
} x = {100, 'a'}, y = {70, 'e'};

您创建了struct和两个对象xy,但您无法再次访问struct。这意味着您无法创建此类型的任何新对象。

答案 1 :(得分:2)

结构体声明告诉编译器结构体的外观,并有选择地为该结构体命名。如果要将结构用作代码中的“类型”,则需要一个名称:

struct coordinate {
  int x;
  int y;
};

// Can now be used as a return type:
struct coordinate getCoordinate ( ) { ... }

// Can now be used as an argument:
void drawAtPoint ( struct coordinate point ) { ... }

// Can be used to create new constants or variables:
const struct coordinate kOrigin = { 0, 0 };
struct coordinate lastViewPosition;

或者,您可以创建一个无名结构,并使用类型定义将其显式定义为新类型:

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

// Can now be used as a return type:
coordinate getCoordinate ( ) { ... }

// Can now be used as an argument:
void drawAtPoint ( coordinate point ) { ... }

// Can be used to create new constants or variables:
const coordinate kOrigin = { 0, 0 };
coordinate lastViewPosition;

但是如果您什么都不做,就不能将该结构用作类型,因为在C语言中,结构的类型由其名称而不是其数据布局定义。

以下是有效的C代码:

struct coordinate {
  int x;
  int y;
};

struct coordinate startCoord = { 20, 80 };
struct coordinate endCoord = startCoord;

但以下不是:

struct {
  int x;
  int y;
} startCoord = { 20,  80 };

struct {
  int x;
  int y;
} endCoord = startCoord;

编译器将因错误而失败。在两个示例中,似乎startCoordendCoord具有相同的类型,但这不是事实。两个结构不仅仅因为它们具有相等的内存布局或相等的字段名称就表示相同的类型。对于C编译器,在后面的示例中startCoordendCoord具有不同的类型,因此您无法如上所示分配它们,因为这要求它们都具有相同的类型。

因此,唯一可以跳过命名结构的情况是直接声明该结构类型的变量,而无需在整个代码中再次将该结构称为数据类型。

答案 2 :(得分:1)

如果您使用该标记,则可以在以后创建更多类型为struct st1的变量(或从中派生的类型(例如,struct st1*)):

struct st1 z, *zp;

之后:

struct { int x; char c;}x={100,'a'},y={70,'e'};

你永远不能再创造这种类型的变量了。

虽然你能做到:

struct { int x; char c;} z = {80, 'f'}; 
//same layout and member names

就涉及别名和类型检查而言,它的类型与x和y的类型不同。

标签允许您重复使用该类型。

(Typedefing an anousous struct

typedef struct { int x; char c;} st1;
st1 x,y,z;

是重用该类型的另一种方法。)