类与结构体

类的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Person
{
private: //private私有变量
int age, height;
double money;
string book[100];

public: //public公有变量
string name;

void say()
{
cout << "I`m" << name << endl;
}

int get_age()
{
return age;
}

void add_money(double x)
{
money += x;
}
};

类中的变量和函数被统一称为类的成员变量。

private后面的内容是私有成员变量,在类的外部不能访问;public后面的内容是公有成员变量,在类的外部可以访问。在类中,如果不表明是私有变量还是公有变量则默认是私有变量。

类的使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
#include <iostream>

using namespace std;

class Person
{
private: //private私有变量
int age, height;
double money;
string book[100];

public: //public公有变量
string name;

void say()
{
cout << "I`m" << name << endl;
}

int get_age()
{
return age;
}

int set_age(int a)
{
age = a;
return age;
}

void add_money(double x)
{
money += x;
}
};

int main()
{
Person c;

c.name = "Caliburian";
//c.age = 18; age私有变量无法在类外面访问
c.set_age(23);
cout << c.get_age() << endl;
c.add_money(13);
return 0;
}

结构体

结构体的定义

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
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]; //person_a, person_b 分别表示两个独立的Person对象,而persons[100]则是由100个Person对象组成的数组。

构造函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>

using namespace std;

struct Person
{
int age, height;
double money;

Person(int _age, int _height, int _money) //构造函数
{
age = _age;
height = _height;
money = _money;
}

Person() {} //空默认构造函数
};

int main()
{
Person p(22, 181, 2000); //在构造结构体变量时,使用构造函数直接为变量赋值
Person p1 = {18, 180, 1500}; //按顺序赋值
Person q; //不给初值必须使用默认构造函数

return 0;
}

另一种构造函数写法

1
struct Person(int _age, int _height, double _money) : age(_age), height(_height), money(_money);

指针和引用

指针

指针指向存放变量的值的地址。因此我们可以通过指针来修改变量的值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>

using namespace std;

int main()
{
int a = 10;
int *p = &a; //定义一个指针类型的变量p并初始化为a的地址

cout << *p << endl; //输出指针p所指的地址的值

*p = 12; //修改指针p所指的地址的值

cout << *p << endl;
cout << a << endl; //a被修改

int **q = &p; //定义指针p的制作q
cout << q << endl; //输出指针q的地址

return 0;
}

输出

1
2
3
4
10
12
12
0x61fe08

数组名是一种特殊的指针:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <iostream>

using namespace std;

int main()
{
int a[5] = {1, 2, 3, 4, 5};

cout << a << endl;

for (int i = 0; i < 5; i ++ )
cout << *(a + i) << endl;

return 0;
}

输出

1
2
3
4
5
6
0x61fe00
1
2
3
4
5

在指针类型不同时直接对指针进行+1操作,指针的地址变化也不同,如int型变量是4个字节,所以下一个地址是这个地址加4,而char型就是加2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include <iostream>

using namespace std;

int main()
{
int a[5] = {1, 2, 3, 4, 5};
int *p = a;

char b[5] = {'a', 'b', 'c', 'd', 'e'};
char *q = b;

cout << p << endl;
cout << p + 1 << endl;
cout << (void*)q << endl;
cout << (void*)q + 1 << endl;

return 0;
}

输出

1
2
3
4
0x61fdf0
0x61fdf4
0x61fdeb
0x61fdec

引用

引用和指针类似,相当于给变量起了一个别名。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include <iostream>

using namespace std;

int main()
{
int a = 10;
int &p = a; //用p作为a的引用,且p和a存在同一个地址,类似别名

p += 5;
cout << a << endl;

return 0;
}

输出

1
15

atoistoi都可以用于将字符串转换为整数,

1
2
atoi(str.c_str());
stoi(str);

链表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#include <iostream>

using namespace std;

struct Node
{
int val;
Node* next;
} *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. 斐波那契数列

    输入一个整数 n,求斐波那契数列的第n项。

    假定从 0开始,第 0项为 0。

    输入样例

    1
    5

    输出样例

    1
    5

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    #include <iostream>

    using namespace std;

    class Solution {
    public:
    int Fibonacci(int n) {
    int dp[40];
    dp[0] = 0;
    dp[1] = 1;
    for (int i = 2; i <= n; i ++)
    dp[i] = dp[i - 1] + dp[i - 2];

    return dp[n];
    }
    };

    int main()
    {
    int n;
    cin >> n;

    Solution solution;
    cout << solution.Fibonacci(n) << endl;

    return 0;
    }
  2. 替换空格

    请实现一个函数,把字符串中的每个空格替换成%20

    数据范围

    0≤输入字符串的长度 ≤1000
    注意输出字符串的长度可能大于 1000

    输入样例

    1
    "We are happy."

    输出样例

    1
    "We%20are%20happy.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    #include <iostream>

    using namespace std;

    class Solution {
    public:
    string replaceSpaces(string &str) { //此处使用&str引用,避免创建副本占用内存
    string res;
    for (auto c : str) //for循环遍历str,自动判断类型
    {
    if (c == ' ')
    res += "%20";
    else
    res += c;
    }

    return res;
    }
    };

    int main()
    {
    Solution solution;
    string s;
    getline(cin, s);
    cout << solution.replaceSpaces(s) << endl;

    return 0;
    }
  3. 求1+2+…+n

    1+2+…+n,要求不能使用乘除法、for、while、if、else、switch、case 等关键字及条件判断语句 (A?B:C)

    数据范围

    1≤n≤50000

    输入样例

    1
    10

    输出样例

    1
    55

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    #include <iostream>

    using namespace std;

    class Solution {
    public:
    int getSum(int n) {
    int res = n;
    n > 0 && (res += getSum(n - 1)); //如果n > 0,则执行后面的否则不执行
    return res;
    }
    };

    int main()
    {
    int n;
    cin >> n;

    Solution solution;

    cout << solution.getSum(n) << endl;

    return 0;
    }
  4. 左旋转字符串

    字符串的左旋转操作是把字符串前面的若干个字符转移到字符串的尾部。

    请定义一个函数实现字符串左旋转操作的功能。

    比如输入字符串”abcdefg”和数字 2,该函数将返回左旋转 2位得到的结果”cdefgab”。

    数据范围

    输入字符串长度 [0,1000]

    输入样例

    1
    2
    abcdefg
    2

    输出样例

    1
    cdefgab

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #include <iostream>
    #include <algorithm>

    using namespace std;

    class Solution {
    public:
    string leftRotateString(string str, int n) {
    int len = str.size();

    if (len == 0 || n >= len || n <= 0)
    return str;

    reverse(str.begin(), str.end());
    reverse(str.begin(), str.end() - n);
    reverse(str.end() - n, str.end());

    return str;
    }
    };

    int main()
    {
    string str;
    int n;

    cin >> str;
    cin >> n;

    Solution solution;

    cout << solution.leftRotateString(str, n) << endl;

    return 0;
    }