基本数据类型: int double float char
构造类型: 数组/ 结构体
人:
姓名: // char *
年龄: // int
身高: // double
狗:
姓名 :
年龄 :
身长 :
体重 :
几只眼睛 :
几条腿 :
数组: 是用于保存一组相同类型的数据
结构体: 是用于保存一组不同类型的数据
要想保存人得数据, 就必须先定义变量
数据类型 变量名称;
如何定义一个结构体变量
1.定义结构体类型
2.根据结构体类型, 定义结构体变量
定义结构体类型的格式:
struct 结构体类型名称
{
属性;
};
struct Person {
char *name;
int age;
double height;
};
struct Person p ;
p.name = "suluoluo";
p.age = 27;
p.height = 178;
printf("这个帅哥 = %s age = %i", p.name, p.age);
结构体初始化
int nums[3] = {1,3,5};//定义同时初始化
int nums2[3];//先定义在逐个初始化
nums2[0] = 2;
nums2[1] = 3;
nums2[2] = 6;
int nums3[3];//先定义再一次性初始化(错误 数组不可以先定义 再一次性初始化,)
// nums3 = {4,5,6};
struct Dog
{
char *name;
int age;
double height;
};
struct Dog redDog = {"red", 12, 0.5};//1.定义的同时初始化
struct Dog whiteDod;//2.0先定义再逐个初始化
whiteDod.name = "wDog";
whiteDod.age = 10;
whiteDod.height = 0.8;
struct Dog blackDog;
// 特别注意: 结构体和数组有一点区别, 数组不能先定义再进行一次性的初始化, 而结构体可以
// 只不过需要明确的告诉系统{}中是一个结构体
blackDog =(struct Dog) {"blackDog", 8, 0.7};
//4.指定将数据赋值给指定的属性
struct Dog sd3 = {.height = 1.77, .name = "ww", .age = 33};
结构体的内存存储细节
// 1.定义结构体类型并不会分配存储空间
struct Person{
int age; // 4
int height; // 4
int width; // 4
};
// 2.只有定义结构体变量才会真正的分配存储空间
struct Person sp = {30, 1, 1};
// 结构体第0个属性的地址就是结构体的地址
printf("&sp = %p\n", &sp);
printf("age = %p\n", &sp.age);
printf("size = %lu\n", sizeof(sp));
int nums[3] = {1, 3, 5};
//nums == &nums == &nums[0];
//和数组一样, 结构体内存寻址从大到小, 存储数组是从小到大(先存储第0个属性, 再一次存储其它属性)
printf("height = %p\n", &sp.height);
printf("width = %p\n", &sp.width);
/*
结构体如何开辟存储空间
看上去, 结构体分配存储空间是将所有属性占用的存储空间的总和加在一起后再分配
注意:
其实结构体分配存储空间本质上并不是将所有属性占用的存储空间的总和加在一起后再分配
而是会获取结构体类型中占用内存最大的属性的大小, 然后取该大小的倍数
特例:
如果剩余的存储空间"不够"存储将要存储的数据, 那么就会重新开辟8个字节的存储空间, 并且将需要存储的数据放到新开辟的存储空间中
如果剩余的存储空间"够"存储将要存储的数据, 那么就不会开辟了
*/
struct Person2{
//double height; // 8
int age; // 4
//int heigth; // 4
double height; // 8
char c; // 1
//char *name; // 8
};
struct Person2 sp2;
printf("size = %lu\n", sizeof(sp2));
结构体类型的定义
// 1.先定义结构体类型, 在定义结构体变量
struct Person
{
int age;
char *name;
double height;
};
struct Person sp;
// 2.定义结构体类型的同时定义结构体变量
struct Person2
{
int age;
char *name;
double height;
} sp1;
// 数据类型 变量名称
sp.age = 30;
printf("age = %i\n", sp1.age);
struct Person sp2;
sp2.name = "lnj";
printf("name = %s\n", sp2.name);
// 3.定义结构体类型的同时定义结构体变量, 并且省略结构体名称
// 如果在定义结构体类型的同时定义结构体变量, 那么可以省略结构体类型名称
// 弊端: 由于结构体类型没有名称, 所以以后就不能使用该结构体类型
// 优点: 如果结构体类型只需要使用一次, 那么可以使用该方式
struct
{
int age;
char *name;
double height;
} sp3;
sp3.age = 55;
printf("age = %i\n", sp3.age);
结构体的作用域
如果将变量写到函数或者代码块外面, 那么就不是局部变量, 而是全局变量
全局变量的作用域是从定义的那一行开始, 直到文件末尾 (暂时这样理解)
int num;
如果将结构体类型写在函数或者代码块外面, 那么结构体类型的作用域和全局变量一样, 从定义的那一行开始一直直到文件末尾
相同作用域不能有同名的结构体类型
在不同的作用域中可以定义同名的结构体类型 , 如果使用同名的结构体类型定义结构体变量, 采用就近原则
指向结构体的指针
如何定义指向结构体变量的指针
1.拷贝结构体类型 和 结构体变量名称
2.在类型和名称中间加上一颗心
当指针指向结构体之后如何利用指针访问结构体
结构体变量名称.属性;
(*结构体指针变量名称).属性;
结构体指针变量名称->属性;
struct Person
{
int age;
char *name;
double height;
};
struct Person sp = {13, "lmj", 1.80};
sp.name = "shuaige";
sp.age = 13;
sp.height = 1.80;
struct Person *personP;
personP = &sp;
(*personP).name = "luogw";
(*personP).age = 40;
(*personP).height = 1.90;
printf("age = %i, name = %s, height = %lf\n", (*personP).age, (*personP).name, (*personP).height);
personP->name = "sugege";
personP->age = 19;
personP->height = 1.90;
printf("age = %i, name = %s, height = %lf\n", personP->age, personP->name, personP->height);
/*如何定义指向结构体变量的指针
1.拷贝结构体类型 和 结构体变量名称
2.在类型和名称中间加上一颗心
当指针指向结构体之后如何利用指针访问结构体
结构体变量名称.属性;
(*结构体指针变量名称).属性;
结构体指针变量名称->属性;
*/
结构体数组
// 要求定义变量保存公司中所有部门的绩效
struct Bumen{
char *name;
int count;
double kpi;
};
struct Bumen ios = {"iOS", 20, 100.0};
struct Bumen andorid = {"Andoird", 10, 99.0};
struct Bumen php = {"php", 500, 88.0};
// 元素类型 数组名称[元素个数];
struct Bumen bumens[3] =
{
{"iOS", 20, 100.0}, // 0
{"Andoird", 10, 99.0},
{"php", 500, 88.0}
};
bumens[0].name = "iOSv587";
bumens[0].count = 99;
bumens[0].kpi = 100.0;
printf("name = %s, count = %i, kpi = %lf\n", bumens[0].name, bumens[0].count, bumens[0].kpi);
结构体和函数
// 1.将结构体的属性传递给函数, 在函数中修改形参不会影响到实参
// 2.将结构体名称作为参数传递, 在函数中修改形参不会影响到实参
// 结构体之间赋值是值传递, 系统会将A结构体的值 拷贝一份到 B结构体中
printf("age = %i\n", sp.age);
change1(sp);
printf("age = %i\n", sp.age);
struct Person sp1 = {30, "lnj"};
struct Person sp2 = sp1;
// 3.结构体之间赋值是值传递, 相当于拷贝
printf("sp1.age = %i\n", sp1.age);
sp2.age = 998;
printf("sp1.age = %i\n", sp1.age);
printf("sp2.age = %i\n", sp2.age);
struct Person sp4 = {30, "lnj"};
printf("sp1.age = %i\n", sp4.age);
change(&sp4);
printf("sp1.age = %i\n", sp4.age);
}
return 0;
}
void change(struct Person *p)
{
p->age = 998;
}
void change1(struct Person value)
{
value.name = "luoge";
value.age = 100;
}
网友评论