一、结构体类型的基本使用
1.1结构体类型的基本使用
1.1.1为什么要用结构体
C语言内置的数据类型,除了几种原始的基本数据类型,只有数组属于复合类型,可以同时包含多个值,但是只能包含相同类型的数据,实际使用场景受限。
场景:用指针和结构体结合起来构造节点(如链表节点、二叉树结点等)
1.1.2、结构体概述
C语言没有其它语言的对象(object)和类(class)的概念,struct结构很大程度上提供了对象和类的功能。
struct Person{
char name[20];
int age;
char gender[10];
double weight;
}
//结构体:通讯录
struct Contacts{
char name[20];
int year;
int month;
int day;
char emali[50];
char phoneNumber[20];
}
结构体是一种构造类型的数据结构,
是一种或多种基本类型或构造类型的数据的集合
1.2结构体变量的定义和初始化
语法格式:
方法一:先声明结构体类型,再定义变量名
(1)第一步
struct 结构体名{
成员列表}
(2)第二步
struct 结构体名 变量名
方法二:定义结构体类型的同时,定义变量
struct 结构体名{
成员列表}变量名;
方法三:定义结构体类型的同时,定义变量
struct{
成员列表}变量名1,变量名2;
//也可以用typedef创建新类型 后续会用到
typedef struct{
int a;char b;
double c;
} Simple2;
1.3、调用结构体成员(添加)
结构体变量名.成员名=常量或变量值
第一步:创建或声明结构体
第二步:声明结构体变量
第三步:调用结构体变量成员
方法一:
#include <stdio.h>
#include <string.h>
//1、先定义结构体类型
struct Student {
int num;
int age;
char name[50];
char* addr;
};
int main(){
//2.再定义结构体变量
struct Student stu1;
//3.调用结构体成员
stu1.num=1001;
stu1.age=18;
//stu1.name="Jack";//对于数组,不能重新赋值
strcpy(stu1.name,"Jack");
stu1.addr="郑州市高新区";
printf("%d %d %s %s \n",stu.num,stu.age,stu.name,stu.addr);
//1001 18 Jack 郑州市高新区
// ----- 直接赋值的方法
struct Student stu2 = { 1002,20,"Tom","北京" };//定义的同时即赋值
printf("%d %d %s %s \n", stu2.num, stu2.age, stu2.name, stu2.addr);
return 0;
}
注意:struct Student stu1;
1、struct定义结构类型的关键字
2、Student标志符,是结构体的类型名
3、stu1结构体变量
方法二:
#include <stdio.h>
#include <string.h>
//1、先定义结构体类型
struct Student {
int num;
int age;
char name[50];
char* addr;
}stu1,stu2;
int main(){
//调用结构体成员
stu1.num=1001;
stu1.age=18;
//stu1.name="Jack";//对于数组,不能重新赋值
strcpy(stu1.name,"Jack");
stu1.addr="郑州市高新区";
printf("%d %d %s %s \n",stu.num,stu.age,stu.name,stu.addr);
/--/1001 18 Jack 郑州市高新区
struct Student stu2 = { 1002,20,"Tom","北京" };
printf("%d %d %s %s \n", stu2.num, stu2.age, stu2.name, stu2.addr);
return 0;
}
方法三:
#include <stdio.h>
#include <string.h>
//1、先定义结构体类型 这种方式,在main函数中无法再定义其它的 结构体类型的变量
struct{
int num;
int age;
char name[50];
char* addr;
}stu1;
struct{
int num;
int age;
char name[50];
char* addr;
}stu2= { 1002,18,"Andy","北京" }, stu3= { 1003,20,"Tom","北京" };
int main(){
//调用结构体成员
stu1.num=1001;
stu1.age=18;
//stu1.name="Jack";//对于数组,不能重新赋值
strcpy(stu1.name,"Jack");
stu1.addr="郑州市高新区";
printf("%d %d %s %s \n",stu.num,stu.age,stu.name,stu.addr);
//1001 18 Jack 郑州市高新区
printf("%d %d %s %s \n", stu2.num, stu2.age, stu2.name, stu2.addr);
printf("%d %d %s %s \n", stu3.num, stu3.age, stu3.name, stu3.addr);
return 0;
}
方法四:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <string.h>
//1、先定义结构体类型
typedef struct Student {
int num;
int age;
char name[50];
char* addr;
}STU;
int main() {
STU stu1 = { 1001,18,"Andy","北京" };
printf("%d %d %s %s \n", stu1.num, stu1.age, stu1.name, stu1.addr);
return 0;
}
1.4、结构体成员的访问(使用)
结构体成员的使用,分为两种情况:
1、通过结构体变量访问成员 语法:结构体变量名.成员
2、通过结构体指针变量访问 语法:结构体指针变量->成员
#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
//定义一个结构体类型
struct Stu {
char name[50];
int age;
};
int main() {
//定义结构体变量
struct Stu s = { "Jack",18 };
//1、通过结构体变量获取成员
printf("姓名:%s\n", s.name);
printf("年龄:%d\n", s.age);
//2、通过结构体变量指针获取成员
printf("姓名:%s\n", (&s)->name);
printf("年龄:%d\n", (&s)->age);
//修改结构体成员
strcpy(s.name,"admin");
s.age = 30;
printf("修改后的姓名:%s\n", s.name);
printf("修改后的年龄:%d\n", (&s)->age);
return 0;
}
说明:
1.在创建一个结构体变量后,需要给成员赋值。在没有给成员赋值的情况下调用,打印的值是垃圾数据,可能导致程序异常终止。
2.不同结构体变量的成员是独立的,互不影响,一个结构体变量的成员更改,不影响另外一个。
总结:区分三个概念:结构体、结构体变量、结构体变量的成员。
**结构体是自定义的数据类型,表示的是一种数据类型。
**结构体变量代表一个具体变量。
int num1;//int 是数据类型 而num1是一个具体的int变量
struct Car car1;//Car 是结构体数据类型,而car1是一个Car变量
二、进一步认识结构体
2.1 结构体嵌套
结构体的成员也是变量,那么成员可以是基本数据类型,也可以是数组、指针、结构体类型。如果结构体的成员是另一个结构体,这就构成了结构体嵌套。
2.2结构体变量的赋值操作
同类型的结构体变量可以使用赋值运算(=),赋值给另一个变量,比如:
stu1=stu2;//假设 stu1 和stu2已定义为同类型的结构体变量
这时会生成一个全新副本。系统会分配一块新的内存空间,大小与原来的变量相同,把每个属性都复制过去,即原样生成了 一份数据。
也就是说,结构体变量的传递机制是值传递,而非地址传递。 这一点跟数组的赋值不同,使用赋值运算符复制数组,不会复制数据,只是传递地址。
int a1[4]={1,2,3};
int a[3]={10,20,30};
//a3=a1;//报错的
int *b;
b=a;