C++ Tutorial
1.基础语法
C++ 应用:操作系统、图形用户界面和嵌入式系统
C和C++区别:C++支持类和对象
C++语法
#include <iostream>
using namespace std;int main(){cout << "hello world!";return 0;
}int main () { cout << "Hello World! "; return 0; }
Line1:#include <iostream>
是一个头文件库,可让我们使用输入和输出对象,例如 cout,头文件向 C++ 程序添加函数
Line2:using namespace std;
意味着可以使用标准库中的对象和变量的名称
Line3:空行,C++中空行不影响
Line4:int main()
总是会出现在C++程序中,称为function
,大括号 {} 内的任何代码都将被执行
Line5:cout
是与运算符 (<<
) 一起使用来输出文本的对象。注意:每个C++语句都以分号;
结束
Line6:return 0
结束主函数
#include <iostream>int main(){std::cout << "hello world!";return 0;
}
using namespace std;
也可以用std::代替
C++输出
cout
对象,与运算符 (<<
) 一起使用来输出文本或值
可以一次性输出多行,但是C++不会自动分行
#include <iostream>
using namespace std;int main(){cout << "hello world!";cout << "learning everyday";return 0;
}
hello world!learning everyday
如果要分行,有两种方式:
- 插入转义序列
\n
:相当于回车 - 使用
endl
操纵器
cout << "hello world!\n";
cout << "hello world!" << endl;
hello world!
learning everyday
C++注释
单行注释://
多行注释:/*
和*/
#include <iostream>
using namespace std;int main(){// single linecout << "hello world!" << endl;/* multipleline */cout << "learning everyday";return 0;
}
C++变量
int
:整型double
:浮点型char
:字符string
:字符串bool
:布尔
创建变量
type variableName = value;int x = 5;
int y = 7;
int myAge = x + y;
string text = " years";
cout << "I am " << myAge << text << " old";
可以一行创建多个变量
int x = 5, y = 4, z = 6;
可以一行赋值多个变量相同的值
int x, y, z;
x = y = z = 5;
固定变量的值使用const
const int x = 5;
C++输入
cin
与运算符>>
一起用来读取输入
cin >> x;
C++数据类型
float
和double
的区别:float小数点后面最多6-7个数字,而double
可以有15个数字,使用double
计算更安全
浮点数可以用科学计数法,使用e
表示
float f1 = 35e3;
bool
类型只能赋值false
和true
bool learning = true;
单一字符可以用ASCII码表示
char a = 65;
cout << a;
A
创建string
时头文件要导入#include <string>
C++运算符
算术运算符
分配运算符
比较运算符
逻辑运算符
C++ 字符串
- 字符串连接:
+
或者append()
string firstName = "Zoey ";
string lastName = "Doe";
string fullName = firstName.append(lastName);
string fullName = firstName + " " + lastName;
- 字符串长度:
length()
或者size()
string text = "learning everyday";
cout << text.length();
17
- 字符串读取:
[]
string text = "learning";
cout << text[2];
a
- 特殊字符串:字符串有双引号,因此文本中有一些特殊字符无法识别,需要专义字符
string text = "living like a \"tree\"";
cout << text;
living like a "tree"
- 输入字符串
cin输入字符串文本时默认以空格为结束符,因此只会读取第一个单词
string text;
cin >> text;
cout << text;
living like a tree
living
如果要读取一行,使用getline()
string text;
getline(cin, text);
cout << text;
living like a tree
living like a tree
C++数学
头文件#include "cmath"
,常见max
,min
,abs
C++条件语句
if else
语句
int main(){int time = 22;if (time < 10){cout << "morning";}else if (time < 20){cout << "day";}else{cout << "evening";}
}
用一句话描述if else
语句
variable = (condition) ? expressionTrue : expressionFalse;
result = (time < 18) ? "Good day" : "Good evening";
switch
语句
expression
和x
的值比较,如果匹配就执行后面的代码,如果所有情况都不匹配,就执行default
switch(expression) {case x:// code blockbreak;case y:// code blockbreak;default:// code block
}
int main(){int day = 2;switch (day) {case 1:cout << "Monday";break;case 2:cout << "Tuesday";break;default:cout << "Weekend";break;}
}
while
循环
包括while
和do while
while (condition) {// code
}
do {// code
}
while (condition);
int main(){int index = 0;do{cout << index;index++;}while (index < 4);
}
for
循环
for (statement 1; statement 2; statement 3) {// code
}- statement 1:初始值- statement 2:执行条件- statement 3:执行语句
break
和continue
break
结束当前循环,continue
结束当前轮次
int main(){for (int index=0; index < 10; index++){if (index % 2 == 0){continue;}cout << index;}
}
C++数组
- 数组初始化:指定类型,数组名,
[]
为数组长度,可以不指定,赋值用{}
,可以后面再赋值
string cars[4] = {"Volvo", "BMW", "Ford", "Mazda"};
- 数组循环:使用for循环
C++中还有一个for-each
循环,可以更方便的遍历数组
string cars[5] = {"Volvo", "BMW", "Ford", "Mazda", "Tesla"};
for (int i = 0; i < 5; i++) {cout << i << " = " << cars[i] << "\n";
}string numbers[4] = {"a", "b", "c", "d"};for (string i: numbers){cout << i << endl;}
- 数组长度
sizeof()
输出数组字节长度,因此是4*4=16,要得到长度还需要除int
型的字节数
int numbers[4] = {20, 30, 40, 50};
cout << sizeof(numbers) / sizeof(int);
- 多维数组
string letters[2][4] = {{ "A", "B", "C", "D" },{ "E", "F", "G", "H" }
};
C++结构体
将多个相关的变量放在一起组成结构体
struct StructureName{ // 声明结构体,结构体命名可以省略int myNum; // 结构体成员string myString; // 结构体成员
}myStruct1, myStruct2, myStruct3; // 结构体变量
创建结构体变量可以通过结构体命名,也可以直接在后面创建
int main(){struct car{string brand;int price;}myCar1;car myCar2;myCar2.brand = "Ford";myCar1.price = 1000;cout << myCar1.price << endl;
}
1000
C++指针
- 引用变量reference variable:用来指向某个变量,创建时使用
&
运算符
int main(){string food = "Pizza";string &meal = food;cout << food << endl;cout << meal << endl;meal = "Coco";cout << food << endl;
}output:
Pizza
Pizza
Coco
创建引用变量meal是使用&meal
,代表引用于food变量,因此输出是相同的。如果修改了meal的值,food的值也会变化
&
运算符也可以用来获取变量物理地址
int main(){string food = "Pizza";cout << &food << endl;
}output:
0x16fdff118
- 指针变量pointer variable:将物理地址存储为值,使用
*
运算符
int main(){string food = "Pizza";string* ptr = &food;cout << food << endl;cout << &food << endl;cout << ptr << endl;cout << *ptr << endl;
}output:
Pizza
0x16fdff118
0x16fdff118
Pizza
ptr
指针变量存储food的物理地址,此处的&
是取址符,food物理地址是0x16fdff118,因此&food和ptr都是0x16fdff118,*ptr
是用来dereference,输出ptr指针指向的变量取值,也就是food的值。*
运算符有两个作用
- 声明一个指针变量
- dereference操作符
如果修改了指针变量的值,原始变量的值也会变化
*ptr = "Hamburger";
cout << *ptr << endl;
cout << food << endl;output:
Hamburger
Hamburger
2.函数
创建函数
void myFunction() { // 声明// code to be executed (定义)
}- void:函数返回类型- myFunction():函数名
自定义函数创建时可以只声明不定义,但是声明一定要在main函数前
void myFunction();int main(){myFunction();
}void myFunction(){cout << "hello";
}
函数参数
函数传入参数时要定义类型,可以一次性传入多个参数,可以设置默认值,也可以传入数组
#include "iostream"
using namespace std;void myFunction(string name, int age, int cars[3]){cout << name << " is " << age << " years old" << endl;for (int i = 0; i < 3; i++){cout << cars[i] << endl;}
}int main(){int age = 10;int cars[3] = {20, 30, 40};string name = "zoey";myFunction(name, age, cars);return 0;
}
zoey is 10 years old
20
30
40
函数参数也可以传入引用变量,需要修改变量值时比较有用,下面例子用来交换first
和second
的值,swap
函数传入的是引用变量,first=&x
,因此x
的值变成y
之后,first
的值也变成了sceond
,如果传入的不是&x
而是x
,函数内部的变化是不会影响到参数的。
void swap(int &x, int &y){int z = x;x = y;y = z;
}int main(){int first = 2;int second = 3;swap(first, second);cout << first << endl;cout << second << endl;
}
- 函数重载:只要参数的数量和/或类型不同,多个函数就可以具有相同的名称
int plusFunc(int x, int y) {return x + y;
}double plusFunc(double x, double y) {return x + y;
}
- 函数回溯:递归,函数中再调用自身
int sum(int k) {if (k > 0) {return k + sum(k - 1);} else {return 0;}
}int main() {int result = sum(10);cout << result;return 0;
}
3.面向对象编程
创建类和对象
类class是自定义的一种数据类型,比如汽车,对象object是类的某个实例,比如丰田,每个类都有属性attributes和方法methods
class MyClass { // The classpublic: // Access specifierint myNum; // Attribute (int variable)string myString; // Attribute (string variable)
};- class用来创建一个类,命名为MyClass- public是一个访问说明符access specifier,它指定可以从类外部访问该类的成员(属性和方法)- 类属性有两个:整型变量myNum和字符变量myString
创建对象直接使用类名,然后通过.
引用属性为其赋值
class MyClass{
public:int age;string name;
};int main(){MyClass obj;obj.age = 12;obj.name = "zoey";cout << obj.name << endl;
}output:
zoey
类方法
方法就是属于这个类的函数,有两种定义方式
- 类内部定义
class MyClass{
public:void myMethod(){cout << "hello";}
};
- 类外部定义:使用
::
操作符
class MyClass{
public:void myMethod();
};void MyClass::myMethod(){cout << "hello";
}
构造函数Constructor
C++中的构造函数是一种特殊的方法,在创建类的对象时会自动调用它。创建构造函数,要使用与类相同的名称,后跟括号 ()
。构造函数主要作用是在对象创建时执行必要的初始化操作。构造函数中传入参数可以用来为属性赋初始值。
class Car{
public:string brand; //属性int year; //属性Car(string x, int y){ // 构造函数声明brand = x;year = y;}
};int main(){Car obj("Ford", 20); //创建对象时可以直接传入参数cout << obj.brand << endl;cout << obj.year << endl;
}
构造函数也可以在类外部定义,和方法定义一样
class Car{
public:string brand;int year;Car(string x, int y);
};Car::Car(string x, int y){brand = x;year = y;
}
访问说明符Access Specifiers
C++中有三种访问说明符:
public
:可以从类外部访问成员,能赋值或者修改值private
:无法从类外部访问(或查看)成员protected
:不能从类外部访问成员,但是可以在继承类中访问它们
class Car{
public:int year;
private:int age;
};int main(){Car obj;obj.year = 12;obj.age = 20;
}output:
'age' is a private member of 'Car'
默认情况下,如果不指定访问说明符,类的所有成员都是私有的
封装Encapsulation
封装是为了确保“敏感”数据对用户隐藏。 为此须将类变量/属性声明为私有(无法从类外部访问)。 如果希望其他人读取或修改私有成员的值,可以提供公共的 get
和 set
方法
#include "iostream"
using namespace std;class Employee{
private:int salary; // 私有属性
public:void setSalary(int s){salary = s;}int getSalary(){return salary;};
};int main(){Employee obj;obj.setSalary(2000);cout << obj.getSalary() << endl;
}output:
2000
salary
是私有属性,但是可以通过公有方法setSalary
和getSalary
设置和获取salary的值。这种方式能更好的控制代码,只需要修改一部分,增加数据的安全性。
继承Inheritance
C++中可以将属性和方法从一个类继承到另一个类,继承有两个概念:
- 派生类:从另一个类继承的类
- 基类:继承自的类
从一个类继承需要使用:
符号
- 继承可以多层
class Myclass{ //基类
public:void fucntion(){cout << "day" << endl;}
};class Mychild: public Myclass{ //继承类
};class MyGrandchild: public Mychild{ //继承类
};int main(){MyGrandchild obj;obj.fucntion();
}
- 可以继承自多个类
class Class1{
public:void fucntion1(){cout << "day" << endl;}
};class Class2{
public:void function2(){cout << "hello" << endl;}
};class ClassChild: public Class1, public Class2{
};int main(){ClassChild obj;obj.fucntion1();obj.function2();
}
- 访问说明符
proteced
:继承类可以访问
class Employee{
protected:int salary;
};class Programmer: public Employee{
public:int bonus;int get(){return salary;}void set(int s){salary = s;}
};int main(){Programmer obj;obj.set(1000);obj.bonus = 1200;cout << obj.get() << endl;
}
多态Polymorphism
多态意味着“多种形式”,当我们有许多通过继承相互关联的类时,就会发生这种情况。例如,考虑一个名为 Animal 的基类,它有一个名为 AnimalSound() 的方法。 动物的派生类可以是猪、猫等,而且它们也有自己的动物声音方法
#include "iostream"
using namespace std;class Animal{
public:void animalSound(){cout << "the animal make a sound \n";}
};class Pig: public Animal{
public:void animalSound(){cout << "the pig says:wee" << endl;}
};class Dog: public Animal{
public:void animalSound(){cout << "the dog says:wow " << endl;}
};int main(){Animal a;Pig b;Dog c;a.animalSound();b.animalSound();c.animalSound();
}
the animal make a sound
the pig says:wee
the dog says:wow
C++文件
#include <fstream>
fstream
库用于处理文件,有三个类
ofstream
:创建和写文件ifstream
:读取文件fstream
:创建,写,读取文件
#include <iostream>
#include <fstream>
using namespace std;int main() {//创建空白文件ofstream MyFile("filename.txt");// 写文件MyFile << "Files can be tricky, but it is fun enough!";// 关闭文件MyFile.close();
}
异常处理
C++ 中的异常处理由三个关键字组成:try
、throw
和 catch
try {// 尝试的代码块throw exception; // 错误发生时显示异常
}
catch () {// 处理错误的代码块
}
int main(){try{int age = 15;if (age > 18){cout << "Access granted" << endl;}else{throw (age);}}catch (int number){cout << "Access denied" << endl;cout << "you are " << number << endl;}
}
Access denied
you are 15
由于age<18
,因此报错,错误类型定义为age
,输入到catch
作为参数传入,如果不知道错误类型,可以直接使用catch (...)