注意结构体分配偏移量时的字节对齐问题 C++可以为结构体定义方法,与class的唯一区别就是默认public
#include <iostream>
using namespace std;
#include <stdio.h> // sprintf
typedef unsigned char u_char;
typedef struct ip_address{
u_char byte1;
u_char byte2;
u_char byte3;
u_char byte4;
char* toString(){
char* str = new char(16);
sprintf(str,"%d.%d.%d.%d",byte1,byte2,byte3,byte4);
return str;
}
bool operator == (const struct ip_address& other) const{
return (byte1 == other.byte1)
&& (byte2 == other.byte2)
&& (byte3 == other.byte3)
&& (byte4 == other.byte4);
}
friend ostream &operator<< (ostream &out,struct ip_address &a) { // &a
//out<<a.byte1<<'.'<<a.byte2<<'.'<<a.byte3<<'.'<<a.byte4; 这句有问题,造成无法输出
out << a.toString();// 注意这里是out 不是cout 还有a.byte1,不是byte1
return out;// 注意要返回
}
}ip_address;
int main() {
ip_address ip1 = {198,163,2,1};
ip_address ip2 = {198,168,22,56};
cout<< "u_char:" << sizeof(u_char)<<endl ;
cout<< "ip_address:" << sizeof(ip_address) << endl; // 方法不占空间!
cout<<ip1.toString()<<endl;
cout<<ip1<<endl;
cout<<ip2.toString()<<endl;
cout<<ip2<<endl;
if(ip1==ip2)
cout<<"ip1 == ip2" <<endl;
else cout<< "ip1 != ip2" <<endl;
ip_address ip3 = {198,163,2,1};
if(ip1==ip3)
cout<<"ip1 == ip3" <<endl;
else cout<< "ip1 != ip3" <<endl;
return 0;
}
/*
Success time: 0 memory: 3472 signal:0
Output:
u_char:1
ip_address4
198.163.2.1
198.163.2.1
198.168.22.56
198.168.22.56
ip1 != ip2
ip1 == ip3
*/
#include <iostream>
using namespace std;
typedef unsigned char u_char;
typedef unsigned short int u_short;
typedef unsigned int u_int;
/*
字节对齐原则
结构体默认的字节对齐一般满足三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量(offset,即每个成员的起始地址)都是成员自身大小的整数倍,如有需要编译器会在成员之间加上填充字节(internal adding);
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节(trailing padding)。
注意:当结构体成员里面有数组成员时,如int a[10],要看成10个整形变量才参与计算。
*/
typedef struct{
u_char flag;
u_short version;
u_short command;
u_short sequence;
u_int number;
}oicq_packet1;
typedef struct{
u_short version;
u_short command;
u_short sequence;
u_int number;
}oicq_packet2;
typedef struct{
u_char flag;
u_char padding; // 2)
u_short version;
u_short command;
u_short sequence;
u_int number;
}oicq_packet3;
typedef struct{
u_short version;
u_short command;
u_short sequence;
u_short padding; // 2)
u_int number;
}oicq_packet4;
int main() {
cout << sizeof(u_char) << endl;
cout << sizeof(u_short) << endl;
cout << sizeof(u_int) << endl;
cout << sizeof(oicq_packet1) << endl;
cout << sizeof(oicq_packet2) << endl;
cout << sizeof(oicq_packet3) << endl;
cout << sizeof(oicq_packet4) << endl;
return 0;
}