一、联合union
联合是以能在同一个存储空间里(但不同时)存储不同类型数据的数据类型。
例:
union data
{
unsigned char a;
unsigned int b ;
};
sizeof(data) = ? //表示求这个联合里面最大的数据类型 4个字节(int)
data.b = 0x12345678;
data.a= ? //0x78
data.a=0xef;
data.b=? //0x123456ef
例题:如何定义: // 判断计算机是大小端字节序?(也可用指针来实现)
int ls_lsb(void)
{
union byteorder
{
int a;
char b;
}byte;
byte.a = 0x12345678;
if(byte.b ==0x78)
return 1;
else
return 0;
}
二、枚举enum:可以使用枚举类型声明表示整数常量的符号名称。//偶尔当作宏来使用
enum //int类型
{
Gold, //枚举第一个参数默从0开始 0
Wood, //后面的值会在前面的值自加 1
Water, // 2
Fire = 8,
Earth, //9
};
swith (five_line)
{
case Gold;
do_something;
break;
default;
break;
}
三、结构体:类似C++中的类
结构体可以有几本数据类型构造出一种新的符合数据类型来。
例如:
#define male 0
#define female 1
enum{ male,female};
struct _st_stdudent
{
char name[32];
int gender;
int age;
float score;
}student;
struct _st_student student = {"zhangsan",male,20,90,0};
struct _st_student student = {.name="zhangsan",.gender=male,.age=20,.score=90.0}; //调用结构体的数据需要.
printf("Name:%s Gender:%d Age:%d Score:%f\n",student.name,student.gender,student.age,student.score);
四、Typedef
用来定义一种新的数据
typedef unsigned char u8; //u8 var1,var2;
typedef unsigned short uint_16; //uint_16 var1,var2;
对比:
typedef char * pchar;
#define PCHAR char *;
typedef struct _st_student //定义了一种_st_syduent结构体这种新类型(一般_****的函数是低级函数,除非你了解低级函数的功能否则不要调用)
{
char name[32];
int gender;
int age;
float score;
}st_student; //如果没有typeof 那么此处为变量,有的话就是一个新的类型 st_student== struct _st_student
st_student student; == struct_st_student student;
#结构体对齐 (空间换时间、时间换空间 注:[]为空间1个字节)
若题目没有要求,默认系统为32位
typedef struct_st_struct1
{
char a; // [] 1个字节
short b; // [][] 2个字节
int c; // [][][][] 4个字节
}st_struct1;
sizeof(st_struct1)=? //存储空间8字节 解:a的对齐值1的整数倍,b的对齐值2的整数倍,c的对齐值4的整数倍故,故占[][][][][][][][]8个字节(第二个[]是由于b存放值必须是2的整数倍故空出来的,其次整个空间圆整时也必须是自身对齐值最大的整数倍,即为4的整数倍)
typedef struct_st_struct2
{
short b; //[][] 2个字节
int c; //[][][][] 4个字节
char a; //[] 1个字节
}st_struct2;
sizeof(st_struct1)=? //存储空间12字节 解:b的对齐值2的整数倍,c的对齐值4的整数倍,a的对齐值1的整数倍故,故占[][][][][][][][][][][][](第一个[][]是由于c存放值必须是4整数倍故空出来的,其次整个空间圆整时也必须是自身对齐值最大的整数倍,即为4的整数倍故a后要多占3个位置)
#结构体数组:
结构体指针:指针和->的调用对比//访问者是变量用.,如果访问者是变量中的指针用->
例如:
st_student student;
st_student *stu_ptr = NULL;
stu_ptr = &student;
strncpy(student.name,"zhangsan",32);
student.gender = female;
student.age = 19;
student.score =95.5;
strncpy(stu_ptr->name,"zhangsan",32);
stu_ptr->gender =female;
stu_ptr->age = 19;
stu_score->score =95.5;
(*stu_ptr).gender =female;
(*stu_ptr).age =19;
(*stu_ptr).score = 95.0;
结构体传参:
目前的C允许把一个结构体赋值给另外一个结构,但不能对数组这么做。
st_student student1;
st_student student2;
student2 = student1;
memcpy(&student2,&student1,sizeof(st_student));
intarr[]
void increase_age(st_student *student)
{
student->age ++;
}
st_student student;
increase_age(&student); //年龄改变+1
st_student increase_age(st_student student)
{
student.age ++;
return student; //有返回值如果是void 则是此student非彼student
}
st_student student;
student = increase_age(student); //年龄也改变+1
函数指针与回调函数:
指针是用来存放地址的,而函数名就是函数入口地址。我们可以定义一个指针来指向一个函数。
valv_total_score //回调函数:函数指针来调用
如果*func没有括号,就是一个函数的声明 *与int 结合表示返回值为一个int *类型