要熟练掌握结构体的使用方法,以前学的数组和字符串,只能定义相同类型的一组数或者是字符。假如编程时候需求不同类型的数据的时候,就可以用到结构体了。好比要定义一个人的年龄,性别,生日等。
在说结构体之前,先跟我一同复习下变量的类型。
一:根据变量的作用域,可以分为:
1.局部变量:
①定义:在函数(代码块)内部定义的变量(包括函数的形参)
② 作用域:从定义变量的那一行开始,一直到代码块结束
③ 生命周期:从定义变量的那一行开始分配存储空间,代码块结束后,就会被回收
④ 没有固定的初始值
2.全局变量
① 定义:在函数外面定义的变量
② 作用域:从定义变量的那一行开始,一直到文件结尾(能被后面的所有函数共享)
③生命周期:程序一启动就会分配存储空间,程序退出时才会被销毁
④默认的初始值就是0
例如:
// 全局变量:a、b、c
// 局部变量:v1、v2、e、f
#include
// 变量a的初值是10
int a = 10;
// 变量b的初值是0
// 变量c的初值是20
int b , c = 20;
int sum(int v1, int v2)
{
return v1 + v2;
}
void test()
{
b++;
int i = 0;
i++;
printf("b=%d, i=%d\n", b, i);
}
int main()
{
test();
int e = 10;
{
{
int f = 30;
}
}
return 0;
}
二:结构体:可以由多个不同类型的数据构成。
例如: 要定义学生的年龄,身高,姓名等属性。
#include
int main()
{
// 1.定义结构体类型
struct Person
{ // 里面的3个变量,可以称为是结构体的成员或者属性
int age; // 年龄
double height; // 身高
char *name; // 姓名
};
// 2.根据结构体类型,定义结构体变量
struct Person p = {20, 1.55, "jack"};
p.age = 30;
p.name = "rose";
printf("age=%d, name=%s, height=%f\n", p.age, p.name, p.height);
/* 错误写法
struct Person p2;
p2 = {30, 1.67, "jake"};
*/
struct Person p2 = {.height = 1.78, .name="jim", .age=30};
p2.age = 25;
return 0;
}
结构体的内存分析:
1.定义结构体类型(并不会分配存储空间)
struct Date
{
int year;
int month;
int day;
};
2.定义结构体变量(真正分配存储空间)
struct Date d1 = {2011, 4, 10};
printf("%d - %d - %d\n", d1.year, d1.month, d1.day);
3.补齐算法:
//补齐算法(对齐算法)
// 结构体所占用的存储空间 必须是 最大成员字节数的倍数
struct Student
{
int age;// 4个字节
char a;
}stu; // 所以stu结构体变量占用8个字节
定义结构体的方法和使用注意:
1.定义结构体变量的3种方式
① 先定义类型,再定义变量(分开定义)
struct Student
{
int age;
};
struct Student stu;
② 定义类型的同时定义变量
struct Student
{
int age;
} stu;
struct Student stu2;
③ 定义类型的同时定义变量(省略了类型名称)
struct
{
int age;
} stu;
2.结构体类型的作用域
①定义在函数外面:全局有效(从定义类型的那行开始,一直到文件结尾)
②定义在函数(代码块)内部:局部有效(从定义类型的那行开始,一直到代码块结束)
结构体与数组:
struct RankRecord
{
int no; // 序号 4
int score; // 积分 4
char *name; // 名称 8
};
struct RankRecord r1 = {1, "jack", 5000};
struct RankRecord r2 = {2, "jim", 500};
struct RankRecord r3 = {3, "jake",300};
指向结构体的指针:
1.指向结构体的指针的定义
struct Student *p;
2.利用指针访问结构体的成员
① (*p).成员名称
② p->成员名称
#include
int main()
{
struct Student
{
int no;
int age;
};
// 结构体变量
struct Student stu = {1, 20};
// 指针变量p将来指向struct Student类型的数据
struct Student *p;
// 指针变量p指向了stu变量
p = &stu;
p->age = 30;
// 第1种方式
printf("age=%d, no=%d\n", (*p).age, (*p).no);
// 第2种方式
printf("age=%d, no=%d\n", p->age, p->no);
return 0;
}
结构体和函数: 如果结构体作为函数参数,只是将实参结构体所有成员的值对应地赋值给了形参结构体的所有成员;修改函数内部结构体的成员不会影响外面的实参结构体。
#include
struct Student
{
int age;
int no;
};
void test(struct Student s)
{
s.age = 30;
s.no = 2;
}
void test1(struct Student *p)
{
struct Student stu2 = {15, 2};
p = &stu2; //此时指针变量p指向了stu2这个结构体
p->age = 16; // 所以修改的值是stu2
p->no = 3;
}
int main()
{
struct Student stu = {28, 1};
test1(&stu); // 把stu的地址传给指针变量p
printf("age=%d, no%d\n", stu.age, stu.no);
return 0;
}