前言:
本篇文章是一次大胆的尝试,我想试着改变我那枯燥不堪的文笔,试着能不能幽默风趣地讲解知识点。如果效果好的话,我会进一步尝试!希望大家喜欢!
学习结构体之前,我们先来讲讲 非常 🐂🍺 的 typedef 函数!
一、typedef 函数
0x00 函数介绍
简单来说,typedef 可以将一个数据类型重命名,使用方法如下:
❓ 额……那它有什么用呢?我们来看下面的例子:
吐槽:unsigned char 真是又臭又长,用得让我很不爽!我真是受够了!使用 typedef ,你就可以给 unsigned char 取新的名字,不要998,只要学会它!就能给这个数据类型取名!你还在等什么?赶快来学吧!
💬 举个例子:将 unsigned char 重命名为 u_char
typedef unsigned char u_char;
👆 👆 👆
关键字 数据类型 新名字
这样一来,我们就可以用 u_char 来取代又臭又长的 unsigned char 了!
unsigned char c;
u_char c;
值得注意的是!typedef 的影响是有范围限制的,只能在它所处的大括号内使用,也就是出了作用域就会嗝屁。如果你想全局使用,可以在 #include 头文件包含下面就定义 typedef,这样它就有了 主角光环 !就不会这么轻易的狗带了!如下所示:
#include <stdio.h>
#include <stdlib.h>
typedef char* String; //我是带有主角光环的typedef ✨
int my_strlen(String str) {
int i, cnt = 0;
for(i = 0; str[i] != '\0'; i++) {
cnt++;
}
return cnt;
}
int main(void) {
String s = (String)malloc(sizeof(char) * 10); //还能进行强制类型转换
printf("Enter String: ");
scanf("%[^\n]", s);
free(s); // s: 我免费了!
return 0;
}
这么一来,typedef 就可以全局使用了。你学费了吗?亲手敲一敲试试看!
二、初识结构体
0x00 结构体是个什么玩意
结构体是一些值的集合,这些值称为成员变量。结构的每个成员以是不同类型的变量。
如果说数组是同一类型的变量集合,那么结构体就是各种各样变量的集合。因为结构体支持所有C数据类型,所以结构体内部也可以有数组存在。
💬 举个栗子,如果要保存学生的信息(学号,姓名,年级),想将信息捆绑在一起,作为一个变量来管理会十分便利。像这样把多个数据类型捆绑在一起的,就叫做结构体。
0x01 声明结构体
💬 上述举的例子(保存学生信息):
struct {
int id;
char name[26];
double gradePoints;
} student;
但是,对于有多个学生的情况,需要多个这样的变量。考虑到每次都是用 struct {} 语法来产生变量的方法未免过于繁琐,C语言允许将结构体当作一个数据类型来方便我们更好地使用。如下所示,
ps:tag 表示 结构体标签
struct tag {
type1 fieldName1;
...
typeN fieldNameN;
};
struct tag variable_identifier1;
struct tag variable_identifier2;
struct student{
int id;
char name[26];
float grade;
};
struct student xiaoming;
struct student xiaohong;
综上所述得出总结:结构体是用户自定义的类型 (user-defined type) 。
0x02 结构体初始化
下面将演示结构体变量声明后初始化的过程:
💬 声明变量时允许指定初始值:
为了接近结构体的变量,我们可以使用 "点操作符(·)" 来获取它。值得一提的是,字符串复制时要使用 strcpy。
0x01 结构体与 typedef
📚 当然,typedef 还可以作用于结构体。这样可以让结构体用起来更爽,而不用拖着 struct name 又臭又长的玩意来定义变量,使用方法如下:
💬 之前举的学生结构体的例子,我们现在可以升级一下了:
💩 使用 typedef 前
struct student {
int id;
char name[26];
float grade;
};
struct student xiaohong;
⚡ 使用 typedef 后:
typedef struct {
int id;
char name[26];
float grade;
} stu;
stu Park;
简直是爽炸了有木有!不爽不要玩!
0x02 定义结构体的方法
① 匿名定义
简直是莽夫行为,莽就完事了!直接拿来就用,名字都懒得取了!
struct {
...
} var;
😂 开玩笑开玩笑,这其实是传说中的 "匿名结构体"
📚 匿名结构体:在声明结构的时候,可以不完全声明。匿名结构体在声明时省略掉结构体标签(tag),因为没有结构体标签导致无法构成类型,所以匿名结构体自然只能用一次。
💬 匿名结构体使用方法演示:
struct {
int a;
char b;
float c;
double d;
} s;
struct {
int a;
char b;
float c;
double d;
} *ps;
② tag 定义(结构体标签)
非常常见的定义结构的方式
struct tag {
...
} var;
struct tag var;
③ typedef 定义
非常爽的定义方式,定义完之后用起来更加得心应手!
typedef struct {
...
} test;
test var;
当然,如果你怕你忘了 test 是个啥,你也可以加上 tag ,tag 多长都没事,反正你用 typedef 了。
typedef struct This_is_a_test {
...
} test;
test var;
0x03 结构体访问
📚 结构体变量间也可以使用赋值操作符的。但是!只有是同一结构体类型时才能使用。
通俗点说,想要结构体变量间赋值,它们得是同一个妈生的才行。
💬 例子:
#include <stdio.h>
int main(void) {
typedef struct {
int year;
int month;
int day;
} birthday;
birthday A = {2000, 4, 12};
birthday B = {2002, 7, 9};
printf("A的生日: %d年%d月%d日\n", A.year, A.month, A.day);
printf("B的生日: %d年%d月%d日\n", B.year, B.month, B.day);
// 赋值
A = B;
printf("A <- B 复制后:\n");
printf("A的生日: %d年%d月%d日\n", A.year, A.month, A.day);
printf("B的生日: %d年%d月%d日\n", B.year, B.month, B.day);
return 0;
}
🚩 运行结果:
好了!我们点到为止,这一篇只是开个头,下一篇我将会继续讲解结构体!