Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C编程中访问不完整类型的成员_C - Fatal编程技术网

如何在C编程中访问不完整类型的成员

如何在C编程中访问不完整类型的成员,c,C,假设在我的child.h文件中声明了以下不完整类型 typedef struct child * child_ptr; struct child { char * type; int age; }; // some code before the main int main( void ) { struct child *child = new_child( "Boy", 5 ); child->type; // i know i will get an e

假设在我的
child.h
文件中声明了以下不完整类型

typedef struct child * child_ptr;
struct child {
   char * type;
   int age;
};
// some code before the main 
int main( void ) {
   struct child *child = new_child( "Boy", 5 );
   child->type;  // i know i will get an error
}
我的
child.c
文件中有不完整的完整类型定义

typedef struct child * child_ptr;
struct child {
   char * type;
   int age;
};
// some code before the main 
int main( void ) {
   struct child *child = new_child( "Boy", 5 );
   child->type;  // i know i will get an error
}
假设这是我的
main.c
文件

typedef struct child * child_ptr;
struct child {
   char * type;
   int age;
};
// some code before the main 
int main( void ) {
   struct child *child = new_child( "Boy", 5 );
   child->type;  // i know i will get an error
}

不同于C++、爪哇、C、C,C对封装类型的支持有限。C为封装提供的唯一工具是不完整类型。这些类型描述对象,但缺少确定其大小所需的信息。这就是为什么编译程序后会出现错误的原因。那么,有没有办法访问它们


我认为,一种方法是在我的
child.h
文件中声明“public”函数。例如,一个函数,它获取指向子对象的指针并返回存储在“type”成员变量中的值;但是,这将防止数据隐藏。如果我将结构移动到
child.h
文件中,默认情况下所有成员都是public。同样,这将防止数据隐藏。

您可以在
child.h
文件中创建函数原型,它将
struct child*
作为参数,并返回不同的成员

例如:

char * get_name(child_ptr chld);
child.c
文件中,可以看到
struct child
的定义,并在
main.c
文件中使用它,如下所示:

child_ptr chld = new_child( "Boy", 5 );
char* child_name = get_name(chld);
struct private_child{
  struct child;
  /*private members*/
};

struct child *new_child(/*Init Params*/){
  struct private_child *tmp = malloc(sizeof *tmp);
  /* Initialize the child */
  return &tmp->child;
}

void use_child(const child *c){
  struct private_child *pc = (struct private_child *)c;
  /*access the private members*/
}

您可以在
child.h
文件中创建函数原型,它将
struct child*
作为参数,并返回不同的成员

例如:

char * get_name(child_ptr chld);
child.c
文件中,可以看到
struct child
的定义,并在
main.c
文件中使用它,如下所示:

child_ptr chld = new_child( "Boy", 5 );
char* child_name = get_name(chld);
struct private_child{
  struct child;
  /*private members*/
};

struct child *new_child(/*Init Params*/){
  struct private_child *tmp = malloc(sizeof *tmp);
  /* Initialize the child */
  return &tmp->child;
}

void use_child(const child *c){
  struct private_child *pc = (struct private_child *)c;
  /*access the private members*/
}

您可以在
child.h
文件中创建函数原型,它将
struct child*
作为参数,并返回不同的成员

例如:

char * get_name(child_ptr chld);
child.c
文件中,可以看到
struct child
的定义,并在
main.c
文件中使用它,如下所示:

child_ptr chld = new_child( "Boy", 5 );
char* child_name = get_name(chld);
struct private_child{
  struct child;
  /*private members*/
};

struct child *new_child(/*Init Params*/){
  struct private_child *tmp = malloc(sizeof *tmp);
  /* Initialize the child */
  return &tmp->child;
}

void use_child(const child *c){
  struct private_child *pc = (struct private_child *)c;
  /*access the private members*/
}

您可以在
child.h
文件中创建函数原型,它将
struct child*
作为参数,并返回不同的成员

例如:

char * get_name(child_ptr chld);
child.c
文件中,可以看到
struct child
的定义,并在
main.c
文件中使用它,如下所示:

child_ptr chld = new_child( "Boy", 5 );
char* child_name = get_name(chld);
struct private_child{
  struct child;
  /*private members*/
};

struct child *new_child(/*Init Params*/){
  struct private_child *tmp = malloc(sizeof *tmp);
  /* Initialize the child */
  return &tmp->child;
}

void use_child(const child *c){
  struct private_child *pc = (struct private_child *)c;
  /*access the private members*/
}

在child.h中,提供所有公共成员的定义(并使他们在定义中处于首位)

你不需要让任何人接触你孩子的私人部位,如果你不想让任何人碰它们,我也不会。这只是为了证明你在这里看到的类型还有更多

在child.c中,创建另一个类似的类型:

child_ptr chld = new_child( "Boy", 5 );
char* child_name = get_name(chld);
struct private_child{
  struct child;
  /*private members*/
};

struct child *new_child(/*Init Params*/){
  struct private_child *tmp = malloc(sizeof *tmp);
  /* Initialize the child */
  return &tmp->child;
}

void use_child(const child *c){
  struct private_child *pc = (struct private_child *)c;
  /*access the private members*/
}
您可以在这里看到一些示例,说明如何使用private_child创建新的子级,以及如何通过cast访问child.c中的私有成员。 这将始终有效,因为

(C1x§6.7.2.1.13:“指向经过适当转换的结构对象的指针指向其 初始成员…反之亦然。as结构中可能有未命名的填充 对象,但不是在其开头。”)

编辑


在旧版本的C中,flexible length数组成员可能不可用,您可以忽略子元素的该成员。这个数组实际上使您(可能)想要的类型不完整,因此没有人会意外地尝试在自动存储中创建其中一个类型(它只能通过分配来创建,希望只能使用指定的“构造函数”)。我不确定是否有其他方法可以使C中的类型不完整。

在child.h中提供所有公共成员的定义(并使他们在定义中排在第一位)

你不需要让任何人接触你孩子的私人部位,如果你不想让任何人碰它们,我也不会。这只是为了证明你在这里看到的类型还有更多

在child.c中,创建另一个类似的类型:

child_ptr chld = new_child( "Boy", 5 );
char* child_name = get_name(chld);
struct private_child{
  struct child;
  /*private members*/
};

struct child *new_child(/*Init Params*/){
  struct private_child *tmp = malloc(sizeof *tmp);
  /* Initialize the child */
  return &tmp->child;
}

void use_child(const child *c){
  struct private_child *pc = (struct private_child *)c;
  /*access the private members*/
}
您可以在这里看到一些示例,说明如何使用private_child创建新的子级,以及如何通过cast访问child.c中的私有成员。 这将始终有效,因为

(C1x§6.7.2.1.13:“指向经过适当转换的结构对象的指针指向其 初始成员…反之亦然。as结构中可能有未命名的填充 对象,但不是在其开头。”)

编辑


在旧版本的C中,flexible length数组成员可能不可用,您可以忽略子元素的该成员。这个数组实际上使您(可能)想要的类型不完整,因此没有人会意外地尝试在自动存储中创建其中一个类型(它只能通过分配来创建,希望只能使用指定的“构造函数”)。我不确定是否有其他方法可以使C中的类型不完整。

在child.h中提供所有公共成员的定义(并使他们在定义中排在第一位)

你不需要让任何人接触你孩子的私人部位,如果你不想让任何人碰它们,我也不会。这只是为了证明你在这里看到的类型还有更多

在child.c中,创建另一个类似的类型:

child_ptr chld = new_child( "Boy", 5 );
char* child_name = get_name(chld);
struct private_child{
  struct child;
  /*private members*/
};

struct child *new_child(/*Init Params*/){
  struct private_child *tmp = malloc(sizeof *tmp);
  /* Initialize the child */
  return &tmp->child;
}

void use_child(const child *c){
  struct private_child *pc = (struct private_child *)c;
  /*access the private members*/
}
您可以在这里看到一些示例,说明如何使用private_child创建新的子级,以及如何通过cast访问child.c中的私有成员。 这将始终有效,因为

(C1x§6.7.2.1.13:“指向经过适当转换的结构对象的指针指向其 初始成员…反之亦然。as结构中可能有未命名的填充 对象,但不是在其开头。”)

编辑

在旧版本的C中,flexible length数组成员可能不可用,您可以忽略子元素的该成员。这个数组实际上使您(可能)想要的类型不完整,因此没有人会意外地尝试在