user-0 提问: 有关结构体，共同体，指针

回复:
user: user-1
content: 引用 4 楼 weixin_36741484 的回复:看了大家的讲解，懂了很多，还有一点没有弄懂， void (*free)(struct String *ptr); 中String为typedef定义的结构体别名，现在这个定义还没有结束，在定义的过程中又用到这个别名，那么和在定义结束后用这个别名有什么区别？ 另外free()在c语言中本来就是一个函数，这里又把它定义为一个函数指针变量，是对free()进行了二次定义了吗？ 希望能帮忙再解答一下 首先要明白“不完全类型（imcomplete type）”的概念： 如果有一个定义类String class String;//声明String，未定义 在声明之后，定义之前，自定义类就是一个不完全类型。即已知String是一个类型，但是不知道包含哪些成员。 同理，“完全类型”指的是定义之后的类。只有当类A为“完全类型”时，在类B中数据成员才能被指定为类A的类型，如果累A是“不完全类型”，则类B的数据成员只能是类A的指针或者引用。 这样，如果类A中要包含本身A的数据成员，因为在定义类A的数据成员时，类A肯定是“不完全类型”，所以，类A的数据成员可以且只能是自身类型的指针或引用。 void (*free)(struct String *ptr); free函数指针的参数是String*是正确的，如果是String则错误！

user: user-1
content: union（联合）是一种特殊的类。一个union可以有多个数据成员，但是在任意时刻只有一个数据成员可以有值。union提供了一种有效的途径使得可以方便地表示一组类型不同的互斥值。   union {         char *buf;         char array[16];     } o;  个人认为这种union的定义方式，就是某个数据的两种不同表示方式。如果需要一个整体的字符串，则使用array数组，如果需要字符串中的某个字符或者某个子字符串，则使用char指针buf。 这种定义union的方法就像套接字编程里面对IP地址节结构in_addr的定义类似 struct in_addr{ union{   struct{     unsigned char s_b1, s_b2, s_b3, s_b4; }S_un_b;   struct{ unsigned short s_w1, s_w2;   }S_un_w;   unsigned long S_addr; }S_un; }; 在struct中包含了一个union，在这个union中包含了IP地址的各种形式。如果需要IP地址的unsigned long，则使用S_addr，如果需要IP地址的四个段，则使用结构S_un_b，里面包含了四个段。这样就不需要额外再将IP地址转换为四个段的代码了。

user: user-0
content: 看了大家的讲解，懂了很多，还有一点没有弄懂， void (*free)(struct String *ptr); 中String为typedef定义的结构体别名，现在这个定义还没有结束，在定义的过程中又用到这个别名，那么和在定义结束后用这个别名有什么区别？ 另外free()在c语言中本来就是一个函数，这里又把它定义为一个函数指针变量，是对free()进行了二次定义了吗？ 希望能帮忙再解答一下

user: user-2
content: 引用 5 楼 hou09tian 的回复:union（联合）是一种特殊的类。一个union可以有多个数据成员，但是在任意时刻只有一个数据成员可以有值。union提供了一种有效的途径使得可以方便地表示一组类型不同的互斥值。   union {         char *buf;         char array[16];     } o;  个人认为这种union的定义方式，就是某个数据的两种不同表示方式。如果需要一个整体的字符串，则使用array数组，如果需要字符串中的某个字符或者某个子字符串，则使用char指针buf。 这种定义union的方法就像套接字编程里面对IP地址节结构in_addr的定义类似 struct in_addr{ union{   struct{     unsigned char s_b1, s_b2, s_b3, s_b4; }S_un_b;   struct{ unsigned short s_w1, s_w2;   }S_un_w;   unsigned long S_addr; }S_un; }; 在struct中包含了一个union，在这个union中包含了IP地址的各种形式。如果需要IP地址的unsigned long，则使用S_addr，如果需要IP地址的四个段，则使用结构S_un_b，里面包含了四个段。这样就不需要额外再将IP地址转换为四个段的代码了。 C语言的数据结构不建议使用C++的语法知识来分析，结构体和类还是有一定区别的。

user: user-2
content: 引用 5 楼 hou09tian 的回复:union（联合）是一种特殊的类。一个union可以有多个数据成员，但是在任意时刻只有一个数据成员可以有值。union提供了一种有效的途径使得可以方便地表示一组类型不同的互斥值。   union {         char *buf;         char array[16];     } o;  个人认为这种union的定义方式，就是某个数据的两种不同表示方式。如果需要一个整体的字符串，则使用array数组，如果需要字符串中的某个字符或者某个子字符串，则使用char指针buf。 这种定义union的方法就像套接字编程里面对IP地址节结构in_addr的定义类似 struct in_addr{ union{   struct{     unsigned char s_b1, s_b2, s_b3, s_b4; }S_un_b;   struct{ unsigned short s_w1, s_w2;   }S_un_w;   unsigned long S_addr; }S_un; }; 在struct中包含了一个union，在这个union中包含了IP地址的各种形式。如果需要IP地址的unsigned long，则使用S_addr，如果需要IP地址的四个段，则使用结构S_un_b，里面包含了四个段。这样就不需要额外再将IP地址转换为四个段的代码了。 “但是在任意时刻只有一个数据成员可以有值” 这句话有问题，不是只有一个成员有值，而是它们共同有这个值。根据成员占用字节数，区分占有这个值的多少个字节。

user: user-3
content: //编译平台vs2013 #include <stdio.h>  typedef  void(*FUNCPTR)(int);  //定义一个函数 void my_int_func(int x){ 	printf("output:%d\n", x); }  int _tmain(int argc, _TCHAR* argv[]) { 	void(*foo)(int x); //定义一个函数指针foo 	void(*fsa)(int x); //定义一个函数针织fsa 	foo = my_int_func; //初始化函数指针 	fsa = &my_int_func; //初始化函数指针，此处目的是告诉你在初始化函数指针时，是否使用“&”并无关系 	FUNCPTR fun = my_int_func; //定义一个函数指针并初始化 	foo(3);  //调用函数 	fsa(4); 	fun(5); 	return 0; }  我想这段代码可以告诉你前面void (*free)(struct String *ptr);的意思了。 关于struct与union的知识点，需要你花点时间去理解一下书本

user: user-4
content: 仅供参考：//char (*(*x[3])())[5];//x是什么类型的变量? // //分析C语言声明，关键是搞清楚这个变量是个什么东西（函数、指针、数组）， //是函数那么剩下的就是他的参数和返回值， //是指针那剩下部分是说明他指向什么， //是数组剩下的部分就是说明数组的成员是什么类型。 //解析C语言声明规则： //从左侧第一个标识符开始，按照优先级进行结合。*表示是..的指针，const表示只读的，volatile表示可变的，[]表示是数组，()表示是函数。 // //x和[3]结合说明是一个大小为3的数组，该数组的每个元素为一类指针，该类指针指向一类函数，该类函数无参数，返回一类指针，该类指针指向一个大小为5的char型数组 #include <stdio.h> #include <typeinfo.h> char num[5]; char (*x00())[5] {     return # } int main() {     char (*(*x[3])())[5];//是个数组，大小为3     char (*(*x0  )())[5];//数组的元素，是个函数指针     char (*( x00 )())[5];//函数原型，参数为空，返回值为指针     char (*  x000   )[5];//返回值      x0 = x00;     x[0] = x0;     x[1] = x0;     x[2] = x0;     printf("typeid(x).name() is %s\n",typeid(x).name());     return 0; } //typeid(x).name() is char (* (__cdecl**)(void))[5]

user: user-5
content: void (*free)(struct String *ptr);是一个函数指针，union是一个共同体。

user: user-2
content: void (*free)(struct String *ptr); 这个是一个函数指针变量，即它也是一个变量，只不过比较特殊是一个函数指针变量，它可以指向一个参数为struct String类型指针变量，返回值为void的函数。它是结构体String的一个元素。 联合体o也是结构体的一个元素，联合体里有一个数组和一个指针，即若缓存较大时（大于16个字节）可以用指针存放一个缓存（大于16个字节）的首地址。如果缓存不大于16，可以直接用array，联合体的长度是16个字节。