C/C++语言中struct的深入探讨

转载 2012年03月27日 21:35:45
文章整理自:
一. struct的巨大作用
  面对一个人的大型C/C++程序时,只看其对struct的使用情况我们就可以对其编写者的编程经验进行评估。因为一个大型的C/C++程序,势必要涉及一些(甚至大量)进行数据组合的结构体,这些结构体可以将原本意义属于一个整体的数据组合在一起。从某种程度上来
说,会不会用struct,怎样用struct是区别一个开发人员是否具备丰富开发经历的标志。
  在网络协议、通信控制、嵌入式系统的C/C++编程中,我们经常要传送的不是简单的字节流(char型数组),而是多种数据组合起来的一个整体,其表现形式是一个结构体。
  经验不足的开发人员往往将所有需要传送的内容依顺序保存在char型数组中,通过指针偏移的方法传送网络报文等信息。这样做编程复杂,易出错,而且一旦控制方式及通信协议有所变化,程序就要进行非常细致的修改。
  一个有经验的开发者则灵活运用结构体,举一个例子,假设网络或控制协议中需要传送三种报文,其格式分别为packetA、packetB、packetC
struct structA 
{
int a;
char b;
};
struct structB 
{
char a;
short b;
};
struct structC
{
int a;
char b;
float c;
}
优秀的程序设计者这样设计传送的报文:
struct CommuPacket
{
int iPacketType;  //报文类型标志
union      //每次传送的是三种报文中的一种,使用union
{
  struct structA packetA;
   struct structB packetB;
   struct structC packetC;
}
};
在进行报文传送时,直接传送struct CommuPacket一个整体。
假设发送函数的原形如下:
// pSendData:发送字节流的首地址,iLen:要发送的长度
Send(char * pSendData, unsigned int  iLen);
发送方可以直接进行如下调用发送struct CommuPacket的一个实例sendCommuPacket
Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );
假设接收函数的原形如下:
// pRecvData:发送字节流的首地址,iLen:要接收的长度 返回值:实际接收到的字节数
unsigned int Recv(char * pRecvData, unsigned int  iLen);
接收方可以直接进行如下调用将接收到的数据保存在struct CommuPacket的一个实例recvCommuPacket中:
Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );
接着判断报文类型进行相应处理:
switch(recvCommuPacket. iPacketType)
{
    case PACKET_A:
    …    //A类报文处理
    break;
    case PACKET_B:
    …   //B类报文处理
    break;
    case PACKET_C:
    …   //C类报文处理
    break;
}
以上程序中最值得注意的是
Send( (char *)&sendCommuPacket , sizeof(CommuPacket) );
Recv( (char *)&recvCommuPacket , sizeof(CommuPacket) );
中的强制类型转换:(char *)&sendCommuPacket、(char *)&recvCommuPacket,先取地址,再转化为char型指针,这样就可以直接利用处理字节流的函数。
  利用这种强制类型转化,我们还可以方便程序的编写,例如要对sendCommuPacket所处内存初始化为0,可以这样调用标准库函数memset():
memset((char *)&sendCommuPacket,0, sizeof(CommuPacket));
二. struct的成员对齐
关于此请参考《C语言struct内存占用问题
三、 C和C++间struct的深层区别
  在C++语言中struct具有了“类” 的功能,其与关键字class的区别在于struct中成员变量和函数的默认访问权限为public,而class的为private。
  例如,定义struct类和class类:
struct structA
{
char a;
}
class classB
{
      char a;
      …
}
则:
struct A a;
a.a = 'a';    //访问public成员,合法
classB b;
b.a = 'a';    //访问private成员,不合法
  许多文献写到这里就认为已经给出了C++中struct和class的全部区别,实则不然,另
外一点需要注意的是:
  C++中的struct保持了对C中struct的全面兼容(这符合C++的初衷——“a better c”
),因而,下面的操作是合法的:
//定义struct
struct structA
{
char a;
char b;
int c;
};
structA a = {'a' , 'a' ,1};    //  定义时直接赋初值
  即struct可以在定义的时候直接以{ }对其成员变量赋初值,而class则不能,在经典
书目《thinking C++ 2nd edition》中作者对此点进行了强调。
四、struct编程注意事项
  看看下面的程序:
1. #include <iostream.h>
2. struct structA
3. {
4. int iMember;
5. char *cMember;
6. };
7. int main(int argc, char* argv[])
8. {
9. structA instant1,instant2;
10.char c = 'a';
    
11. instant1.iMember = 1;
12. instant1.cMember = &c;

13.instant2 = instant1;

14.cout << *(instant1.cMember) << endl;

15.*(instant2.cMember) = 'b';

16. cout << *(instant1.cMember) << endl;

17. return 0;
}
14行的输出结果是:a
16行的输出结果是:b
  Why?我们在15行对instant2的修改改变了instant1中成员的值!
  原因在于13行的instant2 = instant1赋值语句采用的是变量逐个拷贝,这使得instant1和instant2中的cMember指向了同一片内存,因而对instant2的修改也是对instant1的
修改。
  在C语言中,当结构体中存在指针型成员时,一定要注意在采用赋值语句时是否将2个实例中的指针型成员指向了同一片内存。
  在C++语言中,当结构体中存在指针型成员时,我们需要重写struct的拷贝构造函数并进行“=”操作符重载。

C/C++语言中struct的深入探讨

C/C++语言中struct的深入探讨 分类: C和C++语言2012-03-27 21:35 291人阅读 评论(0) 收藏 举报 struct语言class编程网络协议c ...
  • zdy0_2004
  • zdy0_2004
  • 2014年10月13日 00:52
  • 495

C语言中的struct用法

结构(struct)      结构是由基本数据类型构成的、并用一个标识符来命名的各种变量的组合。  结构中可以使用不同的数据类型。      1. 结构说明和结构变量定义      在Tur...
  • tuoguang
  • tuoguang
  • 2015年07月17日 15:44
  • 9875

C语言中struct和typedef struct的区别

最常见的一共有三种写法: struct{ int x; int y; }test1; struct test {int x; int y; }test1; typedef struc...
  • foreverhuylee
  • foreverhuylee
  • 2014年08月23日 16:52
  • 1453

C和C++中struct使用的区别

今天参看了louden用c编写的编译器,发现其中一些地方使用struct很奇妙。所以又研究了一下struct的区别,并发现c和c++在某些地方是有区别的。 struct作为类的一种特...
  • CSDNwei
  • CSDNwei
  • 2016年02月19日 14:39
  • 1477

C语言中,struct与union的区别

struct和union是C语言中两种不同的数据结构,两者都是常见的复合结构,其区别主要表现在两方面: 1、联合体中所有成员共用一块地址空间,即联合体只存放了一个被选中的成员,而结构体中所有成员占用...
  • zhaojian_li
  • zhaojian_li
  • 2015年07月28日 09:29
  • 605

深入解析C语言中typedef的四个用途

作者: 字体:[增加 减小] 类型:转载 时间:2013-08-22 我要评论 以下是对C语言中typedef的四个用途进行了详细的分析介绍,需要的朋友可以过来参考下 ...
  • fcsfcsfcs
  • fcsfcsfcs
  • 2017年08月27日 09:39
  • 73

C语言中的sizeof(struct )和sizeof(union)

一般32位机上各数据类型所占存储空间为: char : 8位 short : 16位 int : 32位 long : 32位 float : 32位 double : 64位 一、结构体stru...
  • yagnruinihao
  • yagnruinihao
  • 2013年11月06日 21:19
  • 1919

C语言中的结构体(struct)

C语言中,结构体类型属于一种构造类型(其他的构造类型还有:数组类型,联合类型)。本文主要介绍关于结构体以下几部分。 1、概念为什么要有结构体?因为在实际问题中,一组数据往往有很多种不同的数据类型。例...
  • yanggangclcsdn
  • yanggangclcsdn
  • 2015年11月08日 13:50
  • 3182

c语言struct的一种初始化方法

typedef struct str{    int a;    int b;}Str;int main(){    Str s={a:1,b:2};//注意这里的冒号    printf("a=%d...
  • jemmy
  • jemmy
  • 2006年02月21日 23:23
  • 4750

Struct嵌套使用

嵌套结构体 结构体也是一种递归定义:结构体的成员具有某种数据类型,而结构体本身也是一种数据类型。换句话说,结构体的成员可以是另一个结构体,即结构体可以嵌套定义。以下的例子中,每个结构体、联合,都可以...
  • loong460
  • loong460
  • 2016年05月19日 11:25
  • 2132
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:C/C++语言中struct的深入探讨
举报原因:
原因补充:

(最多只允许输入30个字)