0%

C语法基础大全

一、基础

1.1 简单示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class Solution {
public:
string longestCommonPrefix(vector<string>& strs) {
if (!strs.size()) {
return "";
}
int length = strs[0].size();
int count = strs.size();
for (int i = 0; i < length; ++i) {
char c = strs[0][i];
for (int j = 1; j < count; ++j) {
if (i == strs[j].size() || strs[j][i] != c) {
return strs[0].substr(0, i);
}
}
}
return strs[0];
}
};

1.2 指针

1.2.1 原理

指针地址的原理如下:

1.2.2 指针与数组的关系

指针与一维数组的关系:

指针与二维数组的关系:

1.2.3 注意事项

  • a与&a[0]等价
  • a[0]与*a、&a[0][0]等价
  • pa指向地址array[0][0]
  • (pa+i)地址指向array[i][0]
  • (*(pa+i)+j)地址指向array[i][j]
  • 二维数组的一维访问形式a[i][j]=*(a[0]+n*i+j)=*(*a+n*i+j)

1.3 字符串

在C/C++中的字符串均以char[]类型进行存储,char是一个字符类型 C++的内置类型,C/C++中的string实为一个类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// char数组初始化、修改与输出
char a[10] = "123";
a[0] = 'a';
*(a+1) = 'b'; // 由于指针和数组等价,所有可以通过指针修改数组内容
cout << *(a+1); // 输出数组的第1个字符2

// 字符串常量
const char *str1 = "abcde"; // 只读常量
str1 = "efghi"; // 目前来开是可以修改的,应该是修改了指针的指向,跟这个"abcde"常量无关
cout << str1;

// 打印输出string字符容器
string a("abc");
printf("%s\n", a.c_str());

1.4 容器

1.4.1 容器分类

序列式容器:

  • 序列式容器:每个元素都有固定位置--取决于插入时机和地点,和元素值无关
  • Vector:将元素置于一个动态数组中加以管理,可以随机存取元素(用索引直接存取),数组尾部添加或移除元素非常快速。但是在中部或头部安插元素比较费时
  • Deque:是“double-ended queue”的缩写,可以随机存取元素(用索引直接存取),数组头部和尾部添加或移除元素都非常快速。但是在中部或头部安插元素比较费时
  • List:双向链表,不提供随机存取(按顺序走到需存取的元素,O(n)),在任何位置上执行插入或删除动作都非常迅速,内部只需调整一下指针

关联式容器:

  • 关联式容器:元素位置取决于特定的排序准则,和插入顺序无关
  • Set/Multiset:内部的元素依据其值自动排序,Set内的相同数值的元素只能出现一次,Multisets内可包含多个数值相同的元素,内部由二叉树实现,便于查找;
    • unordered_map
  • Map/Multimap:Map的元素是成对的键值/实值,内部的元素依据其值自动排序,Map内的相同数值的元素只能出现一次,Multimaps内可包含多个数值相同的元素,内部由二叉树实现,便于查找
    • unordered_map

其他结构容器:

  • priority_queue:维护一个堆结构
  • stack:维护一个栈

1.5 函数

二、面向对象

2.1、面向对象的特性

2.1.1 封装

  • 封装就是将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的函数代码进行有机的结合,形成“类”,其中的数据和函数都是类的成员

2.1.2 继承

  • 根据现实中的事物之间的关系,抽象出了继承的概念
  • C++语言中提供了类的继承机制,允许程序员在保持原有类特性的基础上,进行更具体、更详细的说明

2.1.3 多态

  • 多态性是指程序能够处理多种类型对象的能力

2.2、类

2.2.1 类的定义

1
2
3
4
5
6
7
class Clock{
public:
void setTime(int newH,int newM,int newS);
void showTime();
private:
int hour,minute,second;
};

2.2.2 类的成员函数

1
2
3
4
5
类外实现
返回值类型 类名::函数成员名(参数表)
{
函数体
}

2.2.3 类的访问控制权限

访问限制

访问权限 类内成员函数 类对象 友元函数
public YES YES YES
protected YES NO YES
private YES NO YES

继承的权限变化

基类权限 public继承 protected继承 private继承
public public protected private
protected protected protected private
private 不可访问 不可访问 不可访问

2.2.4 构造函数

  • 构造函数的作用是在对象被创建时利用特定的值构造对象,将对象初始化为一个特定的状态
  • 构造函数在对象被创建的时候被自动调用
  • 构造函数的调用顺序:基类构造函数->对象成员构造函数->派生类本身的构造函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Clock{
public:
Clock(){} //无参构造
Clock(int newH,int newM,int newS); //带参数的构造函数
//或者
//Clock(int newH,int newM,int newS):hour(newH),minute(newM),second(newS){}
void setTime(int newH,int newM,int newS);
void showTime();
private:
int hour,minute,second;
};

Clock::Clock(int newH,int newM,int newS){
hour = newH;
minute = newM;
second = newS;
}

2.2.5 拷贝构造函数

  • 拷贝构造函数是一种特殊的构造函数,它在创建对象时,使用同一类中之前创建的对象来初始化新创建的对象,拷贝构造函数通常的步骤:
    • 通过使用另一个同类型的对象来初始化新创建的对象。
    • 复制对象把它作为参数传递给函数
    • 复制对象,并从函数返回这个对象

语法

  • 如果在类中没有定义拷贝构造函数,编译器会自行定义一个。如果类带有指针变量,并有动态内存分配,则它必须有一个拷贝构造函数。拷贝构造函数的最常见形式如下
  • 在这里,obj 是一个对象引用,该对象是用于初始化另一个对象的
    1
    2
    3
    classname (const classname &obj) {
    // 构造函数的主体
    }

2.2.6 析构函数

  • 析构函数用来完成对象被删除前的一些清理工作
  • 析构函数是在对象的生产期即将结束的时刻被自动调用的
  • 析构函数的调用顺序:派生类本身的析构函数->对象成员析构函数->基类析构函数(与构造顺序正好相反)
1
2
3
4
5
6
7
8
9
class Clock{
public:
Clock();
void setTime(int newH,int newM,int newS);
void showTime();
~Clock(){} // 析构函数
private:
int hour,minute,second;
}

2.2.7 类的继承

语法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class 基类1{

}

class 基类2{

}

class 派生类:继承方式 基类1,继承方式 基类2{
构造函数(参数列表){
基类1构造函数(参数);
基类2构造函数(参数);
派生类
}
}

实例

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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#include <iostream>
using namespace std;

// 基类 Shape
class Shape
{
public:
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};

// 基类 PaintCost
class PaintCost
{
public:
int getCost(int area)
{
return area * 70;
}
};

// 派生类
class Rectangle: public Shape, public PaintCost
{
public:
int getArea()
{
return (width * height);
}
};

int main(void)
{
Rectangle Rect;
int area;

Rect.setWidth(5);
Rect.setHeight(7);

area = Rect.getArea();

// 输出对象的面积
cout << "Total area: " << Rect.getArea() << endl;

// 输出总花费
cout << "Total paint cost: $" << Rect.getCost(area) << endl;

return 0;
}

//Total area: 35
//Total paint cost: $2450