一、联合
联合是一个能在同一个存储空间里(但不同时)存储不同类型数据的数据库类型
union u_data
{
unsinged char a;
unsigned int b;
} data;
sizeof(data) = ?
data.b = 0x12345678;
data.a = ?
data.a = 0xef;
data.b = ?
二、枚举
可以使用枚举类型声明表示整数常量的符号名称。
enum
{
Gold, Wood, Water, Fire = 8, Earth, };
switch(five_line)
{
case Gold:
do_something;
break;
default:
break;
}
三、结构体
如果我们想保存学生的信息,这些信息包括学生的姓名,年龄,性别,成绩等。在我们已知
的类型中是否有一种数据类型能够描述这所有信息?
结构体可以由基本数据类型构造出一种新的复合数据类型来。
enum { male, female };
struct st_student
{
char name[32];
int gender;
int age;
float score;
} ;
struct st_student student = {"zhangsan", male, 20, 90.0};
struct st_student student = {.name="zhangsan", .gender=male, .age=20, .score=90.0};
student.name=”lisi”; ?
printf("Name:%s Gender:%d Age:%d Score: %f\n", student.name, student.gender, student.age, student.score);
1、Typedef
Typedef 用来定义一种新的数据
typedef unsigned char u8; u8 var1, var2;
typedef unsigned short uint_16; uint_16 var1, var2;
typedef char * pchar; pchar var1, var2;
typedef int * pint; pint var1, var2;
#define PCHAR char * PCHAR var1, var2;
typedef struct _st_student
{
char name[32];
int gender;
int age;
float score;
} st_student ;
st_student student; == struct _st_student student;
2、结构体对齐
typedef struct _st_struct1
{
char a;
short b;
int c;
} st_struct1;
sizeof(st_struct1) = ?
typedef struct _st_struct2
{
short b;
int c;
char a;
} st_struct2;
sizeof(st_struct2) = ?
自身对齐值: 自身对齐值就是结构体变量里每个成员的自身大小;
指定对齐值: 指定对齐值是由宏#pragma pack (N)指定的值,里面的N必须是2的幂次方,
如1,2,4,8,16等。如果没有通过#pragma pack宏那么在32位的Linux主机上默认指定对
齐值为4,64位的Linux主机上默认指定对齐值为8,ARM CPU默认指定对齐值为8;
有效对齐值: 结构体成员自身对齐时有效对齐值为自身对齐值与指定对齐值中较小的一个,
结构体圆整时,为所有成员中自身对齐值最大的与指定对齐值较小的一个;
步骤: 1, 结构体各成员对齐 2,整个结构体圆整
3、结构体数组
如何保存和访问一个班上的学生的信息?
#define MAX_STUDENTS 60
st_student students[MAX_STUDENTS];
students[1]={.name="lisi", .gender=male, .age=21, .score=80.0};
for(i=0; i<MAX_STUDENTS; i++)
{
printf("Name: %s Gender: %s Age:%d Score:%f\n", students[i].name, students[i].gender, students[i].age, students[i].score);
}
4、结构体指针
st_student student;
st_student *ptr = NULL;
ptr = &student;
strncpy(student.name, "zhangsan", 32);
student.gender = female;
student.age = 19;
student.score = 95.0;
strncpy(ptr->name, "zhangsan", 32);
ptr->gender = female;
ptr->age = 19;
ptr->score = 95.0;
(*ptr).gender = female;
(*ptr).age = 19;
(*ptr).score = 95.0;
5、结构体嵌套
typedef struct _st_score
{
float math;
int english;
int chinese;
} st_score;
typedef struct _student
{
char name[32];
int gender;
int age;
st_score score;
st_score *pscore;
} st_student;
st_student student;
st_student *ptr = &student;
student.score.math = 90.0; student.pscore->math = 90.0
ptr->scrore.math = 90.0; ptr->pscore->math = 90.0
6、结构体传参
现在的C允许把一个结构赋值给另外一个结构,但不能对数组这么做。
st_student student1;
st_student student2;
student2 = student1;
memcpy(&student2, &student1, sizeof(st_student));
void increase_age(st_student student)
{
student.age ++;
}
st_student student={.age=10;};
increase_age(student);
st_student increase_age(st_student student)
{
student.age ++;
return student;
}
st_student student={.age=10;};
student = increase_age(student)
四、函数指针与回调函数
指针是用来存放地址的,而函数名就是函数的入口地址。那么我们是否可以定义一个指针来指
向一个函数?
int func1(int arg1, int arg2); void func2(int arg1, int arg2)
int (*func_ptr)(int, int) ; int *func_ptr(int , int);
func_ptr = func1; func_ptr = func2;
func_ptr(1,2) == func1(1,2);
float calc_total_score(struct st_score score)
{
return score.math+score.english+score.chinese;
}
float print_student_score(struct st_score score, float (* func_ptr)(struct st_score))
{
printf("Math:%f English:%f Chinse:%f Total:%f\n", score.math, score.english, score.chinese, func_ptr(score));
}
print_student_score(student.score, calc_total_score);