目录
一、结构体变量的定义与使用
1.先声明结构体类型再定义变量名
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
struct student {
char name[21];
int age;
char address[51];
};
void main()
{
struct student stu;
//stu.name = "张三";//错误,stu.name是数组名,是个常量
strcpy(stu.name, "张三");
stu.age = 18;
strcpy(stu.address, "北京市朝阳区");
printf("name:%s\n", stu.name);
printf("age:%d\n", stu.age);
printf("address:%s\n", stu.address);
struct student stu1 = { "李四",18,"北京市海淀区" };
printf("name:%s\n", stu1.name);
printf("age:%d\n", stu1.age);
printf("address:%s\n", stu1.address);
}
2.在声明类型的同时定义变量
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
struct student {
char name[21];
int age;
char address[51];
} stu;
void main()
{
//stu.name = "张三";//错误,stu.name是数组名,是个常量
strcpy(stu.name, "张三");
stu.age = 18;
strcpy(stu.address, "北京市朝阳区");
printf("name:%s\n", stu.name);
printf("age:%d\n", stu.age);
printf("address:%s\n", stu.address);
}
3.直接定义结构体类型变量(无类型名)
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
struct {
char name[21];
int age;
char address[51];
}stu;
void main()
{
//stu.name = "张三";//错误,stu.name是数组名,是个常量
strcpy(stu.name, "张三");
stu.age = 18;
strcpy(stu.address, "北京市朝阳区");
printf("name:%s\n", stu.name);
printf("age:%d\n", stu.age);
printf("address:%s\n", stu.address);
}
二、结构体偏移对齐
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
struct student {
char name[21];
int age;
char address[51];
};
void main()
{
struct student stu[3] = {
{"张三",20,"北京昌平"},
{"李四",22,"北京朝阳"},
{"王五",19,"北京海淀"}
};
printf("结构体数组字节大小%d\n", sizeof(stu));//240
printf("结构体字节大小%d\n", sizeof(stu[0]));//80
printf("结构体字节大小%d\n", sizeof(struct student));//80
printf("结构体元素个数%d\n", sizeof(stu) / sizeof(struct student));//3
}
student 结构体字节大小并不是21+4+51=76,而是21+2+4+51+2=80。
结构体中元素是按照定义顺序一个一个放到内存中去的,但并不是紧密排列的。从结构体存储的首地址开始,每个元素放置到内存中时,它都会认为内存是按照自己的大小来划分的,因此元素放置的位置一定会在自己宽度的整数倍上开始。
结构体总大小为最大类型所占字节数的整数倍。
name[21]占21个字节;下一个位置为22
age为int类型,占4字节,但是第22位不是4的整数倍,第24位才是,所以偏移2位后存age;下一个位置为28
address[51],类型为char,char占1个字节,第28位是char的整数倍,一共占51个字节;此时总大小为78,但78不是最大类型int 所占字节数4的整数倍,所以student 结构体字节大小为80.
【举个例子】下方student结构体字节大小为76,不需要进行偏移。
struct student {
char name[21];
char address[51];
int age;
};
三、结构体指针
1.普通成员
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct student {
char name[21];
int age;
char address[51];
};
void main()
{
struct student stu1 = { "张三",20,"北京昌平" };
struct student stu2 = stu1;
strcpy(stu2.name, "李四");
printf("%s\n", stu1.name);//张三
}
2.指针成员
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct student {
char* name;
int age;
char* address;
};
void main()
{
struct student stu1 = { "张三",20,"北京昌平" };
struct student stu2;
//strcpy(stu2.name, "小三");//报错,使用了未初始化的局部变量stu2
stu2.name = "李四";//正确
stu2.name = (char*)malloc(sizeof(char) * 21);
strcpy(stu2.name, "李四");//正确
stu2.age = 30;
stu2.address = "北京海淀";//正确
stu2.address = (char*)malloc(sizeof(char) * 51);
strcpy(stu2.address, "北京海淀");//正确
printf("%s\n", stu2.address);//张三
}
3.结构体指针
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct student {
char* name;
int age;
char* address;
};
struct student stu = { "张三",20,"北京昌平" };
struct student* p = &stu;
void main()
{
struct student* stu = (struct student*)malloc(sizeof(struct student) * 3);
for (size_t i = 0; i < 3; i++)
{
stu[i].name = (char*)malloc(sizeof(char) * 21);
stu[i].address = (char*)malloc(sizeof(char) * 51);
scanf("%s%d%s", stu[i].name, &stu[i].age, stu[i].address);
}
for (size_t i = 0; i < 3; i++)
{
printf("%s ", stu[i].name);
printf("%d ", stu[i].age);
printf("%s\n", stu[i].address);
}
}
void main()
{
struct student stu1 = { "张三",20,"北京昌平" };
struct student* stu2 = &stu1;
stu2->name= "李四";
printf("%s\n", stu1.name);//李四
}
四、结构体作为函数参数
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct student {
char* name;
int age;
char* address;
};
void GetStudent(struct student stu)
{
stu.name = "Lisa";
stu.age = 29;
stu.address = "another nation";
printf("%s's age is %d,she is from %s\n", stu.name, stu.age, stu.address);//Lisa's age is 29,she is from another nation
}
void main()
{
struct student stu = {"Lin",22,"China"};
printf("%s's age is %d,she is from %s\n", stu.name, stu.age, stu.address);//Lin's age is 22,she is from China
GetStudent(stu);
printf("%s's age is %d,she is from %s\n", stu.name, stu.age, stu.address);//Lin's age is 22,she is from China
}
#define _CRT_SECURE_NO_WARNINGS
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
struct student {
char* name;
int age;
char* address;
};
void GetStudent(struct student* stu)
{
//(*stu).name = "Lisa";
stu->name = "Lisa";
stu->age = 29;
stu->address = "another nation";
printf("%s's age is %d,she is from %s\n", stu->name, stu->age, stu->address);//Lisa's age is 29,she is from another nation
}
void main()
{
struct student stu = {"Lin",22,"China"};
printf("%s's age is %d,she is from %s\n", stu.name, stu.age, stu.address);//Lin's age is 22,she is from China
GetStudent(&stu);
printf("%s's age is %d,she is from %s\n", stu.name, stu.age, stu.address);//Lisa's age is 29,she is from another nation
}