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 line
cout << "hello world!" << endl;
/* multiple
line */
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 block
break;
case y:
// code block
break;
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 class
public: // Access specifier
int 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 (...)