一、结构体(自定义数据类型)
1.定义
(1)声明结构体类型的一般形式:
2)对各成员的类型声明:
2.定义结构体类型变量
(3)在声明结构体类型在定义变量名:
(4)在声明结构体类型的同时定义变量名:
注意,变量名列表要放在分号前进行;
(5)结构体变量的引用:结构体变量名 . 成员名,其中.是结构体成员运算符;
struct Student
{
int id;
char name[10];
float score;
};
int main()
{
struct Student s;
return 0;
}
2.初始化:
//全部初始化
struct Student s = {1, "zhangsan", 99};
//结构体成员部分初始化,没初始化的部分默认清零
struct Student s = {
.id = 1,
.score = 99;
};
3.赋值:
s.id = 1;
strcpy(s.name, "zhangsan");
s.score = 98;
4.结构体与结构体之间不可比较,但是结构体的成员可以比较;
5.排序
(2)逆序
void reverseStruct(struct student *a,int len)
{
int i;
for(i = 0 ;i < len /2;++i)
{
struct student t;
t = a[i];
a[i] = a[len - i -1];
a[len - i - 1] = t;
}
}
(3)用回调函数排序
int nameCmp(struct student *a,struct student *b)
{
return strcmp(a->name,b->name);
}
int nameCmpP2(const void *a,const void *b)
{
struct student *a1 = (struct student *)a;
struct student *b1 = (struct student *)b;
return strcmp(a1->name,b1->name);
}
int scroeCmp(struct student *a,struct student *b)
{
if(a->scroe > b->scroe)
{
return 1;
}
else if(a->scroe == b->scroe)
{
return 0;
}
else
{
return -1;
}
}
void sortStructStudentsP2(struct student *a,int len,int (*pfn)(struct student *,struct student *))
{
int i,j;
for(i = 0 ;i < len -1 ;++i)
{
for( j = i + 1 ; j < len ;++j)
{
if(pfn(a+i,a+j))
{
swap((a+i),(a+j));
}
}
}
}
(3)用回调函数排序
int nameCmp(struct student *a,struct student *b)
{
return strcmp(a->name,b->name);
}
int nameCmpP2(const void *a,const void *b)
{
struct student *a1 = (struct student *)a;
struct student *b1 = (struct student *)b;
return strcmp(a1->name,b1->name);
}
int scroeCmp(struct student *a,struct student *b)
{
if(a->scroe > b->scroe)
{
return 1;
}
else if(a->scroe == b->scroe)
{
return 0;
}
else
{
return -1;
}
}
void sortStructStudentsP2(struct student *a,int len,int (*pfn)(struct student *,struct student *))
{
int i,j;
for(i = 0 ;i < len -1 ;++i)
{
for( j = i + 1 ; j < len ;++j)
{
if(pfn(a+i,a+j))
{
swap((a+i),(a+j));
}
}
}
}
6.结构体在内存所占字节数
内存对齐原则:空间换时间,提高程序运行效率
(1)默认按照计算机位数对齐,64/8=8最终大小必须是8的整数倍;(32位系统下默认4字节对齐)
(2)从结构体中的成员中查找最大字节的成员,最终按此成员大小对齐;
(3)把每个成员按照声明顺序依次存放入内存,偏移量/sizeof(成员)必须能够整除。
7.
二、共用体(自定义数据类型)
1.声明格式:
2.sizeof(union **):
1)成员相互共用内存,(int i;short s;char c)
(2)最终的大小 = 里面成员的最长空间的大小;
3.访问:对共用体进行访问时的结果,是对最后赋值的成员的结果;共享总是从起始位置进行共享,即所有成员的起始地址都相同;
4.用共用体判断本机的大小端
5.共用体通常用于协议里面,协议:双方通信时遵循的协议;共用体在里面的作用时降低通信内存的负担,提高通信的效率;
三、枚举(自定义数据类型)
1.目的:创建一个数据类型,枚举一些需要的,这个数据类型的范围就是所枚举的;
2.声明格式:
enum 名
{
枚举值列表;
};
3.使用 :enume 名 变量名;
变量名 = 枚举值;
4.打印枚举都可以用%d打出,sizeof是4,printf(“%d”,w);是w枚举值的位置,位置可以自己指定,要注意避免枚举值不要重复;
四、用typedef定义类型()
1.给原有的数据类型起个别名;
2.使用:此时INT不是变量名,是个数据类型名,给int起了别名INT;
typedef int INT;
int main(void)
{
INT a;
return 0;
}
typedef struct
{
int id;
char name[10];
}student;
int main(void)
{
student s;
}
五、位运算
1.作用:用于硬件的操作;
2.位运算符
(1)逻辑左移:平行左移,高位丢弃,低位补零;
(2)~是单目运算符优先级别2级,结合方向自右向左;
(3)右移:有符号位称算术右移;无符号位移称逻辑右移;
注意,枚举也可进行位运算;
(2)作用
按位与:指定位清零;
按位或:指定位置1;
按位异或:指定位翻转,其他位不变;
按位取反:全翻转;