C语言结构体的使用

结构体

定义:是用于存储不同类型或相同类型的元素的集合

  • 与数组的区别
    • 数组是一组相同类型元素的集合
    • 而结构体可以存放相同或不同类型元素的集合

特点:

  • 允许用户根据自己的需求来创建可用的数据类型

  • 用来处理复杂对象的 相当于java里面的类

定义结构体变量

使用struct关键字

先声明结构体类型,再定义结构体变量
1
struct 结构体名称 结构体变量1,结构体变量2...;
声明结构体类型并定义变量
1
2
3
4
struct 结构体名称{
//成员变量列表
//类型名 变量名;
}//结构体变量列表--全局的结构体变量列表;
无类型名直接定义结构体类型变量
1
2
3
4
struct {
//成员变量列表
//类型名 变量名;
}结构体变量列表;

举例

1
struct Teacher Teacher1,Teacher2;
1
2
3
4
struct Teacher{
int num;
char name[10];
}Teacher1,Teacher2;
1
2
3
4
struct{
int age;
char gender;
};

注:

结构体最后的分号一定要写

  • 定义结构体变量后,系统会为其分配内存空间
    • 区分:对于结构体类型,系统不为其分配内存空间,只对其变量分配相应的内存空间

初始化

形式

1
2
3
4
struct 结构体名称 结构体变量={内容};
struct 结构体名称{
//成员
}结构体变量;
直接为结构体变量赋予初值
1
2
3
4
struct Teacher{
int num;
char name[10];
}a={10,"李四"};
为某一个结构体变量成员赋予初值
1
struct Teacher c={.num=20};

其他为未初始化的内容

  • 数值型,系统初始化为0
  • 字符型,系统初始化为\0

注:

为结构体变量赋予初值时,可以不完全初始化

是为结构体变量初始化,不能为结构体类型初始化

调用结构体成员

  • 单个结构体
1
结构体变量名.成员名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <stdio.h>
struct Peo {
char name[20];
char gender[5];
char tele[12];
};
struct Stu {
struct Peo p;
int num;
float f;
};
int main() {
struct Peo p1= {"张三","男","11111111111"};
printf("%s %s %s",p1.name,p1.gender,p1.tele);//张三 男 11111111111

但不能使用结构体变量名称来获取整个结构体中所有成员的值

  • 嵌套结构体

结构体里的成员可以是另一个结构体

1
结构体变量名1.结构体变量名2.成员名

只能一级一级的去找到最低级别的成员

注:

  • 结构体变量中的成员可以进行各类运算
    • 调用结构体时,我们采用“.”这个成员运算符,它的 优先级高于其余的运算符,在计算时,我们首先调用该成员的内容,再进行相关的操作

结构体数组

导入:结构体中可以存放各种类型的元素,当然数组类型的数据也能被存放

应用:对于多个对象的多个数据的运算

声明结构体数组
1
2
3
4
struct peo{
char name[50];
int age;
} person [3];
初始化结构体数组
1
2
3
4
5
struct peo{
{"tom",19};
{"bob",23};
{"linda",18};
} person [3];
结构体数组使用
1
结构体数组.成员
1
2
3
4
int i=0;
for(i=0;i<3,i++){
printf("%s %s",person[i].name,person[i].age);
}

结构体指针

指向结构体变量的指针

调用结构体变量中的成员——我们可以为一个函数传入该结构体变量的地址,表示结构体变量成员的第一项的地址,用结构体指针来接收,对该地址解引用后,访问它的属性值(作用与结构体变量一致),即可获取到该结构体变量中的成员

1
2
3
4
5
6
7
8
9
10
11
12
13
struct Peo {
char name[20];
char gender[5];
char tele[12];
};
struct Stu {
struct Peo p;
int num;
float f;
};
struct Stu s= {{"李四","女",10,"18288947230"},1,99.0f};
//浮点数不能精确保存
struct Stu s= {{"李四","女",10,"18288947230"}};

指针调用

  • 结构体指针
    (*结构体指针变量名).成员名
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    #include <stdio.h>
    struct Peo{
    char name[20];
    char gender[5];
    char tele[12];
    };
    int main(){
    struct Peo p1={"张三","男","11111111111"};
    struct Peo * p = NULL;
    P=&p1;
    printf("%d",(*p).name);//张三
    return 0;
    }

    注:

    不能省略*结构体指针变量名两端的括号,否则优先级将会变成先得到结构体变量的地址再调用属性

    上述结构体指针的调用可简写为

    结构体指针变量名->成员名
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    #include <stdio.h>
    struct Peo {
    char name[20];
    char gender[5];
    char tele[12];
    };
    struct Stu {
    //结构体嵌套已存在的结构体
    struct Peo p;
    int num;
    float f;
    };
    void print(struct Peo* pc) {
    printf("%s %s %s ",pc->name,pc->gender,pc->tele);//结构体指针->成员变量
    }//张三 男 11111111111
    int main() {
    struct Peo p1= {"张三","男","11111111111"};
    print(&p1);
    return 0;
    }

周报8

对话空间小组

​ 工号: 姓名:潘瑞琪 班级:数据2302

本周工作计划:2024年04月14日-2024年04月21日

本周对c语言的指针进行进一步的了解与使用,高数,离散,大物的刷题,javaWeb的初步了解

序号 工作内容 状态 完成度 学习时长/h
1 英语15个单词 已完成 100% 5
2 微信小程序开发课程(swiper-item—数据绑定) 已完成 90% 8
3 c语言的循环嵌套代码练习+结构体的介绍 已完成 80% 8
4 大学物理的简谐振动的刷题+狭义相对论的理解 已完成 100% 4
5 web的css的元素显示模式–css三大特性 已完成 100% 6
6 高等数学刷题巩固(三重积分的应用–坐标的弧长积分) 已完成 100% 8
7 JavaWeb Js介绍—Js对象(JSON) 已完成 100% 10
总时长: 49h
本周任务完成情况 本周工作总结&问题反馈
基本完成学习任务 多抽出时间完成学习任务

周报7

对话空间小组

​ 工号: 姓名:潘瑞琪 班级:数据2302

本周工作计划:2024年04月07日-2024年04月14日

本周对c语言的指针进行进一步的了解与使用,高数,离散,大物的刷题,javaWeb的初步了解

序号 工作内容 状态 完成度 学习时长/h
1 英语25个单词 已完成 100% 5
2 微信小程序开发课程(小程序简介–view的用法) 已完成 100% 8
3 c语言的指针+指针与函数的使用 已完成 100% 10
4 大学物理的旋转矢量–单摆与复摆 已完成 100% 4
5 web的css的背景图+属性学习 已完成 100% 5
6 高等数学刷题巩固(方向导数–二重积分) 已完成 90% 9
7 JavaWeb介绍–HTML实现标题–样式2 已完成 90% 10
总时长: 42h
本周任务完成情况 本周工作总结&问题反馈
基本完成学习任务 多抽出时间完成学习任务

指针

  • 指针

    核心

    本质上指针就是地址

    概念理解:

    • 内存单元的编号就是地址(指针)

    • 口语中的指针,其实是指针变量是用来存放内存地址的变量

    1
    2
    3
    4
    5
    int main(){
    int a=0;
    int* pa =&a;//pa用于存放a的值 类型为int *
    return 0;
    }

    结论

    • 指针变量 里面存放的是地址,通过这个地址,能够找到一个内存单元

    • 在32位的机器上,有32个地址线,能够编译2的32次方的地址

      • 指针在32位机器上是4个字节
    • 在64位的机器上,有64个地址线,能够编译2的64次方的地址

      • 在64位机器上指针为8个字节

    指针类型

    • 导入
    1
    2
    3
    4
    int a=10;
    int *pc=&a;
    char *pi=&a;
    double *pl=&a;

    在内存中我们知道

    • 指针变量所占的字节大小取决于该机器所配备的位数

    那么思考:

    为什么我们需要为指针设置那么多的类型?而不直接创建一个总的指针来定义?

    实际意义
    1
    2
    3
    4
    int a=0x11223344;//16进制的数字
    int* pc=&a;//指针变量存放地址
    *pc=0;//地址所找到的那个值进行修改为0
    //最终四个字节的位置都被改变为了0
    1
    2
    3
    4
    int a=0x11223344;
    char* pc=(char *)&a;//强制类型转化为字符指针变量
    *pc=0;
    //最终只有一个字节的位置被修改为了0

    如果int*的指针,指针访问4个字节

    如果char*的指针,指针访问1个字节

    结论1

    • 指针类型决定了指针在被解引用时访问几个字节

    • 但是不决定指针变量所占的字节大小

    1
    2
    3
    4
    5
    6
    7
    int a=0x11223344;
    int *pc =&a;
    char* pq =(char*)&a;
    printf("%p",pc);//地址--首元素的地址
    printf("%p",pc+1);//跳过了四个字节的指针步长
    printf("%p",pq);//地址--首元素的地址
    printf("%p",pq+1);//跳过了一个字节的指针步长

    结论2

    • 指针的类型决定了指针+1或 -1操作时,跳过几个字节

    • 决定了指针的步长

    理解

    指针变量的大小与机器位数相关,指针变量指向的那个空间即为内存所决定的大小由它的类型所决定
    指针变量是存储地址的 而它的访问权限取决于该数据变量的类型
    类型有多大 可访问该数据变量的字节也会随之增大


    野指针

    不赋初值
      • 错误演示
    1
    2
    int* p1;//未为指针变量赋初值
    *p1=10;//非法访问指针变量存放的地址对应的值

    ​ 因为p1为指针变量 在内存中有很多块空间 如果不赋初值 会导致指针指向发生错误

    ​ 当不知道给指针赋什么值时 我们采用空指针赋值给指针变量

    1
    2
    3
    4
    int * p=NULL;//赋予空指针
    if(p!=NULL){
    *p=20;
    }//需要判断此指针不为空指针

    这里需要用判断语句 判断该指针是否为空指针 如果不为空指针 才能对指针里的变量进行修改

    指针指向的空间释放
      • 错误演示
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    //局部变量的生命周期
    //在所限定的代码块区内部 出了代码块区 则这个局部变量会被销毁
    int *test(){
    int a=10;//a为局部变量
    //在test函数可以使用,但是a出了该函数会被销毁
    return &a;
    }
    int main(){
    int *p=test();
    //指针变量能够找到该变量地址
    //但是不能访问
    return 0;
    }
    指针下标越界
      • 错误演示
    1
    2
    3
    4
    5
    6
    7
    int arr[10]={0};
    int i=0;
    int *p=&arr;//首元素地址
    for(i=0;i<=10;i++){
    *p=i;
    *p++;//此时会发生指针下标越界,访问不到下标为10的值
    }
    结论

    为防止野指针的出现,我们采用以下几点:

    • 对与指针变量赋初值

      • 当然,可以采取赋空指针的方法–防止指针指向错误
    • 注意下标越界问题,思考该数组的元素个数

    • 调用函数使用指针时,避免返回局部变量的地址

周报5

对话空间小组

​ 工号: 姓名:潘瑞琪 班级:数据2302

本周工作计划:2024年03月31日-2024年04月07日

本周学习离散数学的一阶逻辑等值演算与推理,c语言循环代码练习,大学物理刚体转动,高等数学梯度的理解,web的css初始标签选择器认知

序号 工作内容 状态 完成度 学习时长/h
1 英语25个单词 已完成 100% 5
2 离散数学的集合的运算–序偶与集合的笛卡尔积 已完成 90% 8
3 c语言的数组复习几种数组排序方式+函数综合练 已完成 100% 10
4 大学物理的狭义相对论+电场强度–电势能 已完成 100% 15
5 web的css几种标签选择器–css进阶(背景色) 已完成 100% 9
6 高等数学的二重积分–三重积分+刷题巩固 已完成 80% 12
7 mysql的安装–DDL的数值类型了解 已完成 90% 10
总时长: 69h
本周任务完成情况 本周工作总结&问题反馈
基本完成学习任务 多抽出时间完成学习任务

周报4

对话空间小组

​ 工号: 姓名:潘瑞琪 班级:数据2302

本周工作计划:2024年3月25日-2024年3月31日

本周学习离散数学的一阶逻辑等值演算与推理,c语言循环代码练习,大学物理刚体转动,高等数学梯度的理解,web的css初始标签选择器认知

序号 工作内容 状态 完成度 学习时长/h
1 英语15个单词 已完成 100% 4
2 离散数学的谓词逻辑的推理刷题–特殊集合的刷课 已完成 100% 6
3 c语言的数组练习+循环代码练习 已完成 100% 10
4 大学物理的刚体定轴转动复习+刷题 已完成 100% 7
5 web的css的文本字体样式+html的表单刷课 已完成 100% 9
6 高等数学的多元函数的极值–极坐标的介绍 已完成 80% 10
7 java的新特性–内部类 已完成 95% 5
总时长: 51h
本周任务完成情况 本周工作总结&问题反馈
基本完成学习任务 多抽出时间完成学习任务

周报3

对话空间小组

​ 工号: 姓名:潘瑞琪 班级:数据2302

本周工作计划:2024年3月18日-2024年3月24日

本周学习离散数学的一阶逻辑等值演算与推理,c语言循环代码练习,大学物理刚体转动,高等数学梯度的理解,web的css初始标签选择器认知

序号 工作内容 状态 完成度 学习时长/h
1 英语15个单词 已完成 100% 5
2 离散数学的一阶逻辑等值演算与推理 已完成 90% 7
3 c语言的几种类型的循环代码练习 已完成 100% 8
4 大学物理的刚体定轴转动–角动量守恒定律 已完成 100% 10
5 web的css初始标签选择器与笔记写作 已完成 100% 5
6 高等数学空间曲线切平面–梯度 已完成 100% 9
7 java的图书管理系统–新特性 已完成 85% 10
总时长: 54h
本周任务完成情况 本周工作总结&问题反馈
基本完成学习任务 多抽出时间完成学习任务

面向对象基础

面向对象基础

类与对象

  • 在java中,必须先设计类,才能获得对象
1
2
3
4
public class Phone{
成员变量
成员属性//行为
}
  • 成员变量 成员方法
1
2
3
4
color ="蓝色";//成员变量
public void move(){//成员方法
System.out.println("流动方式");
}

调用成员变量需要实例化对象

1
2
3
phone p =new phone()
p.color;
p.move();

注:一个文件中可以创建多个类,但只有一个类能有public所修饰


封装

对象代表什么,就得封装对应的数据,并提供数据对应的行为

  • private关键字

    • 是一个权限修饰符

    • 可以修饰成员(成员变量与成员方法)

注:被private修饰的成员只能在本类中才能访问

1
2
3
4
5
6
public class GirlFriend
{
private String name;
private int age;
...属性
}
1
2
GirlFriend p=new GirlFriend();
p.age;//被private修饰,外部访问不到,而赋值错误的会报错

针对于每一个私有化的变量,都需要提供getset方法

  • set方法
    • 给成员变量赋值
  • get方法
    • 对外提供成员变量的值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class  GirlFriend{
private int age;
public void setAge(int a){
if(a>18 && a<40){
age=a;
System.out.println(a);
}else{
System.out.println("非法");
}
}
}//set方法
public void getAge(){
return age;
}//get方法

局部变量与成员变量

  • 当局部变量名与成员变量名相同时,采用就近原则
1
2
3
4
5
6
7
public class  GirlFriend{
private int age;
public void method(){
int age=10;
System.out.println(age);
System.out.println(this.age);
}

猜一猜该输出的结果为分别为什么呢?

下面我们来揭晓答案

1
2
System.out.println(age);//10
System.out.println(this.age);//本类的成员变量0

在类中,方法体外的为成员变量

在类中,方法体内的为局部变量

当成员变量与局部变量名字相同时在调用该方法中的成员变量时,局部变量的优先级高于成员变量,采用就近原则输出结果


this关键字

就近原则

​ 若全局变量与局部变量命名相同时,输出时,以最近的那个变量为依据输出即可。

区别 说明
System.out.println(age); 以局部变量优先
System.out.println(this.age); 在本类中寻找此变量输出
  • advantage:

    ​ 区别成员变量和成员变量


构造方法

1.构造方法

  • 特点:

    • 构造方法无返回值,也不能为void
    • 构造方法的名称要与本类名称完全相同
    • 构造方法的作用是用来给成员变量初始化的
    • 构造方法中不能使用return

2.构造方法格式

  • 无参构造方法
1
2
3
修饰符 class 类名(){
//方法体
}
  • 有参构造方法
1
2
3
修饰符 class 类名(){
//this([参数])
}

例如:

![](C:\Users\35176\Desktop\屏幕截图 2024-03-18 214733.png)

:ear::ear::ear:

注:

1.无类的参数时,java虚拟机会自动帮我们创建一个无参构造方法

2.若类中出现有参的构造方法了,系统不会再帮我们创建无参构造方法了

3.使用过程中,一般我们既要写无参的构造方法也要写有参的构造方法


static关键字

1.条件:区分类与对象的

2.使用:

    • static修饰的成员为类成员,静态成员(被所有的对象共享)
  • 格式

    1
    static 类型 变量名;
  • 调用方法

  • 类名.静态变量;
    
    1
    2
    3
    4
    5
    6
    7



    * * 未被static修饰的成员为对象,非静态成员

    * 格式

    类型 变量名; 修饰符 返回值类型 方法名 { //方法体 }
    1
    2
    3
    4
    5
    6

    * 调用方法:

    * ```
    类名 对象名 = new 类名();//实例化
    对象名.成员名;

注:是否+static关键字取决于该变量是否具有唯一性

  • 具有唯一性 不加该关键字

  • 不具有唯一性 可以加入该关键字

周报

对话空间小组

工号: 姓名:潘瑞琪 班级:数据2302

本周工作计划:2024年2月13日-2024年2月18日

本周学习高数一元向量值函数及其导数–方向导数 英语听力+阅读理解 java的Day15作业回顾– 图书管理系统02

本周工作周报

序号 工作内容 状态 完成度 学习时长/h

1 英语听力+英语阅读理解+积累作文+单词 已完成 90% 10

2 高等数学 一元向量值函数及其导数–方向导数 已完成 50% 5

3 java的Day15作业回顾– 图书管理系统02 已完成 80% 3

5 综合性刷题 +复习 已完成 100% 10

总时长:28h

本周任务完成情况 本周工作总结&问题反馈

​ 基本完成学习任务 多抽出时间完成学习任务

本周工作计划:2024年2月19日-2024年2月25日

本周学习高数偏导数–隐函数求导 英语听力和阅读理解练习 java的HashSet–作业回顾 刷题

本周工作周报

序号 工作内容 状态 完成度 学习时长/h

1 英语听力+英语阅读理解+积累作文+单词 已完成 100% 10

2 高等数学的偏导数–隐函数求导 已完成 100% 6

3 java的Day15作业回顾– 图书管理系统02 已完成 80% 9

5 综合性刷题 +复习 已完成 100% 10

总时长:35h

本周任务完成情况 本周工作总结&问题反馈

​ 基本完成学习任务 多抽出时间完成学习任务

本周工作计划:2024年2月26日-2024年3月2日

本周学习c语言程序设计的初始基础巩固,大学物理质点运动学的公式理解和应用,高等数学的一阶线性方程组与高阶线性方程组的刷题,英语背单词

本周工作周报

序号 工作内容 状态 完成度 学习时长/h

1 英语15个单词 已完成 100% 6

2 刷高等数学的微分方程的题目 已完成 100% 7

3 离散数学命题–主合取范式的刷课 已完成 80% 10

5 c语言的基本数据类型–输入与输出的知识巩固 已完成 100% 10

6 java的图书管理系统03–file类02 已完成 80% 9

总时长:42h

本周任务完成情况 本周工作总结&问题反馈

​ 基本完成学习任务 多抽出时间完成学习任务

本周工作计划:2024年2月3日-2024年3月10日

本周完成c语言第三章代码运行,离散数学主析取范式–命题逻辑推理的几种方式 的刷课,高等数学微分方程巩固刷题,英语背单词,大学物理牛顿定律的刷题

本周工作周报

序号 工作内容 状态 完成度 学习时长/h

1 英语15个单词(每日) 已完成 100% 6

2 高等数学微分方程巩固刷题 已完成 100% 5

3 离散数学主析取范式–命题逻辑推理 已完成 80% 15

5 c语言的代码运行与预习 已完成 100% 7

6 大学物理的牛顿定律刷题 已完成 90% 9

7 web基础知识文档书写 已完成 100% 2

8 java的递归算法–字符流的使用 已完成 80% 10

总时长:54h

本周任务完成情况 本周工作总结&问题反馈

​ 基本完成学习任务 多抽出时间完成学习任务

本周工作计划:2024年3月11日-2024年3月17日

本周完成c语言四章代码作业,离散数学求解主析取范式的刷题和谓词逻辑中量词的符号化,高等数学多元函数的极限–一元向量值函数,英语背单词,大学物理动量定理–刚体运动的刷课

本周工作周报

序号 工作内容 状态 完成度 学习时长/h

1 英语15个单词(每日) 已完成 100% 5

2 高等数学多元函数的极限–一元向量值函数 已完成 100% 8

3 离散数学主析取范式解题–谓词逻辑 已完成 80% 8

5 c语言的第四章代码运行与作业 已完成 100% 10

6 大学物理的动量定理–刚体运动的刷课 已完成 100% 12

7 web的html初阶认识学习 已完成 100% 4

8 java的拓展工具–图书管理系统模块04 已完成 75% 8

总时长:55h

本周任务完成情况 本周工作总结&问题反馈

​ 基本完成学习任务 多抽出时间完成学习任务