上一节讲了内存动态分配的知识,这节应该要讲字符串但是对于字符串的操作太多太多,而且在网上也有相应的API,这里就直接贴出
下面我们来学一下结构体、联合体、枚举的知识
结构体
结构体是什么呢?它类似于我们的java 类,可以在里面定义多个不同的数据上类型然后整合起来的一个数据类型。
struct Man{
//成员
char name[20];
int age;
//int(*func)();
}
就像上面一样就定义了一个简单的结构体,然后我们对它进行初始化
struct Man m1 = {"aaa", 2};
另外一种
struct Man m1;
m1.age = 23;
//m1.name = "Raa";//这样方式是不允许的
strcpy(m1.name,"rose");
这里需要记住当结构体里面有字符数组的时候并且没有直接进行初始化的时候一定要使用字符串copy的方法进行赋值
这样就从简单的结构体创建到生成对象就完成了,那对于结构体还有其他的类型吗?这里列举几种
-
结构体变量名
struct Man{ char name[20]; int age; } m1, m2 = {"hello",20}; //m1结构体变量名
-
匿名结构体
struct{ char name[20]; int age; }m1;
这种就直接生成了结构体m1的对象,之后便不能创建新的对象了,类似的单例模式,当然结构体里面也可以嵌套结构体来使用
struct Teacher{
char name[20];
};
struct Student {
char name[20];
int age;
struct Teacher t;
};
当然我们也可以这么来书写
struct Student
{
char name[20];
int age;
struct Teacher
{
char name[20];
};
};
结构体里面不仅可以放结构体还可以放函数的指针只需要在里面写入int (*p)();就可以接受返回值为int,无参数的函数了,是不是特别的简单呢?
struct People{
char* name;
int age;
int(*func)();
};
typedef struct People* _People;
int run(){
printf("run...");
return 1;
}
void main(){
struct People people = {"Ly",12};
_People p = &people;
p->func = run;
printf("People name is %s\n", p->name);
p->func();
getchar();
}
结构的嵌套就算弄完了,接下来来了解一下结构体的大小,对于结构体的大小遵循字节对齐原则,大小为最宽基本数据类型的整数倍
struct Man{
int age;
double weight;
};
上面的结构体大小为16字节,因为最大字节double是8字节,因为除了double还有其他的成员所以还会在开辟8个字节,用来存储4个字节的int数据。
接下来我们与之前动态内存分配联系写了小Demo
struct Man{
char *name;
int age;
};
//结构体与动态内存分配
void main(){
struct Man *p = (struct Man*)malloc(sizeof(struct Man) * 10);
struct Man *pp = p;
//赋值
pp->name = "Hello";
pp->age = 22;
pp++;
pp->name = "World";
pp->age = 23;
struct Man *p_loop = p;
//遍历
for (; p_loop < p + 2; p_loop++){
printf("name=%s\nage=%d\n", p_loop->name, p_loop->age);
}
getchar();
}
代码很简单这里就不多说,接着往下看,在我们创建一个结构体对象的时候需要struct Man man;这样的代码,书写起来比较繁琐,好在C语言提供了类型别名
类型别名代表在干着不同的事情
不用的情况下,来使用不同的别名
-
书写简洁
下面来给出相应的例子typedef struct People{ char name[20]; int age; }P,*WP;
这样的代码得到P是People的别名,WP是People的指针别名,这样的方式和下面是等价的
typedef struct People W;
typedef struct People *WP;
联合体
union MyUnion{
int x;
int y;
double z;
};
联合体也叫做共用体,不同类型的变量共同占用一段内存,之间相互覆盖,任何情况下只有一个变量存在,这样更节省内存,大小=最大的数据类型大小。当你为联合体对象赋值时,后赋值的会覆盖前赋值,当同类型的时候前赋值会等于后赋值的值,如
void main(){
printf("size:%d\n", sizeof(union MyUnion));
union MyUnion un;
un.x = 90;
un.y = 100;
printf("%d,%d", un.x, un.y);//结果:100,100
getchar();
}
枚举
enum Day{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
};
枚举保证列举了所有的情况,具有限定值的作用保证取值的安全性。