结构体(数据类型):定义变量、数组。
struct person {
char name[20];
int age;
char gender;
float height;
};
struct关键字是C语言特有的
struct在C++中的是类
C语言中定义:struct person Yu;
匿名结构体:
匿名结构体只能使用1次
// 匿名结构体
struct {
char name[20];
int age;
char gender;
float height;
};
访问成员:
直接引用 . Yu.name
间接引用 -> p = &Yu p->name
结构体申请空间的对齐方式:
根据定义顺序已知最长的长度的倍数来决定最终的占内存大小。
对齐方式是根据相应成员的类型,与其倍数的地址对齐。不够的补空白。
name占用20字节[0-19]
age占用4字节[20-23]
gender占用1字节[24],其中[25-27]是空的
height占用4字节[28-31]
#include <stdio.h>
struct node1 {
char a;
char b;
int c;
};
struct node2 {
char a;
int c;
char b;
};
int main() {
printf("node1 = %d\n", sizeof(node1));
printf("node2 = %d\n", sizeof(node2));
return 0;
}
node1内存占用:
char a占[0]
char b占[1]
[2-3]空位
int c占[4-7]
node1占8B
node2内存占用:
char a占[0]
[1-3]空位
int c占[4-7]
char b 占[8]
[9-11]空位
node2占12B
相同类型放一起声明,会更节约空间。
-----------------------------------------------
共用体(数据类型):定义变量、数组。
若干变量共用同一片内存
关键字 union
union register {
struct {
unsigned char byte1;
unsigned char byte2;
unsigned char byte3;
unsigned char byte4;
} bytes;
unsigned int number;
};
里面有两个基本字段:
匿名结构体 定义的 变量bytes 占4B
无符号整形 number 占4B
其内存形式:
[0 bytes(byte1)][0 number]
[1 bytes(byte2)][1 ]
[2 bytes(byte3)][2 ]
[3 bytes(byte4)][3 ]
共用体哪个字段的大,则内存有多大
访问形式同结构体:直接引用、间接引用。
union node {
double a;
char b;
int c;
};
其内存占用结构图;
[0 double][0 char][0 int]
[1 ][ ][1 ]
[2 ][ ][2 ]
[3 ][ ][3 ]
[4 ][ ][ ]
[5 ][ ][ ]
[6 ][ ][ ]
[7 ][ ][ ]
[8 ][ ][ ]
如果8个字节都取了,则当为a变量
只取1B,则是b变量
连续取4B,则是c变量
如果:
union node {
double a;
char b[20];
int c;
};
则占24B,因为最大的是double,如果去掉double a,则占20B
随堂练习:
使用共用体,实现ip转整数的功能。
用4B表示ip,需要unsigned int
uint_8 用%hhd
my_code:
#include <stdio.h>
union ip {
unsigned char arr[4];
unsigned int a;
};
int main() {
union ip ip1;
scanf("%hhd.%hhd.%hhd.%hhd", &ip1.arr[0], &ip1.arr[1], &ip1.arr[2], &ip1.arr[3]);
printf("%u\n", ip1.a);
return 0;
}
船长code:
#include <stdio.h>
union IP {
struct {
unsigned char a1;
unsigned char a2;
unsigned char a3;
unsigned char a4;
} ip;
unsigned int num;
};
int main() {
union IP p;
char str[100] = {}; // 接收输入的ip地址字符串
while (~scanf("%s", str)) {
sscanf(str, "%hhd.%hhd.%hhd.%hhd", &p.ip.a1, &p.ip.a2, &p.ip.a3, &p.ip.a4);
printf("%u", p.num);
}
return 0;
}
此处可看大端小端,目前主流存储方式都是小端机。大端是历史电脑机
小端:数字的低位->低地址位
大端:数字的低位->高地址位
大端机数据存储:
高位 低位
[192][168][0][1]
0 1 2 3
低地址 高地址
小端机数据存储:
低位 高位
[1][0][168][192]
0 1 2 3
低地址 高地址
证明自己是小端机:
是小端机输出1
存一个int 1 看看在4B中的低地址还是高地址
is_litle() {
int num = 1;
return ((char *)(&num))[0];
}
/*
0是低地址
3是高地址
*/
字节序:
①主机字节序(大小端问题)/本地字节序
socket需要本地字节序转换成网络字节序
②网络字节序
------------------------------------------------
enum 枚举型,相当于符号常量
有enum weekday {Sun, Mon, Tue, Wed, Thu, Fri, Sar} day1, day2;
day1 > Sat 等价于 day1 > 6
-----------------------------------------------
OJ203:
快速排序: