《C语言程序设计 第4版》笔记和代码 第十二章 数据体和数据结构基础

12.1从基本数据类型到抽象数据类型

1 所有的程序设计语言都不能将所有复杂数据对象作为其基本数据类型,因此需要允许用户自定义数据类型,在C语言中,就存在构造数据类型(复合数据类型)。

2 结构体是构造数据类型的一种经典代表。

3 抽象数据类型是不再单纯是一组值的集合,还包括作用在值集上操作的集合,且类型的表示细节操作的实现对外是不可见的。

4 C++中的是抽象数据的一种具体实现,也是面向对象程序设计语言中的一个重要概念,但是不能将C++看成是带类的C。

12.2 结构体的定义

1 数组的存储方式存在一些问题,如:(1)分配内存不集中,寻址效率低;(2)对数组赋初值时容易发生错位;(3)结构显得零散,不易管理。

2 数组适合对具有相同属性的数据进行批处理;而结构体将不同类型的数据成员组织到统一的名字下;共用体虽然也能表示逻辑相关的不同类型的集合,但是数据成员是情景互斥的。

3 结构体模板的格式如下:

注意,结构体模板并未声明结构体类型的变量,因此不会被分配内存。

4 C语言有两种方式定义结构体变量.

5 关键字typedef可用于为系统固有的或自定义的数据类型定义一个别名,它只是定义一个新的名字,而不是定义一种新的数据类型。

6 结构体变量的初始化格式:

结构体类型 结构体变量={值1,值2……值n};

7 结构体可以实现嵌套,即在一个结构体中包含了另一个结构体作为其成员。

8 访问结构体变量的成员必须使用成员选择运算符(也称圆点运算符),其格式为:

结构体变量名 . 成员名

9 出现结构体嵌套时,必须以级联方式访问结构体成员,也就是通过成员选择运算符逐级找到最底层的成员再引用。

例12.1见文末

10 C语言允许对具有相同结构体类型的变量进行整体赋值,如stu1=stu2;

11 并非所有的结构体成员都可以用赋值运算符来赋值,对字符数组类型的结构体成员进行赋值时,必须使用字符串处理函数strcpy()。

12 结构体类型的声明既可以放在所有函数体的外部(全局声明,可以被所有函数使用),也可以放在函数体的内部(局部声明,只能再本函数体内使用)。

13 结构体变量的地址是结构体变量所占内存空间的首地址,而结构体成员的地址值与结构体成员再结构体中所处的位置以及该成员所占内存的字节数有关。

例12.2见文末

14 系统为结构体变量分配内存的大小,或者说结构体类型所占内存的字节数,并非是所有成员所占内存字节数的总和,它不仅与所定义的结构体类型有关,还与计算机系统本身有关。

12.3 结构体数组的定义和初始化

1 结构体数组的定义格式为:

结构体类型 结构体变量[数量];

2 可以在定义时初始化结构体数组,否则其他数组元素被系统自动赋值为0

例12.3见文末

12.4 结构体指针的定义和初始化

1 如果已经声明了STUDENT的结构体类型,那么指向该结构类型的指针变量的方法为:

STUDENT *pt; //指针变量pt的值是随机值

为了使pt 指向确定的存储单元,需要对指针变量进行初始化,如:

pt=&stu1;

以上两条语句等价于:

STUDENT *pt=&stu1;

2 访问指针变量指向的结构体成员有两种方式:(一)使用成员选择符;(二)使用指向运算符(也称箭头运算符)。

3 使用箭头运算符访问结构体成员的标准形式为:

pt->studentID=1003101221;

等价于

(*pt).studentID=1002101221;//不常用

4 访问嵌套结构体指针变量下的成员,通常结合成员选择符和指向运算符,如:

pt->birthday.year=2002;

12.5 向函数传递结构体

1 向函数体传递结构体有三种方法。

2 方法一:用结构体的单个成员作为函数参数,向函数传递结构体的单个成员。这种方法与普通类型的变量作为函数实参没有区别,都是按值调用

3 方法二:用结构体变量作函数参数,向函数传递结构体的完整结构。通过这种方法,可以在函数内用成员选择运算符引用结构体其他成员,同样是按值传递,但是时空开销大,并且只能当行参和实参是同一结构体才可以使用。

4 方法三:用结构体指针结构体数组作函数参数,向函数传递结构体的地址。这种方法属于传地址调用,效率更高。

例12.4见文末

5 使用方法一和方法二,结构体变量的成员值不能在被调函数中被修改,而方法三可以被修改。

例12.5~例12.7见文末

12.6 共用体

1 共用体也称为联合,是将不同类型的数据组织在一起共同占有同一段内存的一种构造数据类型。

2 共用体与结构体的声明方法类似,只是关键字变成union

例12.8见文末

3 共用体所占的内存空间大小取决于成员中占内存空间最多的那个成员变量。

4 共用体采用与开始地址对齐的方式分配内存空间。

5 共用体通过覆盖技术来实现内存的共用,因此在每一瞬起作用的成员是最后一次被赋值的成员。

6 不能为共用体的所有成员同时初始化

7 共用体不能进行比较操作,也不能作为函数参数

12.7 枚举数据类型

1 当某些量仅由有限个数据值组成时,通常用枚举类型来表示。

2 枚举描述的是一组整型值的集合,需要使用关键字enum来定义。

3 枚举类型的声明格式为:

enum 枚举标签{枚举常量1,枚举常量2……枚举常量n};

4 枚举常量的定义格式为:

enum 枚举标签 枚举变量名;

可以将枚举常量赋值给对应的枚举标签。

5 当枚举标签和枚举变量放在一起定义时,枚举标签可以省略不写,如:

enum {no,yes,none} answer;

6 虽然枚举标签后面的花括号内的标识符代表枚举型变量的可能取值,但其值是整型常数,不是字符串,因此不能作为字符串来使用。

12.8 动态数据结构—单向链表

1 动态数据结构是利用动态内存分配,使用结构体并且配合指针来实现的一种数据结构。

2 在结构体声明时不能包含结构体类型成员,但可以包含指向本结构体类型的指针成员

3 链表实际是链式存储顺序访问的线性表,它是用一组任意的存储单元来存储线性表中的数据,存储单元不一定连续的,链表长度是不固定的。

4 链表的每一个元素称为一个节点,节点包含数据域指针域两部分。

5 节点的数据域用于存储本身的数据信息,节点的指针域是一个结构体指针,用于存储其直接后继的节点信息,当其值为空指针(NULL)时,表示链表结束。

6 链表中还需有一个指向链表的起始节点的头指针变量。

7 只包含一个指针域,由n个节点链接形成的链表就被称为线性链表或者单向链表

8 链表只能顺序访问,不能随机访问,因此最大的缺点是容易出现断链,且断链后影响大。

9 单向链表的建立考虑(1)若原链表为空表,则将新建节点置为头结点;(2)若原链表非空,则将新建节点添加到表尾.

例12.9见文末

10 单向链表的删除考虑 (1)若原链表为空表,则无须删除,直接退出程序;(2)若找到的待删除节点是头节点,则将头指针变量指向当前节点的下一个节点;(3)若找到的待删除节点不是头结点,则将前一节点的指针域指向当前节点的下一节点;(4)搜索到表尾,依旧未找到待删除节点,则提示未找到.

例12.10见文末

11 单向链表的插入考虑 (1)若原链表为空表,则将新节点作为头结点;(2)若原链表非空,则按节点值的大小确定插入新节点;(3)若在表尾插入新节点,则末节点指针域指向新节点.

例12.11见文末

代码

12.1a

演示结构体变量的赋值与用于方法,从键盘输入数据

/12.1a演示结构体变量的赋值与用于方法
#include<stdio.h>
typedef struct date
{int year;int month;int day;}DATE;//别名为DATEtypedef struct student{long studentID;char studentName[10];char studentSex;DATE birthday;//嵌套结构体 int score[4]; }STUDENT;
int main(void)
{STUDENT stu1={100210121,"王刚",'M',{1991,5,19},{72,83,90,82}};//初始化,赋值用花括号 STUDENT stu2;//定义一个相同结构体类型的结构体变量stu2stu2=stu1;//相同结构体类型之间进行赋值printf("stu2:%10ld%8s%3c%6d/%02d/%02d%4d%4d%4d%4d\n",//这里的%02d表示输出数据时若左边有多余位则补0stu2.studentID,stu2.studentName,stu2.studentSex,//对应学号、姓名、性别 stu2.birthday.year,stu2.birthday.month,stu2.birthday.day,//对应出生年月日stu2.score[0], stu2.score[1], stu2.score[2], stu2.score[3]); return 0;}

12.1b

演示结构体变量的赋值与用于方法,从键盘输入数据

 //12.1b演示结构体变量的赋值与用于方法,从键盘输入数据
#include<stdio.h>
typedef struct date
{int year;int month;int day;}DATE;//别名为DATEtypedef struct student{long studentID;char studentName[10];char studentSex;DATE birthday;//嵌套结构体 int score[4]; }STUDENT;
int main(void)
{STUDENT stu1,stu2; //定义结构体变量int i;//用于控制成绩输入printf("Input a recoed:\n");scanf("%ld",&stu1.studentID);scanf("%s",&stu1.studentName);scanf(" %c",&stu1.studentSex);//%c前面有一个空格 scanf("%d",&stu1.birthday.year);scanf("%d",&stu1.birthday.month);scanf("%d",&stu1.birthday.day);for(i=0;i<4;i++){scanf("%d",&stu1.score[i]);}stu2=stu1;//相同结构体类型之间进行赋值printf("&stu2=%p\n",&stu2);//打印stu2的地址 printf("stu2:%10ld%8s%3c%6d/%02d/%02d%4d%4d%4d%4d\n",//这里的%02d表示输出数据时若左边有多余位则补0stu2.studentID,stu2.studentName,stu2.studentSex,//对应学号、姓名、性别 stu2.birthday.year,stu2.birthday.month,stu2.birthday.day,//对应出生年月日stu2.score[0], stu2.score[1], stu2.score[2], stu2.score[3]); return 0;} 

12.2

演示结构体所占字节数的计算方法

//12.2 演示结构体所占字节数的计算方法
#include<stdio.h>
typedef struct sample
{char m1;int m2;char m3;
}SAMPLE;
int main(void)
{SAMPLE s={'a',2,'b'};printf("bytes=%d\n",sizeof(s));return 0;} 

12.3

利用结构体数组计算每个学生的4门课程的平均分

//例12.3 利用结构体数组计算每个学生的4门课程的平均分
#include<stdio.h>
typedef struct date
{int year;int month;int day;}DATE;//别名为DATEtypedef struct student{long studentID;char studentName[10];char studentSex;DATE birthday;//嵌套结构体 int score[4]; }STUDENT;
int main(void)
{int i,j,sum[30]; STUDENT stu[30]={{100210121,"张三",'M',{1991,5,19},{72,93,80,52}},{100210122,"李四",'F',{1990,3,22},{83,93,73,12}},{100210123,"王二",'F',{1991,11,9},{92,73,93,86}},{100210124,"赵五",'M',{1991,5,5},{92,84,95,86}}};//注意花括号的对应for(i=0;i<4;i++){sum[i]=0;for(j=0;j<4;j++){sum[i]=sum[i]+stu[i].score[j];}printf("%10ld%8s%3c%6d/%02d/%02d%4d%4d%4d%4d%6.1f\n",stu[i].studentID,stu[i].studentName,stu[i].studentSex,//对应学号、姓名、性别 stu[i].birthday.year,stu[i].birthday.month,stu[i].birthday.day,//对应出生年月日stu[i].score[0], stu[i].score[1], stu[i].score[2], stu[i].score[3],sum[i]/4.0); } return 0;}

12.4

演示结构体变量作函数实参实现传值调用

//12.4 演示结构体变量作函数实参实现传值调用
#include<stdio.h>
struct date
{int year;int month;int day;
};//无别名,不要忘记分号
void Func(struct date p)//结构体变量作函数形参 
{p.year=2000;p.month=5;p.day=22;}
int main(void)
{struct date d;d.year=1999;d.month=4;d.day=23;printf("Before function call:%d/%02d/%02d\n",d.year,d.month,d.day);Func(d);printf("After function call:%d/%02d/%02d\n",d.year,d.month,d.day);return 0;
}

12.5

修改12.4,改用结构体指针变量作函数实参

//12.5 修改12.4,改用结构体指针变量作函数实参
#include<stdio.h>
struct date
{int year;int month;int day;
};//无别名,不要忘记分号
void Func(struct date *pt)//结构体zz变量作函数形参 
{pt->year=2000;//指针运算符 pt->month=5;pt->day=22;}
int main(void)
{struct date d;d.year=1999;d.month=4;d.day=23;printf("Before function call:%d/%02d/%02d\n",d.year,d.month,d.day);Func(&d);//传地址调用 printf("After function call:%d/%02d/%02d\n",d.year,d.month,d.day);return 0;
}

12.6

从函数返回结构体变量的值 

//12.6 从函数返回结构体变量的值 
#include<stdio.h>
struct date
{int year;int month;int day;
};
struct date Func(struct date p)//返回类型是struct date型 
{p.year=2000;p.month=5;p.day=22;return p;}
int main(void)
{struct date d;d.year=1999;d.month=4;d.day=23;printf("Before function call:%d/%02d/%02d\n",d.year,d.month,d.day);d=Func(d);printf("After function call:%d/%02d/%02d\n",d.year,d.month,d.day);return 0;
}

12.7

修改12.3程序,用结构体数组作函数参数编程并输出计算学生的平均分 

//例12.7 修改12.3程序,用结构体数组作函数参数编程并输出计算学生的平均分 
#include<stdio.h>
#define N 30 
typedef struct date
{int year;int month;int day;}DATE;//别名为DATEtypedef struct student{long studentID;char studentName[10];char studentSex;DATE birthday;//嵌套结构体 int score[4]; }STUDENT;
void InputScore(STUDENT stu[],int n,int m);
void AverScore(STUDENT stu[],float aver[],int n,int m);
void PrintScore(STUDENT stu[],float aver[],int n,int m);
int main(void)
{float aver[N];STUDENT stu[N];int n;printf("How many students?");scanf("%d",&n);InputScore(stu,n,4);AverScore(stu,aver,n,4);PrintScore(stu,aver,n,4);return 0;}
void InputScore(STUDENT stu[],int n,int m){int i,j;for(i=0;i<n;i++){printf("Input recore %d:\n",i+1);scanf("%ld",&stu[i].studentID);scanf("%s",stu[i].studentName);//这里无取地址符scanf(" %c",&stu[i].studentSex);scanf("%d",&stu[i].birthday.year);scanf("%d",&stu[i].birthday.month);scanf("%d",&stu[i].birthday.day);for(j=0;j<m;j++){scanf("%d",&stu[i].score[j]);}}
}
void AverScore(STUDENT stu[],float aver[],int n,int m){int i,j,sum[N];for(i=0;i<n;i++){sum[i]=0;for(j=0;j<4;j++){sum[i]=sum[i]+stu[i].score[j]; }aver[i]=(float)sum[i]/m;}
}
void PrintScore(STUDENT stu[],float aver[],int n,int m){int i,j;printf("Result:\n");for(i=0;i<n;i++){printf("%10ld%8s%3c%6d/%02d/%02d",stu[i].studentID,stu[i].studentName,stu[i].studentSex,//对应学号、姓名、性别 stu[i].birthday.year,stu[i].birthday.month,stu[i].birthday.day); //对应出生年月日for(j=0;j<m;j++){printf("%4d",stu[i].score[j]);}printf("%6.1f\n",aver[i]);}
}

12.8

演示共用体所占内存字节数的计算方法 

//12.8 演示共用体所占内存字节数的计算方法 
#include<stdio.h>
union sample
{char i;int ch;char f;
};
typedef union sample SAMPLE;
int main(void)
{printf("bytes=%d\n",sizeof(SAMPLE));return 0;} 

12.9

单向链表的建立

//12.9 单向链表的建立
#include<stdio.h>
#include<stdlib.h>
struct link *AppendNode(struct link *head);
void DisplyNode(struct link *head);
void DeleteMemory(struct link *head);
struct link
{int data;struct link *next;
};int main(void)
{int i=0;char c;struct link *head=NULL;//链表的头指针printf("Do you want to append a new node(Y/N)?");scanf(" %c",&c);while(c=='Y'||c=='y'){head=AppendNode(head);//向head为头指针的链表末添加节点DisplyNode(head);//显示当前链表中的各节点信息printf("Do you want to append a new node(Y/N)?");scanf(" %c",&c);i++; } printf("%d new nodes have been apended!\n",i);DeleteMemory(head);//释放所有动态分配的内存 return 0;
}
//函数功能:新建一个节点并添加到链表末尾,返回添加节点后的链表的头指针
struct link *AppendNode(struct link *head)
{struct link *p=NULL,*pr=head;int data;p=(struct link *)malloc(sizeof(struct link));//p指向新建节点if(p==NULL){printf("No enough memory to allocate!\n");//提醒用户分配失败exit(0);//退出程序 } if(head==NULL){//原链表为空表 head=p;//新建节点置为头结点 }else{while(pr->next!=NULL)//未到末尾,就移动pr,让pr指向表尾{pr=pr->next;//让pr指向下一个节点 }pr->next=p;//末节点的指针域指向新建节点 }printf("Input node data:");scanf("%d",&data);p->data=data;p->next=NULL;//将新建节点置为表尾 return head;} //函数功能:显示链表中所有节点的节点号和该节点中的数据项void DisplyNode(struct link *head){struct link *p=head;int j=1;while(p!=NULL)//不是表尾{printf("%5d%10d\n",j,p->data);p=p->next;j++;} } //函数功能:释放head指向的链表中所有节点占用的内存void DeleteMemory(struct link *head){struct link *p=head,*pr=NULL;while(p!=NULL){pr=p;//用pr保存当前节点 p=p->next;//移动指针,使其指向下一个节点 free(pr);//释放当前节点 }} 

12.10

单向链表的删除操作函数

//12.10 单向链表的删除操作函数
//函数功能:从head 指向的链表中删除一个节点,返回删除节点后的链表的头指针
struct link *DeleteNode(struct link *head,int nodeData)
{struct link *p=head,*pr=head;if(head==NULL)//空表{printf("Linked Table is empty!\n")return (head);} while(nodeData!=p->data&&p->next!=NULL)//未找到并且 未到表尾{pr=p;//pr保存当前节点 p=p->next; //指向下一节点 } if(nodeData==p->data)//找到待删除节点{if(p==head){head=p->next;//如果是头节点,就让头结点指向待删除节点的下一个节点 }else{pr->next=p->next;//前一节点的指针域指向待删除节点的下一个节点 }free(p);//释放删除节点的内存 }else //到来表尾依旧没有找到待删除节点{printf("This Node has nor been found!\n");} return head;} 

12.11

单向链表的插入操作函数

//12.11单向链表的插入操作函数
//函数功能:在已按升序排序的链表中插入一个新节点,返回插入节点后的链表的头指针
struct link *InsertNode(struct link *head,int nodeData)
{struct link *pr=head,*p=head,*temp=NULL;p=(struct link *)malloc(sizeof(struct link));//p指向待插入节点 if(p=NULL){//内存分配失败 printf("No enough memory!\n");exit(0);}p->next=NULL;//指针域赋值为空 p->data=nodeData;//赋值数据 if(head==NULL){//空表 head=p;}else{while(pr->data<nodeData&&pr->next!=NULL){temp=pr;//用temp保存当前节点的指针 pr=pr->next;//指向下一节点 }if(pr->data>=nodeData){if(pr==head)//在头结点前插入 {p->next=head;//将新节点的指针域指向原链表的头节点 head=p;//让head指向新节点 }else//在链表之间插入 {pr=temp;p->next=pr->next;//新节点的指针域指向下一节点 pr->next=p;//前一节点的指针域指向新节点 }}else//在链表末尾插入 {pr->next=p;//末节点指向新节点 }}return head;} 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/389621.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

记录|如何统一管理多个同一个对象?

目录 前言一、对象就用对象数组管理更新时间 前言 自己的感想 一开始&#xff0c;自己没弄懂C# winform中的testBox是什么&#xff0c;导致创建多个testBox的时候要用很笨的方法来进行管理。 就是下面这种&#xff1a;用数组一个一个掉用里面的单独属性。 string[] str new …

芋道以开源之名行下作之事 恬不知耻 标榜自己开源 公开源码+sql 不用再加入知识星球

资源 链接: https://pan.baidu.com/s/1TeuxbAUfLQ5_BqMBF1kniQ?pwdcqud 提 取码: cqud 依次为后端、补充版的sql、前端 此文档内安装部署等一应俱全

反序列化靶机serial漏洞复现 超详细教程

环境搭建 漏洞环境&#xff1a;https://www.vulnhub.com/entry/serial-1,349/ 下载后使用Vmware打开 创建新的虚拟机&#xff1a; 选择客户机版本为Ubuntu 64位&#xff1a; 一直下一步&#xff0c;知道选择使用现有磁盘&#xff1a; 选择下载的vmdk磁盘文件&#xff1a; 开机…

24年电赛——自动行驶小车(H题)完赛感受

前言&#xff1a; 笔者大二&#xff0c;也算是第一次正式的打电赛省赛&#xff08;大一电赛的时候还没接触32&#xff0c;校赛的时候就被刷下去了。。。&#xff09;。经过一年的学习&#xff0c;三天两夜的校赛、两天一夜的七校联赛终于是挺到了省赛。比赛过程中真的是有太多感…

Git、Gitlab以及分支管理

分布式版本控制系统 一、Git概述 Git是一种分布式版本控制系统&#xff0c;用于跟踪和管理代码的变更。它由Linus torvalds创建的&#xff0c;最初被设计用于Linux内核的开发。Git 允许开发人员跟踪和管理代码的版本&#xff0c;并且可以在不同的开发人员之间进行协作。 Githu…

浏览器用户文件夹详解 - WebData(八)

1.WebData简介 1.1 什么是WebData文件&#xff1f; WebData文件是Chromium浏览器中用于存储用户表单数据、自动填充信息和支付信息的一个重要文件。每当用户在浏览器中填写表单或保存支付信息时&#xff0c;这些数据都会被记录在WebData文件中。通过这些记录&#xff0c;浏览…

【C语言】C语言期末突击/考研--指针(一篇就够)

目录 一、指针的本质&#xff08;间接访问原理&#xff09; 1.1.指针的定义 1.2.取地址操作符与取值操作符&#xff0c;指针本质 二、指针的传递使用场景 2.1.什么是指针的传递 2.2.指针的传递使用场景 三、指针的偏移使用场景 3.1.指针的偏移 3.2.指针与一维数组 四…

【多线程】阻塞队列

&#x1f3c0;&#x1f3c0;&#x1f3c0;来都来了&#xff0c;不妨点个关注&#xff01; &#x1f3a7;&#x1f3a7;&#x1f3a7;博客主页&#xff1a;欢迎各位大佬! 文章目录 1. 阻塞队列是什么2. 简单使用阻塞队列3. 阻塞队列的应用场景——生产者消费者模型3.1 生产者消…

bootStrap中操作行详情,删除,修改等操作

点击列表某一行的操作按钮&#xff0c;结合swtich case 出发不同操作

spring boot 实现 Stream 钉钉事件订阅

1: 参考链接 https://open.dingtalk.com/document/orgapp/develop-stream-mode-push-server 2&#xff1a;钉钉开放平台订阅配置 配置之后运行一下上面提供的链接 里面的main方法&#xff0c;验证通道 3&#xff1a;订阅启动方式 EventListenerThread eventListenerThrea…

nvm管理node版本问题处理集合

windows上通过nvm管理node版本&#xff0c;通过nvm安装node&#xff0c;报错了&#xff0c;信息&#xff1a; > Could not retrieve https://nodejs.org/dist/latest/SHASUMS256.txt. Get > https://nodejs.org/dist/latest/SHASUMS256.txt: dial tcp 104.20.23.46:443: …

如何通过阿里云服务器部署hexo博客(超详细)

&#x1f44f;大家好&#xff01;我是和风coding&#xff0c;希望我的文章能给你带来帮助&#xff01; &#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博主哦 &#x1f4dd;点击 我的主页 还可以看到和风的其他内容噢&#x…

软件测试20个基础面试题及答案

什么是软件测试&#xff1f; 答案&#xff1a;软件测试是指在预定的环境中运行程序&#xff0c;为了发现软件存在的错误、缺陷以及其他不符合要求的行为的过程。 软件测试的目的是什么&#xff1f; 答案&#xff1a;软件测试的主要目的是保证软件的质量&#xff0c;并尽可能…

【C++】类和对象两个必看题

这两个题只有一句代码的差别。 看题目之前我先说一下怎么看汇编指令。 第一题&#xff1a;下面程序运行结果是&#xff1f; A.编译报错 B.运行崩溃 C.正常运行 #include <iostream> using namespace std; class A { public:void Print(){cout << "A::Pri…

【数据结构初阶】二叉树与堆(一)

文章目录 一、树的基础概念1、节点与度数2、树的度与高度3、引入&#xff1a;数组下标为何从0开始4、祖先节点5、树是递归定义的6、树与非树的区别7、代码表示 二、二叉树2.1、满二叉树2.2、完全二叉树2.3、完全二叉树的存储 三、堆 一、树的基础概念 1、节点与度数 节点分为…

多语言海外AEON抢单可连单加额外单源码,java版多语言抢单系统

多语言海外AEON抢单可连单加额外单源码&#xff0c;java版多语言抢单系统。此套是全新开发的java版多语言抢单系统。 后端java&#xff0c;用的若依框架&#xff0c;这套代码前后端是编译后的&#xff0c;测试可以正常使用&#xff0c;语言繁体&#xff0c;英文&#xff0c;日…

Charles怎么修改参数

Charles怎么修改参数 1、再【Structure】下&#xff0c;找到需要抓取的包&#xff0c;鼠标右键&#xff0c;点中断点。 2、在【Proxy】-点击【Breakpoint Settings…】 3、双击设置断点的接口 4、勾选后&#xff0c;点击【OK】。 5、再次刷新&#xff0c;重新发请求&#…

Nginx解析漏洞

一、nginx_parsing 这个解析漏洞其实是PHP CGI的漏洞&#xff0c;在PHP的配置文件中有一个关键的选项cgi.fix_pathinfo默认是开启的&#xff0c;当URL中有不存在的文件&#xff0c;PHP就会向前递归解析。在一个文件/xx.jpg后面加上/php会将/xx.jpg/xx.php解析为php文件。 1、…

第三方库认识- Mysql 数据库 API 认识

文章目录 一、msyql数据库API接口1.初始化mysql_init()——mysql_init2.链接数据库mysql_real_connect——mysql_real_connect3.设置当前客户端的字符集——mysql_set_character_set4.选择操作的数据库——mysql_select_db5.执行sql语句——mysql_query6.保存查询结果到本地——…

修改mac的音量能像windows系统那样给出音量反馈吗?

一、背景 windows有一些非常好的设计&#xff0c;比如拖动音量条的时候会有对应的音量大小的反馈。有时还能用来确定是视频没声音还是电脑坏了 在mac里怎么设置&#xff1f; 二、方法 首先点击菜单栏音量按钮->声音偏好设置…->勾选 “当更改音量时播放反馈”。 mac…