结构体是⼀些值的集合,这些值称为成员变量。结构的每个成员可以是不同类型的变量。
结构体框架如下
struct
{
};
struct Stu
//Stu为定义的该结构体的名称
{
char name[20];
int age;
float score;
//{}内 为该结构体的成员
};
//注意末尾的分号
struct Point
{
int x;
int y;
};
struct Stu
{
char name[20];
int age;
float score;
}A;
//此时A为全局变量
int main()
{
struct Stu B;
//此时B为局部变量
struct Stu A = { "wangwu",20,63.4 };
//可以按照顺序给结构体变量进行赋值
//当然也可以不按照顺序 如下】
struct Stu B = { .age = 30,.name = "lisi",.score = 66.7 };
return 0;
}
结构体变量.成员变量名
结构体指针—>成员变量名
.
struct Stu
{
char name[20];
int age;
float score;
}A;
int main()
{
struct Stu A = { "zhangsan",20,67.32 };
printf("%f %d %s", A.score, A.age, A.name);
return 0;
}
->
#include
struct Stu
{
char name[20];
int age;
float score;
}A;
void print_stu(struct Stu s)
{
printf("%s %d %f\n", s.name, s.age,s.score);
}
set_stu(struct Stu* ps)
{
ps->age = 88;
strcpy(ps->name , "guoleile666");
ps->score = 98.5;
}
int main()
{
struct Stu A = { "zhangsan",20,30.5 };
print_stu(A);
set_stu(&A);
print_stu(A);
return 0;
}
声明定义好结构体后 就需要求他的大小 这里就用到内存对齐的知识
struct s1
{
char s1;
char s2;
int a;
};
struct s2
{
char s1;
int a;
char s2;
};
//s1和s2只是顺序不一样
int main()
{
struct s1 s3 = { "sss","lll",666 };
struct s2 s4 = { "sss",666,"lll" };
printf("%zd\n", sizeof(s3));
printf("%zd\n", sizeof(s4));
return 0;
}
struct S1
{
char c1; 1 8 1
//第一个1是char类型所占字节 8为默认对齐数 第二个1为 最终取得的对齐数
int i; 4 8 4
char c2; 1 8 1
};
int main()
{
printf("%d\n", sizeof(struct S1));
//结果为12
return 0;
}
struct S2
{
char c1;
char c2;
int i;
};
int main()
{
printf("%d\n", sizeof(struct S2));
//结果为8
return 0;
}
struct S3
{
double d;
char c;
int i;
};
int main()
{
printf("%d\n", sizeof(struct S3));
//结果为16
return 0;
}
struct S3
{
double d;
char c;
int i;
};
struct S4
{
char c1; 1 8 1
struct S3 s3; 16
double d; 8 8 8
};
int main()
{
printf("%d\n", sizeof(struct S4));
//结果为32 根据第四条规则 取S3中最大的8 从8的倍数的位置开始对齐
//s3的大小是16 对齐16位
return 0;
}
#pragma pack(1)//修改默认为1
#pragma pack() /括号里什么都不写 取消设置的默认对齐数
struct A
{
int a : 2;
int b : 5;
int c : 10;
int d : 30;
};
struct B
{
int a ;
int b ;
int c ;
int d ;
};
int main()
{
printf("%zd", sizeof(struct A));
printf("%zd", sizeof(struct B));
//A结果为8
//B结果为16
}
不能对位段的成员使用&操作符 也不能使用scanf
因为可能两个成员共用一个地址哦
和结构体一样,联合体也是由一个或多个成员构成
但是联合体多个成员共用一个地址
联合体给一个成员赋值,其他成员的值也跟着变化
struct s
{
char a;
int b;
};
union a
{
char a;
int b;
};
int main()
{
printf("%zd\n", sizeof(struct s)); //8
printf("%zd\n", sizeof(union a)); //4
}
联合体的大小
1.联合的大小至少是最⼤成员的大小。
2.当最大成员大小不是最大对齐数的时候,就要对齐到最大对齐数的整数倍
例如
union a
{
char a[5]; //按照成员大小 1 8 1
int b; // 4 8 4
//这里5 不满足于4的倍数 所以5--> 8 来满足需要
};
int main()
{
printf("%zd\n", sizeof(union a));
//结果为8
}
union s
{
int i;
char c;
};
int main()
{
union s U;
//创建一个union s 类型的变量U
//s是这个联合体的名字
U.i = 1;
if (U.c == 1)
printf("小端");
else
printf("大端");
return 0;
}
int judge_sys()
{
union
{
char a;
int i;
}U;
U.i = 1;
return U.a;
}
int main()
{
int ret = judge_sys;
if (ret == 1)
printf("小端");
else
printf("大端");
return 0;
}
enum Day
{
//列出的是枚举的可能取值
//这些列出的可能取值被称为:枚举常量
Mon,//默认为0
Tues,//1
Wed,//2
Thur,//3
Fri,//4
Sat,//5
Sun//6
};
int main()
{
printf("%d %d %d %d %d %d %d", Mon, Tues, Wed, Thur, Fri, Sat, Sun);
//当要修改默认值时 Mon=5; 这样时不可以的 因为Mon时常量 默认为1
//需要修改时 可以在枚举定义里修改
// emun Day
//{
// Mon =1;
// 这样后面也会改变 变成 2 3 4 5 6 7
// 也可以改成不同的顺序 例如
// Mon=2;
// Tues=1;这样也是可以的
// 也可以赋值为相同的值 但一般不这样做
//}
return 0;
}
int main()
{
enum Day Friastday = Mon;
return 0;
}
#define _CRT_SECURE_NO_WARNINGS 1
#include
void menu()
{
printf("********************\n");
printf("*** 0.play ****\n");
printf("***1.add 2.sub ****\n");
printf("***3.mul 4.div ****\n");
printf("********************\n");
}
enum
{
play,
add,
sub,
mul,
div
};
int main()
{
int input = 0;
scanf("%d", &input);
while (input)
{
switch (input)
{
case add:
//因为枚举已经声明add为1 sub为2 mul为3 div为4
//所以这里用add代替原先的 case 1: case 2: ......
//相较于原先 提升可读性 一进入switch循环 case 就可以清楚的知道进行哪一步
break;
case sub:
break;
case mul:
break;
case div:
break;
}
}
return 0;
}
而如果 #define add 1;
光标再放到add上时 就不会出现上述现象
这里枚举一下子定义四个 而define需要一个一个定义