不会请自查菜鸟教程:C++ 基本语法 | 菜鸟教程 (runoob.com)
一、基础语法那些词
- 类、对象、放法、即时变量
- 编译&执行c++程序
- 分号、空格、语句块
- 标识符
- 关键字
来吧,写一个简单的helloworld,或者菜鸟那个例子默写下来!
#include <iostream> using namespace std; int main { cout << "hello world"; return 0; }
二、再知道一些词汇(都写个例子)
1、数据类型
(void,int,float,double,bool,char,可以用short,long,signed,unsigned)
2、数据结构
①用户可以自定义的数据类型struct
②函数参数访问.
③指针定义*/查找&/访问->
④typedef可以为创建的类型取一个"别名")
3、数组
①申明:int balance[3];
②初始化:int balance[3]={1,2,3};
③访问:int a=balance[1]
4、vector容器
一种序列容器,它允许你在运行时动态地插入和删除元素:
💧#include <vector>
💧基本特性:
- 动态大小:
vector
的大小可以根据需要自动增长和缩小。- 连续存储:
vector
中的元素在内存中是连续存储的,这使得访问元素非常快速。- 可迭代:
vector
可以被迭代,你可以使用循环(如for
循环)来访问它的元素。- 元素类型:
vector
可以存储任何类型的元素,包括内置类型、对象、指针等。💧什么时候用:
- 当你需要一个可以动态增长和缩小的数组时。
- 当你需要频繁地在序列的末尾添加或移除元素时。
- 当你需要一个可以高效随机访问元素的容器时。
💧怎么用:
- 创建vector:std::vector<int> myVector(5, 10);// 包含 5 个整数vector,每个值都为 10
- 添加元素:myVector.push_back(7)
- 访问元素:int x = myVector[0]; // 获取第一个元素
- 获取大小:int size = myVector.size(); // 获取 vector 中的元素数量
- 迭代访问:for (int element : myVector) {
std::cout << element << " ";
}- 删除元素:myVector.erase(myVector.begin() + 2); // 删除第三个元素
- 清空vector:myVector.clear(); // 清空 vector
5、指针
是个变量,它的值是某变量的地址-----------本质是个地址变量
比喻:写有房间门牌号的变量
#include <iostream> using namespace std; int main () { int var = 20; // 实际变量的声明 int *ip; // 指针变量的声明 ip = &var; // 在指针变量中存储 var 的地址 cout << "Value of var variable: "; cout << var << endl; // 输出在指针变量中存储的地址 cout << "Address stored in ip variable: "; cout << ip << endl; // 访问指针中地址的值 cout << "Value of *ip variable: "; cout << *ip << endl; return 0; }
6、存储类
定义 C++ 程序中变量/函数的范围(可见性)和生命周期。
这些说明符放置在它们所修饰的类型之前
auto:这是默认的存储类说明符,通常可以省略不写。auto 指定的变量具有自动存储期,即它们的生命周期仅限于定义它们的块(block)。auto 变量通常在栈上分配。
register:用于建议编译器将变量存储在CPU寄存器中以提高访问速度。在 C++11 及以后的版本中,register 已经是一个废弃的特性,不再具有实际作用。
static:用于定义具有静态存储期的变量或函数,它们的生命周期贯穿整个程序的运行期。在函数内部,static变量的值在函数调用之间保持不变。在文件内部或全局作用域,static变量具有内部链接,只能在定义它们的文件中访问。
extern:用于声明具有外部链接的变量或函数,它们可以在多个文件之间共享。默认情况下,全局变量和函数具有 extern 存储类。在一个文件中使用extern声明另一个文件中定义的全局变量或函数,可以实现跨文件共享。
mutable (C++11):用于修饰类中的成员变量,允许在const成员函数中修改这些变量的值。通常用于缓存或计数器等需要在const上下文中修改的数据。
thread_local (C++11):用于定义具有线程局部存储期的变量,每个线程都有自己的独立副本。线程局部变量的生命周期与线程的生命周期相同。
7、修饰符类型
signed:表示变量可以存储负数。对于整型变量来说,signed 可以省略,因为整型变量默认为有符号类型。
unsigned:表示变量不能存储负数。对于整型变量来说,unsigned 可以将变量范围扩大一倍。
short:表示变量的范围比 int 更小。short int 可以缩写为 short。
long:表示变量的范围比 int 更大。long int 可以缩写为 long。
long long:表示变量的范围比 long 更大。C++11 中新增的数据类型修饰符。
float:表示单精度浮点数。
double:表示双精度浮点数。
bool:表示布尔类型,只有 true 和 false 两个值。
char:表示字符类型。
wchar_t:表示宽字符类型,可以存储 Unicode 字符。
8、注释方式
注释方式
①单行://
②多行注释:/*注释内容*/
③类似///@author系统专业注释待补充
9、 打印与输入
C++ 的 I/O 发生在流中,流是字节序列。
- 若字节流从设备(如键盘、磁盘驱动器、网络连接等)流向内存,叫做输入操作。
- 若字节流从内存流向设备(如显示屏、打印机、磁盘驱动器、网络连接等),叫做输出操作。
#include <iostream>
#include <iostream> using namespace std; int main( ) { char str[] = "Hello C++"; cout << "Value of str is : " << str << endl; }
打印结果是:Value of str is : Hello C++
#include <iostream> using namespace std; int main( ) { char name[50]; cout << "请输入您的名称: "; cin >> name; cout << "您的名称是: " << name << endl; }
打印结果是:
请输入您的名称: cplusplus
您的名称是: cplusplus
10、函数
函数还有很多叫法,比如方法、子例程或程序。
- 返回类型:一个函数可以返回一个值。return_type 是函数返回的值的数据类型。有些函数执行所需的操作而不返回值,在这种情况下,return_type 是关键字 void。
- 函数名称:这是函数的实际名称。函数名和参数列表一起构成了函数签名。
- 参数:参数就像是占位符。当函数被调用时,您向参数传递一个值,这个值被称为实际参数。参数列表包括函数参数的类型、顺序、数量。参数是可选的,也就是说,函数可能不包含参数。
- 函数主体:函数主体包含一组定义函数执行任务的语句。
结构:
return_type function_name( parameter list )
{
body of the function
}
函数申明与函数调用:
#include <iostream> using namespace std; // 函数声明 int max(int num1, int num2); int main () { // 局部变量声明 int a = 100; int b = 200; int ret; // 调用函数来获取最大值 ret = max(a, b); cout << "Max value is : " << ret << endl; return 0; } // 函数返回两个数中较大的那个数 int max(int num1, int num2) { // 局部变量声明 int result; if (num1 > num2) result = num1; else result = num2; return result; }
11、引用 &
它是某个已存在变量的另一个名字
引用很容易与指针混淆,它们之间有三个主要的不同:
- 不存在空引用。引用必须连接到一块合法的内存。
- 一旦引用被初始化为一个对象,就不能被指向到另一个对象。指针可以在任何时候指向到另一个对象。
- 引用必须在创建时被初始化。指针可以在任何时间被初始化。
#include <iostream>
using namespace std;
int main ()
{
// 声明简单的变量
int i;
double d;
// 声明引用变量
int& r = i;// 读作 "r 是一个初始化为 i 的整型引用"
double& s = d;//读作 "s 是一个初始化为 d 的 double 型引用"
i = 5;
cout << "Value of i : " << i << endl;
cout << "Value of i reference : " << r << endl;
d = 11.7;
cout << "Value of d : " << d << endl;
cout << "Value of d reference : " << s << endl;
return 0;
}
输出结果:
Value of i : 5
Value of i reference : 5
Value of d : 11.7
Value of d reference : 11.7
引用通常用于:函数参数列表和函数返回值
void swap(int& x, int& y)
{
int temp;
temp = x; /* 保存地址 x 的值 */
x = y; /* 把 y 赋值给 x */
y = temp; /* 把 x 赋值给 y */
return;
}
double& setValues(int i) {
double& ref = vals[i];
return ref; // 返回第 i 个元素的引用,ref 是一个引用变量,ref 引用 vals[i]
}
12、运算符
- 算术运算符(+ ,- ,*, / ,% ,++, --)
- 关系运算符(==,!=,>, < , ≥,≤)
- 逻辑运算符(&&,||,!)
- 位运算符(&,|,^, ~,<<,>>)
- 赋值运算符(=,+=,-=,*=,/=,&=,|=,<<=,>>=,^=)
- 杂项运算符(暂不了解)
13、循环
循环类型 | 描述 |
---|---|
while 循环 | 当给定条件为真时,重复语句或语句组。它会在执行循环主体之前测试条件。 |
for 循环 | 多次执行一个语句序列,简化管理循环变量的代码。 |
do...while 循环 | 除了它是在循环主体结尾测试条件外,其他与 while 语句类似。 |
嵌套循环 | 您可以在 while、for 或 do..while 循环内使用一个或多个循环。 |
控制语句 | 描述 |
---|---|
break 语句 | 终止 loop 或 switch 语句,程序流将继续执行紧接着 loop 或 switch 的下一条语句。 |
continue 语句 | 引起循环跳过主体的剩余部分,立即重新开始测试条件。 |
goto 语句 | 将控制转移到被标记的语句。但是不建议在程序中使用 goto 语句。 |
14、判断
语句 | 描述 |
---|---|
if 语句 | 一个 if 语句 由一个布尔表达式后跟一个或多个语句组成。 |
if...else 语句 | 一个 if 语句 后可跟一个可选的 else 语句,else 语句在布尔表达式为假时执行。 |
嵌套 if 语句 | 您可以在一个 if 或 else if 语句内使用另一个 if 或 else if 语句。 |
switch 语句 | 一个 switch 语句允许测试一个变量等于多个值时的情况。 |
嵌套 switch 语句 | 您可以在一个 switch 语句内使用另一个 switch 语句。 |
15、变量类型
整数类型(Integer Types):
int
:用于表示整数,通常占用4个字节。short
:用于表示短整数,通常占用2个字节。long
:用于表示长整数,通常占用4个字节。long long
:用于表示更长的整数,通常占用8个字节。浮点类型(Floating-Point Types):
float
:用于表示单精度浮点数,通常占用4个字节。double
:用于表示双精度浮点数,通常占用8个字节。long double
:用于表示更高精度的浮点数,占用字节数可以根据实现而变化。字符类型(Character Types):
char
:用于表示字符,通常占用1个字节。wchar_t
:用于表示宽字符,通常占用2或4个字节。char16_t
:用于表示16位Unicode字符,占用2个字节。char32_t
:用于表示32位Unicode字符,占用4个字节。布尔类型(Boolean Type):
bool
:用于表示布尔值,只能取true
或false
。枚举类型(Enumeration Types):
enum
:用于定义一组命名的整数常量。指针类型(Pointer Types):
type*
:用于表示指向类型为type
的对象的指针。数组类型(Array Types):
type[]
或type[size]
:用于表示具有相同类型的元素组成的数组。结构体类型(Structure Types):
struct
:用于定义包含多个不同类型成员的结构。类类型(Class Types):
class
:用于定义具有属性和方法的自定义类型。共用体类型(Union Types):
union
:用于定义一种特殊的数据类型,它可以在相同的内存位置存储不同的数据类型。
16、变量作用域
局部作用域:在函数内部声明的变量具有局部作用域,它们只能在函数内部访问。局部变量在函数每次被调用时被创建,在函数执行完后被销毁。
全局作用域:在所有函数和代码块之外声明的变量具有全局作用域,它们可以被程序中的任何函数访问。全局变量在程序开始时被创建,在程序结束时被销毁。
块作用域:在代码块内部声明的变量具有块作用域,它们只能在代码块内部访问。块作用域变量在代码块每次被执行时被创建,在代码块执行完后被销毁。
类作用域:在类内部声明的变量具有类作用域,它们可以被类的所有成员函数访问。类作用域变量的生命周期与类的生命周期相同。
17、常量
类型:整数常量、浮点常量、布尔常量、字符常量、字符串常量“”、
在 C++ 中,有两种简单的定义常量的方式:
- 使用 #define 预处理器。
- 使用 const 关键字。
18、时期&时间
#include <ctime>
19、字符串string
#include <cstring>
20、数字
随机数:srand(),rand()
一个是 rand(),该函数只返回一个伪随机数。生成随机数之前必须先调用 srand() 函数。
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
int main ()
{
int i,j;
// 设置种子
srand( (unsigned)time( NULL ) );
/* 生成 10 个随机数 */
for( i = 0; i < 10; i++ )
{
// 生成实际的随机数
j= rand();
cout <<"随机数: " << j << endl;
}
return 0;
}
产生结果:
随机数: 1748144778
随机数: 630873888
随机数: 2134540646
随机数: 219404170
随机数: 902129458
随机数: 920445370
随机数: 1319072661
随机数: 257938873
随机数: 1256201101
随机数: 580322989
21、面向对象
(1)对象-类
类可以被看作是一种模板,可以用来创建具有相同属性和行为的多个对象。
定义c++对象(Box Box1;);
访问数据成员(Box1.height=1;以及Box3.get();)
#include <iostream>
using namespace std;
class Box
{
public:
double length; // 长度
double breadth; // 宽度
double height; // 高度
// 成员函数声明
double get(void);
void set( double len, double bre, double hei );
};
// 成员函数定义
double Box::get(void)
{
return length * breadth * height;
}
void Box::set( double len, double bre, double hei)
{
length = len;
breadth = bre;
height = hei;
}
int main( )
{
Box Box1; // 声明 Box1,类型为 Box
Box Box2; // 声明 Box2,类型为 Box
Box Box3; // 声明 Box3,类型为 Box
double volume = 0.0; // 用于存储体积
// box 1 详述
Box1.height = 5.0;
Box1.length = 6.0;
Box1.breadth = 7.0;
// box 2 详述
Box2.height = 10.0;
Box2.length = 12.0;
Box2.breadth = 13.0;
// box 1 的体积
volume = Box1.height * Box1.length * Box1.breadth;
cout << "Box1 的体积:" << volume <<endl;
// box 2 的体积
volume = Box2.height * Box2.length * Box2.breadth;
cout << "Box2 的体积:" << volume <<endl;
// box 3 详述
Box3.set(16.0, 8.0, 12.0);
volume = Box3.get();
cout << "Box3 的体积:" << volume <<endl;
return 0;
}
(2)三要素
-
封装
💧数据封装是一种把数据和操作数据的函数捆绑在一起的机制;
💧数据抽象是一种仅向用户暴露接口而把具体的实现细节隐藏起来的机制。
-
继承
💧基类-派生类
💧不说明修饰符,则默认是private
// 基类
class Animal {
// eat() 函数
// sleep() 函数
};
//派生类
class Dog : public Animal {
// bark() 函数
};
访问 | public | protected | private |
---|---|---|---|
同一个类 | yes | yes | yes |
派生类 | yes | yes | no |
外部的类 | yes | no | no |
-
多态
💧多态意味着调用成员函数时,会根据调用函数的对象的类型来执行不同的函数。
#include <iostream>
using namespace std;
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
virtual int area()//加了virtual,area()就是虚函数了,否则静态多态早绑定,无法多态
{
cout << "Parent class area :" <<endl;
return 0;
}
};
class Rectangle: public Shape{
public:
Rectangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Rectangle class area :" <<endl;
return (width * height);
}
};
class Triangle: public Shape{
public:
Triangle( int a=0, int b=0):Shape(a, b) { }
int area ()
{
cout << "Triangle class area :" <<endl;
return (width * height / 2);
}
};
// 程序的主函数
int main( )
{
Shape *shape;
Rectangle rec(10,7);
Triangle tri(10,5);
// 存储矩形的地址
shape = &rec;
// 调用矩形的求面积函数 area
shape->area();
// 存储三角形的地址
shape = &tri;
// 调用三角形的求面积函数 area
shape->area();
return 0;
}
当编译和执行前面的实例代码时,它会产生以下结果:
Rectangle class area : Triangle class area :
💧虚函数: 是在基类中使用关键字 virtual 声明的函数。在派生类中重新定义基类中定义的虚函数时,会告诉编译器不要静态链接到该函数。我们想要的是在程序中任意点可以根据所调用的对象类型来选择调用的函数,这种操作被称为动态链接,或后期绑定。
虚函数这样:
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
virtual int area()
{
cout << "Parent class area :" <<endl;
return 0;
}
};
💧纯虚函数:您可能想要在基类中定义虚函数,以便在派生类中重新定义该函数更好地适用于对象,但是您在基类中又不能对虚函数给出有意义的实现,这个时候就会用到纯虚函数。
纯虚函数这样:
class Shape {
protected:
int width, height;
public:
Shape( int a=0, int b=0)
{
width = a;
height = b;
}
// pure virtual function
virtual int area() = 0;
};
💧抽象类(通常称为 ABC)---c++接口:
抽象类定义:类中至少有一个函数被声明为纯虚函数,则这个类就是抽象类(不能被实例化,纯虚函数是通过在声明中使用 "= 0" 来指定的。(可用于实例化对象的类被称为具体类。))
抽象类目的:为了给其他类提供一个可以继承的适当的基类。抽象类不能被用于实例化对象,它只能作为接口使用。(没有在派生类中重写纯虚函数,就尝试实例化该类的对象,会导致编译错误。)
定义一个函数为虚函数,不代表函数为不被实现的函数。
定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。
定义一个函数为纯虚函数,才代表函数没有被实现。
定义纯虚函数是为了实现一个接口,起到一个规范的作用,规范继承这个类的程序员必须实现这个函数。
#include <iostream>
using namespace std;
// 基类
class Shape
{
public:
// 提供接口框架的纯虚函数
virtual int getArea() = 0;
void setWidth(int w)
{
width = w;
}
void setHeight(int h)
{
height = h;
}
protected:
int width;
int height;
};
// 派生类
class Rectangle: public Shape
{
public:
int getArea()
{
return (width * height);
}
};
class Triangle: public Shape
{
public:
int getArea()
{
return (width * height)/2;
}
};
int main(void)
{
Rectangle Rect;
Triangle Tri;
Rect.setWidth(5);
Rect.setHeight(7);
// 输出对象的面积
cout << "Total Rectangle area: " << Rect.getArea() << endl;
Tri.setWidth(5);
Tri.setHeight(7);
// 输出对象的面积
cout << "Total Triangle area: " << Tri.getArea() << endl;
return 0;
}
当上面的代码被编译和执行时,它会产生下列结果:
Total Rectangle area: 35 Total Triangle area: 17
(3)五原则:
-
单一职责原则
-
开放-封闭原则
对扩展开放,对修改封闭
-
liskov替换原则
派生类必须完全能够替换其基类(继承),关注行为的替换(多态)
-
依赖倒置原则
依赖抽象,面向接口编程
-
接口隔离原则
接口尽量小,接口要稳定,职责要单一,多个小接口比一个大通用接口要好
22、重载
💧函数重载:在同一个作用域内,可以声明几个功能类似的同名函数,但是这些同名函数的形式参数(指参数的个数、类型或者顺序)必须不同。
class printData
{
public:
void print(int i) {
cout << "整数为: " << i << endl;
}
void print(double f) {
cout << "浮点数为: " << f << endl;
}
void print(char c[]) {
cout << "字符串为: " << c << endl;
}
};
💧运算符重载:重载的运算符是带有特殊名称的函数,函数名是由关键字 operator 和其后要重载的运算符符号构成的。与其他函数一样,重载运算符有一个返回类型和一个参数列表。
// 重载 + 运算符,用于把两个 Box 对象相加
Box operator+(const Box& b)
{
Box box;
box.length = this->length + b.length;
box.breadth = this->breadth + b.breadth;
box.height = this->height + b.height;
return box;
}