C++学习笔记
----结构
一.结构的概念
- 概念
结构是将多个相关的数据组装成一个整体来使用,其中的每个数据称为结构的成员。 - 声明:
struct 结构类型名
{
数据类型1 结构成员标识符1;
数据类型2 结构成员标识符2;
...
};
- 定义:
结构类型名 结构变量标识符1, 结构变量标识符2, ... ;
- 声明和定义
(1)先定义结构体类型再单独进行变量定义
struct Student
{
int Number;
char Name[20];
char Sex;
int Age;
};
struct Student Stu;
struct Student StuArray[10];
struct Student *pStu;
(2)紧跟在结构体类型说明之后进行定义
struct Student
{
int Number;
char Name[20];
char Sex;
int Age;
}Stu,StuArray[10],*pStu;
(3)在说明一个无名结构体变量的同时直接进行定义, 之后不得定义
struct
{
int Number;
char Name[20];
char Sex;
int Age;
}Stu,StuArray[10],*pStu;
(4)使用typedef说明一个结构体变量之后再用新类名来定义变量
typedef struct
{
int Number;
char Name[20];
char Sex;
int Age;
}Student;
Student Stu,StuArray[10],*pStu;
(5)使用new动态创建结构体变量
struct Student
{
int Number;
char Name[20];
char Sex;
int Age;
}Stu,StuArray[10],*pStu;
int main(){
struct Student *s = new Student();
s->Code = 1;
cout<< s->Code << endl; //输出1,s.Number为1
delete [] s;
return 0;
}
- 其他
结构成员标识符可以与程序中的其他变量名同名,不同结构类型的成员也可以同名。
结构类型的声明不会分配内存,定义后才分配。不能在结构体声明中初始化结构体成员。
为一个结构变量所分配的内存是这个变量所属的结构类型中所有成员所占的内存之和。
- 初始化
(1)在定义的同时就采用类似数组初始化的方式在初始化列表中给出各个成员初始值常量的方式对结构变量进行初始化:
结构类型名 结构变量标识符 = {成员1的初始值, 成员2的初始值, ...};
(2)定义时先不初始化,随后用赋值语句对结构的成员逐一赋值进行初始化:
结构变量标识符.成员名1 = 初始值1;
结构变量标识符.成员名2 = 初始值2;
(3)在定义的同时或之后,用赋值语句将一个已经初始化的同类型结构变量赋值给未初始化的结构变量(同类型的结构变量可以赋值)。 - 引用
(1)用结构变量名后跟‘.’运算符:
结构变量名.成员
(2)先定义一个结构变量指针,然后用结构变量指针后跟’->'运算符:
结构类型 结构变量指针名 = &结构变量名;
结构变量指针名 -> 成员;
或者(*结构变量指针名).成员;
二.结构作为函数的形参
- 可以将函数的形参定义为结构变量将结构实参值拷贝传递给形参,也可以将函数的形参定义为结构变量的指针和结构变量的引用,实现函数的传址调用和引用调用。
- 传递结构成员
#include <iostream>
using namespace std;
struct Student
{
string name;
int grades;
};
int last(int scores, int aver)
{
return scores - aver;
}
int main()
{
const int aver = 73;
struct Student stu[2];
stu[0] = {"LiHua", 89};
stu[1] = {"XiaoMing", 70};
for(int i = 0; i < 2; i++)
cout << stu[i].name << ':' << last(stu[i].grades, aver) << endl;
return 0;
}
- 传递结构
#include <iostream>
using namespace std;
struct Student
{
string name;
int grades;
};
int last(struct Student stu1, int aver)
{
return stu1.grades - aver;
}
int main()
{
const int aver = 73;
struct Student stu[2];
stu[0] = {"LiHua", 89};
stu[1] = {"XiaoMing", 70};
for(int i = 0; i < 2; i++)
cout << stu[i].name << ':' << last(stu[i], aver) << endl;
return 0;
}
- 传递结构的地址
#include <iostream>
using namespace std;
struct Student
{
string name;
int grades;
};
int last(const struct Student *stu1, int aver)
{
return stu1->grades - aver;
}
int main()
{
const int aver = 73;
struct Student stu[2];
stu[0] = {"LiHua", 89};
stu[1] = {"XiaoMing", 70};
for(int i = 0; i < 2; i++)
cout << stu[i].name << ':' << last(&stu[i], aver) << endl;
return 0;
}
三.返回结构的函数
- 函数的返回类型也可以定义为结构、结构指针和结构引用,通过return 语句返回结构变量的值、地址和引用。
- 由于结构有多个成员,将结构变量作为函数形参和函数的类型,可以节省函数参数的个数,一次性向函数传递或从函数返回多个数据。
- 代码实现
#include <iostream>
using namespace std;
struct Student
{
string name;
int grades;
};
struct Student list(string name, int grades)
{
struct Student stu;
stu.name = name;
stu.grades = grades;
return stu;
}
int main()
{
string name = "LiHua";
int grades = 89;
struct Student stu1 = {"0", 0};
stu1 = list(name, grades);
struct Student *p = &stu1;
cout << (*p).name << endl;
cout << p->grades << endl;
return 0;
}
- 运行结果
四.单向链表
- 概念
链表 = 动态内存分配 + 结构 + 指针; - 优点:
(1)按需分配,动态扩充或缩减。
(2)所有节点逻辑上相互连接形成一条链,但物理上节点之间可以连续,也可以不连续储存。
(3)可在任意地方插入或者删除节点。 - 单链表是节点只有一个指针的链表,只能从head表头一个方向访问链表的节点。单链表的插入和删除,不需要移动元素,只需修改节点指针即可。
struct SNode
{
int data;
SNode *next; //指向下一个节点,形成链条
}
- 单链表节点的插入
(1)在链表最后一个节点后插入
SNode *p1, *p2;
p1 = head;
while(p1->next != NULL)
p1 = p1->next; //让p1指向链尾节点
p2 = new SNode; //分配新节点
p2->data = x;
p2->next = NULL;
p1->next = p2; //并使其作为链尾节点
(2)在链表中间节点插入
SNode *p1, *p2;
p1 = head;
while(p1->data != wanted_data)
p1 = p1->next; //让p1指向插入前的节点
p2 = new SNode; //分配新节点
p2->data = x;
p2->next = p1->next;
p1->next = p2;
(3)在链表第一个节点插入
SNode *p2;
p2 = new SNode;
p2->data = x;
p2->next = head;
head = p2;
- 单链表节点的删除
(1)删除链表中间或第一个节点
SNode *p1, *p2;
p1 = head;
p2 = p1;
while(p1->data != wanted_data)
{
p2 = p1;
p1 = p1->next; //让p1指向要删除的节点
}
if(p1 == head)
head = p1->next;
else
p2->next = p1->next;
delete p1;
(2)删除链表的最后一个节点
SNode *p1, *p2;
p1 = head;
p2 = p1;
while(p1->next != NULL)
{
p2 = p1;
p1 = p1->next; //让p1指向链尾节点
}
p2->next = NULL;
delete p1;
- 单向链表例程
#include <iostream>
using namespace std;
struct SNode
{
int data;
SNode *p_next;
};
SNode *head;
SNode *deleteNode(int x)
{
SNode *p1, *p2;
p1 = head;
p2 = p1;
while (p1->data != x)
{
p2 = p1;
p1 = p1->p_next;
if (p1 == NULL)
return head;
}
if (p1 == head)
head = p1->p_next;
else
p2->p_next = p1->p_next;
delete p1;
return head;
}
SNode *createList(int x)
{
if (head == NULL)
{
head = new SNode;
head->data = x;
head->p_next = NULL;
}
else
{
SNode *p1, *p2;
p1 = head;
while (p1->p_next != NULL)
p1 = p1->p_next;
p2 = new SNode;
p2->data = x;
p2->p_next = NULL;
p1->p_next = p2;
}
return head;
}
void traverse()
{
SNode *p = head;
while (p != NULL)
{
cout << p->data << endl;
p = p->p_next;
}
}
void releaseList()
{
SNode *p1 = head;
while (p1 != NULL)
{
head = p1;
p1 = p1->p_next;
delete head;
}
}
int main()
{
for(int i = 0; i < 10; i++)
createList(i);
deleteNode(7);
traverse();
releaseList();
return 0;
}