对结构体、共用体的认识。
结构体是一种自定义的复合数据类型。
类比数组,数组也算一种复合数据类型,数组是由多个由相同数据类型的元素组成,(比如需要记录描述100个人的年龄,此时只需int arr[100]即可,不需一个一个的声明);结构体可由多中数据类型的元素组成(将不同的数据类型组合成为一个整体),比如描述一个学生信息,学生的学号使用long int类型存储、年龄用int类型存储、姓名用字符串(字符数组)存储。如果是一个学生,可以只需声明3个变量即可(long int id;int age;char* name[8]),要是100个学生,如此一个学生就得对应声明3个变量明显是不可行的;可以设想一下,能不能有一种数据类型是专门用来存储学生信息的?能,结构体就可以派上用场,结构体是一种自定义的数据类型,我们可以自己定义一种叫Student的数据类型,这种类型可以同时存放一个long int数据、int数据、字符串。如此,就可以声明Struct Student stu[100];来存放100个学生的数据了。
二、结构体的定义
结构体关键字:struct
定义student这种结构体(注意分号不能少),有三个成员变量id,age,name。
20:18:00
struct student
{
long int id;
int age;
char name[8];
};
20:18:28
三、声明结构体变量
3.1普通方式
struct student stu1; //定义了一个student类型的变量stu1
3.2 在定义的时候声明
struct student
{
long int id;
int age;
char name[8];
}stu1; //在结构体定义时,同时声明一个这种结构体变量stu1
四、结构体的初始化
4.1先声明结构体变量,后初始化。
struct student stu1;
stu1.id = 12345; //通过成员运算符'.'来访问结构体的成员变量
stu1.age = 20;
strcpy(stu1.age,"Liang"); //因为数组在非初始化时,不能直接通过数组名直接赋值,strcpy函数需要包含头文件string.h 错误的写法:stu1.name = "Liang";
4.2在声明结构体变量时同时初始化,类似于数组初始化。
#include <stdio.h>
#include <string.h>
struct student
{
long int id;
int age;
char name[8];
};
int main(int argc,char* argv[])
{
struct student stu1 = {12345,22,"Liang"};
printf("id=%ld age=%d name=%s \n",stu1.id,stu1.age,stu1.name);
return 0;
}
五、结构体成员变量的访问
1、可使用成员运算符'.'来访问结构体成员变量。例如stu1.age = 10;int age = stu1.id;
2、可以使用结构体指针结合"->"来访问及饿哦固体成员变量。例如struct student *sp = &stu1;sp->id = 12345;
也可以 (*sp).age = 20;注意成员运算符'.'的优先级高于指针操作符'*'。
六、结合使用typedef
使用typedef为自定义结构体定义别名,在声明变量时可以省略struct关键字。
七、结构体的大小
字节对齐以提高CPU效率。
比如我的机器是32位,CPU一次最大访问数据位数是32位(也就是4字节,那么默认4字节对齐)。
struct ss
{
char c;
int a;
}s1={'a',0x12345678};
int main(int argc,char* argv[])
{
printf("%d \n",sizeof(s1));
return 0;
}
结构体会有内存对齐现象,所以所有结构体成员的大小之和并不一定是结构体的大小,结构体变量占据的内存单元的个数应当大于等于其内部所有数据成员占据内存单元数的和。
一般来说,不同的编译器字节对齐机制有所不同。字节对齐的细节和具体编译器实现相关,但一般而言,满足三个准则:
1) 结构体变量的首地址能够被其最宽基本类型成员的大小所整除;
2) 结构体每个成员相对于结构体首地址的偏移量都是成员大小的整数倍,如有需要编译器会在成员之间加上填充字节;
3) 结构体的总大小为结构体最宽基本类型成员大小的整数倍,如有需要编译器会在最末一个成员之后加上填充字节。
最宽基本类型的概念,所谓基本类型是指像char、short、int、float、double这样的内置数据类型。“数据宽度”就是指其sizeof的大小。诸如结构体、共用体和数组等都不是基本数据类型。
作业:
#include <stdio.h>
int main()
{
int a,b,d,e,f,g,h;
char c;
scanf("%d %c %d",&a,&c,&b);
switch(c){
case'+':d=a+b;printf("%d",d);break;
case'-':e=a-b;printf("%d",e);break;
case'*':f=a*b;printf("%d",f);break;
case'/':b!=0;g=a/b;printf("%d",g);break;
case'%':b!=0;h=a%b;printf("%d",h);break;
default:printf("ERROR");
}
return 0;
}