P6 万恶的结构体

客户端和服务端字符串转字节为啥不一样? 客户端 struct hostent* h; // 用于存放服务端IP地址(大端序)的结构体的指针。 if ( (h = gethostbyname(argv[1])) == nullptr ) // 把域名/主机名/字符串格式的IP转换成结构体。 { cout << "gethostbyname failed.\n" << endl; close(sockfd); return -1; } memcpy(&servaddr.sin_addr,h->h_addr,h->h_length); // ③指定服务端的IP(大端序)。 服务端 servaddr.sin_addr.s_addr=inet_addr(argv[1]); // ③指定服务端的IP,只能用IP,不能用域名和主机名。 原因 inet_addr 这个只能转换 ip 地址 gethostbyname 可以支持 IP,域名等等。 对于服务端来说,给他 ip 地址就够了。但是对于客户端来说,他需要连接的更多的可能是域名,而不是 IP。 服务端为什么也要设置 IP 如果服务端是运行于多网卡的服务器上面,那么必须要明确当前这个服务端是服务于那一个网段的,通过设置 servaddr.sin_addr.s_addr 就可以确定服务的网段了。 参考 万恶的结构体

<span title='2023-09-24 18:05:00 +0800 CST'>2023-09-24</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;54 words&nbsp;·&nbsp;RamLife

结构体位域字节对齐

需求 有些时候,一些数据只占用几个 bit,而且是紧密排列的,所以就会考虑使用结构体位域,最好能再带上 union,使用起来会更加方便,但是位域是否字节对齐? 解决 经过测试,如果每一段的位域都在单个字节内,没有跨字节,那么就可以直接使用,字节是对齐的。否则每个跨字节的位域会多占用一个字节,会造成整体的数据错位。 参考 结构体(Struct)、联合体(Union)和位域 union联合体与内存对齐 C语言位域(位段)详解 UNION和位域的使用

<span title='2023-05-18 18:04:00 +0800 CST'>2023-05-18</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;11 words&nbsp;·&nbsp;RamLife

c++ struct 使用初始化列表无效

需求 今天使用统一初始化, {} 初始化 struct 之后,发现数据还是 0,没有初始化进去。 解决 经过网上查找之后,找到问题所在,列表初始化只能用于 aggregate, 而 class, struct, union 是否属于 aggregate, 需要满足以下几个条件: 无自定义构造函数 无私有或受到保护的非静态数据成员 无基类 无虚函数 类的定义中,不能有被 {} 和 = 直接初始化的非静态数据成员 // 自定义构造函数 struct Test { int x; int y; Test(int, int) {} }; // 保护非静态数据成员 struct Test { int x; int y; protected: int z; }; // 基类 struct base{}; struct Test : base { int x; int y; }; // 虚函数 struct Test { int x; int y; virtual void func(int, int) {} }; // 直接初始化 struct Test { int x; int y = 5; }; 所以只要注意以上几点即可,但是如果一定要这种情况下还要能使用列表进行初始化,也是可以的,需要如下定义:...

<span title='2023-04-27 11:45:00 +0800 CST'>2023-04-27</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;116 words&nbsp;·&nbsp;RamLife

C 语言结构体数组,函数指针实现简单的菜单选项功能

需求 需要通过 C 语言实现简单的数码管或者段码液晶屏的简单的菜单选项功能 解决 结构体申明和定义 在 .h 文件中申明: typedef struct value_channel { unsigned char dir; unsigned int ADCValue[128]; }v_c; extern v_c value[4]; 在 .c 文件中定义 v_c value[4]; 函数指针 定义一个函数指针 void ( * fp)(void); 函数功能和跳转 void fun_start_01(void); { ...... } void fun_start(void) { switch(cs) { case 01: fp=fun_start_01; break; } } 在菜单调用的地方使用 ( * fp)(); 即可调用相应的菜单项。 函数地址 函数地址也可以放在数组中来调用: typedef void( * dis_turn)(void); void dis_turn_1(void) void dis_turn_2(void) dis_turn dis[]={dis_turn_1,dis_turn_2}; main() { dis[0](); dis[1](); } 实现菜单 typedef void(*FUN_P)(void);//(int Data) typedef struct Message_Item { unsigned char cStatus; FUN_P fnProcess; }MSG_ITEM; MSG_ITEM MSGMap[]={{0x00,fun_start},{0x01,fun_normal},{0x02,fun_set0},{0x03,fun_gas},{0x04,fun_set}}; void SearchMSGMAP(void) //(unsigned char cStatus) { unsigned char n=0; for(n=0;n<UBOND(MSGMap);n++) { if(MSGMap[n]....

<span title='2010-12-01 22:18:00 +0800 CST'>2010-12-01</span>&nbsp;·&nbsp;1 min&nbsp;·&nbsp;108 words&nbsp;·&nbsp;RamLife