第七讲 类、结构体、指针与引用¶
类可以将变量、数组和函数完美地打包在一起。
1. 类与结构体¶
类完全是为人类服务的
可以打包很多复杂的东西
类的定义:
class Person
{
private:
int age, height;
double money;
string books[100];
public:
string name;
void say()
{
cout << "I'm " << name << endl;
}
int get_age()
{
return age;
}
void add_money(double x)
{
money += x;
}
};
类中的变量和函数被统一称为类的成员变量
。
private后面的内容是私有成员变量,在类的外部不能访问;public后面的内容是公有成员变量,在类的外部可以访问。
类的使用:
#include <iostream>
using namespace std;
const int N = 1000010;
class Person
{
private:
int age, height;
double money;
string books[100];
public:
string name;
void say()
{
cout << "I'm " << name << endl;
}
int set_age(int a)
{
age = a;
}
int get_age()
{
return age;
}
void add_money(double x)
{
money += x;
}
} person_a, person_b, persons[100];
int main()
{
Person c;
c.name = "yxc"; // 正确!访问公有变量
c.age = 18; // 错误!访问私有变量
c.set_age(18); // 正确!set_age()是共有成员变量
c.add_money(100);
c.say();
cout << c.get_age() << endl;
return 0;
}
结构体和类的作用是一样的。不同点在于类默认是private,结构体默认是public。
struct Person
{
private:
int age, height;
double money;
string books[100];
public:
string name;
void say()
{
cout << "I'm " << name << endl;
}
int set_age(int a)
{
age = a;
}
int get_age()
{
return age;
}
void add_money(double x)
{
money += x;
}
} person_a, person_b, persons[100];
结构体构造函数:
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
struct Person {
int age, height;
double money;
Person() {}
Person(int _age, int _height) : age(_age), height(_height) {}
Person(int _age, int _height, double _money) : age(_age), height(_height), money(_money) {}
};
int main () {
Person p = {18, 180};
cout << p.money << endl;
}
代码长的时候才会显示出类和结构题的作用和好处
2. 指针和引用¶
指针指向存放变量的值的地址。因此我们可以通过指针来修改变量的值。
操作系统运行程序,每个程序都是一个进程(process)
进程的空间(内存),所有进程运行的大小
映射之后,内存会变成一个16g的数组,编码之后内存的地址是16进制的
假设是4G内存,从0X00000000 - 0 XFFFFFFFF, 2的32次放 (单位是字节byte)
内存在上面的是栈,在下面的是堆,局部变量全部在栈,全局变量在堆空间(默认全部初始化成0)
指针
输出地址:
#include <iostream>
using namespace std;
char a, b;
int main () {
char c, d;
cout << (void*)&a << endl;
cout << (void*)&b << endl;
cout << (void*)&c << endl;
cout << (void*)&d << endl;
return 0;
}
输出:(注意大小顺序)
0x10d9bd040
0x10d9bd041
0x7ff7b254a8fb
0x7ff7b254a8fa
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int *p = &a; //*表示p是int类型的指针
*p += 5; // *p这个地址表示的真正的数,a也随着变化
cout << a << endl;
return 0;
}
数组名是个指针,是数组第一个变量的地址,数组的地址必须是连续的一段
数组名是一种特殊的指针。指针可以做运算:
#include <iostream>
using namespace std;
int main()
{
int a[5] = {1, 2, 3, 4, 5};
for (int i = 0; i < 5; i ++ )
cout << *(a + i) << endl;
return 0;
}
每个int变量包含4个字节
引用和指针类似,相当于给变量起了个别名。
#include <iostream>
using namespace std;
int main()
{
int a = 10;
int &p = a;
p += 5;
cout << a << endl;
return 0;
}
数组里面取a[2]:
#include <iostream>
using namespace std;
char a, b;
int main () {
char c;
int a[5] = {1, 2, 3, 4, 5};
int *p = a;
cout << *(p + 2) << endl; // a[2]
return 0;
}
#include <iostream>
using namespace std;
int main () {
char c;
int a[5] = {1, 2, 3, 4, 5};
int *p = &a[0], *q = &a[2];
cout << q - p << endl; // 这个是地址的减法
return 0;
}
常用方法:(别名)
改变a,p也会变;改变p,a也会变
int *p = &a; // c语言写法
int &p = a; // c++的引用、别名,是上面的简用
3. 链表¶
算法当中的某一种结构
#include <iostream>
using namespace std;
struct Node {
int val;
Node* next;
Node(int _val) : val(_val), next(NULL) {}
};
int main () {
Node* p = new Node(1); // new 动态开辟一个内存空间
// p->next = p; // 前面这个变量是地址的话,就用->否则会用p.next
Node* q = new Node(2);
auto o = new Node(3);
p->next = q;
q->next = o;
Node* head = p;
//链表的第一个点叫做头节点,习惯将第一个节点的地址存到head里面
//链表的遍历方式
// 添加一个节点
Node* u = new Node(4);
u->next = head;
head = u;
// 删除一个节点,链表的删除是指在原链表的遍历过程中,把这个点跳过去,遍历不到这个点就可以了
head->next = head->next->next;
for(Node* i = head; i != NULL;i = i->next)
cout << i->val << endl;
return 0;
}
#include <iostream>
using namespace std;
struct Node
{
int val;
Node* next; // 可以定义结构体的指针,但是不能定义这个结构体的变量,就是一个64位的整数
} *head;
int main()
{
for (int i = 1; i <= 5; i ++ )
{
Node* p = new Node();
p->val = i;
p->next = head;
head = p;
}
for (Node* p = head; p; p = p->next)
cout << p->val << ' ';
cout << endl;
return 0;
}
听到1.7类结构体与指针的1:13