结构体、联合体、枚举
1、结构体
声明
struct Teacher
{
int age;
char isCool;
};
声明+定义变量
struct Teacher
{
int age;
char isCool;
}teacher;
使用
使用结构体定义变量时,前面的struct可写可不写
struct Teacher
{
int age;
char isCool;
}teacher;
int _tmain(int argc, _TCHAR* argv[])
{
struct Teacher t1;
Teacher t2;
t1.age = 11;
t2.age = 22;
// 接收用户的输入
getchar();
return 0;
}
定义+赋初值
struct Teacher
{
int age;
char isCool;
}teacher;
int _tmain(int argc, _TCHAR* argv[])
{
Teacher t1 = {11, 1};
// 接收用户的输入
getchar();
return 0;
}
声明+定义变量
struct Teacher
{
int age;
char isCool;
}teacher;
int _tmain(int argc, _TCHAR* argv[])
{
teacher.age = 10;
printf("%d\n", teacher.age);
// 接收用户的输入
getchar();
return 0;
}
结构体数组
结构体指针
访问结构体成员时用->,而不是.
// 32bit,4字节对齐
struct Teacher
{
int age; // 4
char isCool; // 1
};
void print1(Teacher t)
{
printf("%d\n", t.age);
}
void print2(Teacher *t)
{
printf("%d\n", t->age);
}
int _tmain(int argc, _TCHAR* argv[])
{
struct Teacher teacher;
teacher.age = 10;
teacher.isCool = 1;
// 为什么差8个字节,因为结构体长度是8
// printf("%X, %X\n", &teacher, &teacher + 1);
// printf("%d\n", *(char *)(&teacher + 4));
printf("%d\n", *(char *)((char *)&teacher + 4));
print1(teacher);
print2(&teacher);
// 接收用户的输入
getchar();
return 0;
}
结构体嵌套结构体
结构体做函数参数
值传递、引用传递
struct Teacher
{
int age;
char isCool;
}teacher;
void print_1(Teacher t)
{
printf("%d\n", t.age);
}
void print_2(Teacher *t)
{
printf("%d\n", t->age);
}
void print_3(Teacher &t)
{
printf("%d\n", t.age);
}
int _tmain(int argc, _TCHAR* argv[])
{
Teacher t1 = {11, 1};
print_1(t1);
print_2(&t1);
print_3(t1);
// 接收用户的输入
getchar();
return 0;
}
加const修饰(重要!!读源码经常看到这个语法)
目的是为了防止外部拿到结构体变量的引用修改结构体成员的值
struct Teacher
{
int age;
char isCool;
}teacher;
void print(Teacher *t)
{
t->age = 20;
printf("%d\n", t->age);
}
void print_1(const Teacher *t)
{
t->age = 20;
printf("%d\n", t->age);
}
int _tmain(int argc, _TCHAR* argv[])
{
Teacher t1 = {11, 1};
print(&t1);
printf("%d\n", t1.age);
// 接收用户的输入
getchar();
return 0;
}
2、联合体(union)
允许在相同的内存位置存储不同的数据类型
但是任何时候只能有一个成员带有值
联合体的大小由字节数最多的成员决定
3、枚举(enum)
跟Java中的差不多
引用
可理解为:给变量起别名
其本质其实就是指针常量:int * const a = &b;
语法:
int a = 10; int &b = a;
注意:
1、引用必须初始化
2、引用初始化后无法修改
引用做函数参数
struct Teacher
{
int age;
char isCool;
}teacher;
void print(Teacher &t)
{
t.age = 30;
printf("%d\n", t.age);
}
int _tmain(int argc, _TCHAR* argv[])
{
Teacher t1 = {11, 1};
print(t1);
printf("%d\n", t1.age);
// 接收用户的输入
getchar();
return 0;
}
引用做函数返回值
注意:不能返回局部变量的引用,因为局部变量在函数调用完以后就释放掉了。那持有的引用有点野指针的味道
int & add()
{
int a = 10;
return a;
}
int _tmain(int argc, _TCHAR* argv[])
{
int &a = add();
printf("%d\n", a);
printf("%d\n", a);
printf("%d\n", a);
// 接收用户的输入
getchar();
return 0;
}
如果函数的返回值是引用,这个函数可以作为左值使用
int & add()
{
static int a = 10;
return a;
}
int _tmain(int argc, _TCHAR* argv[])
{
int &a = add();
printf("%d\n", a);
printf("%d\n", a);
add() = 100;
printf("%d\n", a);
// 接收用户的输入
getchar();
return 0;
}
struct Teacher
{
int age;
char isCool;
};
Teacher& print1(Teacher &teacher)
{
teacher.age = 100;
return teacher;
}
int _tmain(int argc, _TCHAR* argv[])
{
Teacher teacher;
teacher.age = 10;
teacher.isCool = 1;
Teacher t = print1(teacher);
// 看两个问题
// 1、在print1改了age,外面发生了改动吗
printf("%d, %d\n", teacher.age, t.age);
//2、print1返回的是传入的对象吗
printf("%X, %X\n", &teacher, &t);
// 接收用户的输入
getchar();
return 0;
}
常量引用
const int &a = b;
练习
1、自实现字符串处理库
2、实现数据结构栈
3、实现数据结构队列