目录
函数
声明方式:
返回类型 函数名(参数)
{
函数体:花括号这里也就是函数的定义了
}
int Function(int Param_one, int Param_two)
//(函数开头的int代表函数结束时返回值的类型;Param类似声明变量,只存在于函数内部)
{
int local_variable;
local_variable = Param_one + Param_two;
cout << "The local variable is:" << local_variable << endl;
return local_variable;
//(对应了前面的返回类型int)
}
int main()
{
int Var_in_main = MyFunction(2, 3);
int Another_Var = MyFunction(Var_in_main, 4);
MyFunction(Var_in_main, Another_Var);
//(没有把返回值赋给任何东西,计算机中为返回值保留的内存释放,
//临时值是存在于程序中不会持续的值,它们会消失)(没有打印,没有调用,没有输出)
}
声明和定义可以分开:
程序是从上往下运行的,所以说函数声明必须在main函数之前,让编译器知道有这个函数的存在
但是函数的定义可以在main函数之后
int Function(int Param_one, int Param_two);//注意分号
//声明函数;告诉程序有这个函数存在
//这叫函数原型,不包括函数体(这一行声明函数,另一行定义函数)
int main()
{
int Var_in_main = MyFunction(2, 3);
int Another_Var = MyFunction(Var_in_main, 4);
MyFunction(Var_in_main, Another_Var);
}
int Function(int Param_one, int Param_two)
{
int local_variable;
local_variable = Param_one + Param_two;
cout << "The local variable is:" << local_variable << endl;
return local_variable;
}
main函数
int main()//主函数入口,也是程序的入口,有且只有一个,从这个函数开始执行
//main函数的返回是int类型,但并没有返回int,因为main函数比较特殊,
//它不一定需要返回值,如果不返回值的话,会默认返回了0 等同于return 0;
//这个只对main函数适用,是一种特殊情况
{
/*花括号范围内的任何内容都是为该块定义的,从花括号开始到结束
被称为一个块,块内部是一个局部作用域*/
/*这个块中声明一个变量,存在于该块的作用域,这个块是main函数
的函数体,main函数之外的地方引用这个变量不被识别*/
int aaa = 0;
{//作用域 === 内部块可以访问外部块,外部不能访问内部
//花括号为作用域,范围内的任何内容都是为该模块定义的,在块内部是一个局部作用域
//内部声明外部同名变量会覆盖掉
int aaa = 1;//只用于该作用域,外部不可识别获取输出
//这里在外部输出aaa的值为1;因为改变了覆盖了内存中的值,结果是会保留的
}
}
函数的重载与重写
重载:
//改变了输入参数的数据类型,那么就是成功重载了函数
//如果唯一改变的是返回值类型,那么不足以认为是重载
//重载必须与你正在重载的函数有相同的函数名
void print(string str);
void print(int i);
void print(string str1, string str2);
void print(int i, string str);
//相同的函数类型,相同的函数名,才是重载
//重载数量无限制,主要改变输入参数类型数量等等以及函数内容
//cout就相当于重载,可以输出不同类型的参数以及值
重写:只有函数体不一样叫做重写,也就是只有函数定义不一样
重构
含义:把所有函数封装成一个描述性函数,使代码更整洁
void welcome();
char getYesorNo();
void printanswer(char aar);
void answerYesorNo();
int main()
{
answerYesorNo();//描述性函数,重构
}
void welcome()
{
std::cout << "welcome!" << std::endl;
}
char getYesorNo() {
std::cout << "Please answer'y'or'n':" << std::endl;
char getchar;
std::cin >> getchar;
return getchar;
}
void printanswer(char aar) {
std::cout << "Your answer was " << aar << std::endl;
}
void answerYesorNo() { //把所有函数抽象成一个描述性函数,这叫做重构,使代码更整洁
welcome();
char a = getYesorNo();
printanswer(a);
}
引用
引用实际上引用的是内存中的地址
引用符号:&
含义:传递变量本身,在其他地方的修改,会被保留
举一个函数的例子:
void printanswer(char aar);
//传入的参数是传入变量的实例,其变量本身不受影响;
//aar只是一个占位符,是传入变量的实例,当函数执行完会被销毁;不影响原来的值
而想要改变本身的值,就需要用到引用
//创造一个函数它可以接受某种输入值并改变它,在传入参数上这种改动会永久保留,
//也就是当函数完成并结束时控制流恢复到主函数或别的地方
//涉及原始数字或字面值时,不能使用引用
//必须引用已经存在的变量,引用本身并不是新的变量,并不占用内存,没有真正的储存空间
//传入函数的变量其内容是会改变的
void AddOne(int& Num)//接收i本身的引用
{Num++;}
int main(){
int a = 1;
AddOne(a);
cout << a << endl;//输出2,改变原本的i值
//&引用会传入a变量本身,所改变的值会被保留;
}
//const能使引用函数接收原始字面值,但不能改变,因为是作为常量引入的
(R值引用能同时接受字面值和变量)
void CanPassLiferals(const int& Now)//(这里指外部传入参数作为常量在内部函数使用)
{const << New << endl;}
void ChangeStr(const string& str)
{str += "!";}
int main()
{
string myStr = "Druid";
ChangeStr("Druid");
//直接输入字面值,需要const定义
cout << myStr << endl;
int b = 2;
CanPassLiferals(b);
CanPassLiferals(3)//都行
}
结构体
关键词:struct
含义:跟枚举一样,是自定义数据类型,英文单词structure的缩写
结构体是一个包含自己信息的实体,比如变量和函数
可以容纳多个变量和函数的容器
跟类的区别:默认Public
结构体实际大纲:
struct Character
{
string Name:
float Health;
int Level;
float Damage;
void Attack()
{
cout << Name << "does" << Damage << "damage!" << endl;
}
};
//创建数据类型的变量
Character Joe;//是结构体Character的实例
Joe.Name = "Joe";
Joe.Health = 100.f;
Joe.Level = I;
Joe.Damage = 2.5.f;
Joe.Attack();
Character Lisa = { "Lisa",100.f,3,15.f };
Lisa.Attack();
struct LocationVector
{
float x;
float y;
float z;
};
struct Player
{
int Level;
float Health;
float Damage;
float Stamina;
LocationVector Location = { 0.f,0.f,0.f };//结构体的嵌套
void TakeDamage(float dmg){Health -= dmg;}
int GetLevel()
{
if (Level > 10)
{
cout << "Level is greater than 10!\n";
}
return Level;
}
void DisplayLocation()
{
cout << "Location.x =" << Location.x << endl;
cout << "Location.y =" << Location.y << endl;
cout << "Location.z =" << Location.z << endl;
}
};
int main()
{
Player p_1;
p_1.Level = 1;
p_1.Health = 100.f;
p_1.Damage = 10.f;
p_1.Stamina = 20.f;
cout << "p_1 Level=" << p_1.GetLevel() << endl;
p_1.TakeDamage(40.f);
cout << "p_1 takes" << 40.f << "damage!" << endl;
cout << "p_1 Health=" << p_1.Health << endl;
p_1.DisplayLocation();
Player p_2 = { 1,50.f,40.f,35.54f,{35.5f,67.45f,100.003f} };
p_2.DisplayLocation();
}
访问修饰符:
public:公开的
结构体是默认公开的,所以不需要public关键词,也可以访问结构体中的任何内容
private:私有的
类是默认私有的,所以需要用public关键词定义一个公开区域,公开需要被访问,调用或修改的内容
完全限制名称访问:双冒号 :: 指定对象访问,区分不同结构体中相同名称的函数等等
class Creature
{
public:
Creature();
void setName(string name);
string getName();
private:
string Name;
int health;
};
int main()
{
Creature Igor;
Igor.setName("Phong");
cout << Igor.getName() << endl;
system("pause");
}
Creature::Creature()
{
cout << "A creature has been created!" << endl;
}
void Creature::setName(string name)
{
Name = name;
}
string Creature::getName()
{
return Name;
}
//访问修饰符
#include<iostream>
#include<string>
using namespace std;
class Creature
{
public:
Creature();
private:
float health;
};
int main()
{
system("pause");
}
Creature::Creature()
{
cout << "A creature has been created!" << endl;
}
类和对象:面向对象编程语言的关键
关键词:class
含义:可以将类看做是对象的一种蓝图形式
//类似于图纸或者模板(例如建造房屋的蓝图等等设计稿规划图之类的),告诉你如何创建,具体尺寸之类的细节
类与对象的区别:
类就像是对象的蓝图,是设计文档
对象则是实际对象本身
创建一个类,用关键字class,后面跟想要创造类的名称
不是结构体是类,虽然很像,但作用不一样,一个在栈一个在堆
class Dog//一个叫Dog的类
{
string name;
int Age;
float Health;
void bark()//类中的函数被称为方法
{
cout << "Woof!" << endl;
}
};
Dog Spot;//创造一个Dog变量,名叫Spot;
Dog Rex;//可创造无数个Dog变量
类只是对数据和功能组合在一起的一种方法
类定义一种类型,由类类型构成的变量称为对象,新的对象变量称为实例
class Player{
public:
int x, y;
int speed;
void Move(int xa, int ya){//类内定义方法,可以直接拿到类中的变量,代码简洁
x += xa * speed;
y += ya * speed;
}
};
void Move(Player& player, int xa, int ya){//类外定义函数,代码冗杂
player.x += xa * player.speed;
player.y += ya * player.speed;
}
Player player;//为Player类型创建一个新的实例
Move(player,1,-1);
player.Move(1,-1);
//类本质上只是语法糖,使用它组织代码可以更容易维护
//不使用类一样可以解决问题
构造函数
关键词:Constructor
可以设计一个专门初始化类的变量值的函数,那个特定的函数被称为constructor构造函数 constructor具有和类本身相同的函数名称
假设想在类的内部定义一个构造函数如Bark,如果想在类体之外做这件事,就要通过完全限定其名称(函数的名字)来定义它
//Dog();//构造函数的声明,即使构造函数不能返回值,它也不是void型的
//像其他函数一样可以直接在类内部构造函数,也可以通过完全限定其名称在类外部定义它
完全限定访问,类外定义默认值:
class Dog
{
string name;
int age;
float Health;
void Bark(){cout << "Woof!" << endl;}
};
Dog::Bark()//完全限定函数名访问
{cout << "Woof!" << endl;}
Dog::Dog()//定义类的默认值
{
name = "Spot";
age = 2;
}
类内部定义构造函数:
class Dog
{
public:
//在类中指定一个公共区域 public是访问修饰符
//类的数据类型默认为private,结构体的数据类型默认为public
Dog()//若想在dog被创建时自动调用,为此可以创建一个构造函数
//通常都会使用构造函数将变量初始化为默认值
{
Bark(); //可以从构造函数中调用函数,然后,当声明一个Dog类型的变量时
//Dog的实例会被创造,它的构造函数会被自动调用,这个函数就会运行
Name = "Default Name";
Age = 10;
Health = 100.f;
}//相当于定义默认值列表
string Name;
int Age;
float Health;
void Bark(){cout << "Woof!" << endl;}
};
int main()
{
Dog Dog;
Dog.Bark();//访问类内部的函数,必须保证这些变量和函数是public的,才能在外面访问
cout << Dog.Name << endl;
cout << Dog.Age << endl;
cout << Dog.Health << endl;
system("pause");
}
类外定义构造函数:唯一不需要返回类型的函数
class Dog
{
public:
Dog();
string Name;
int Age;
float Health;
void Bark();
};
int main()
{
Dog dog;
dog.Bark();
cout << dog.Name << endl;
cout << dog.Age << endl;
cout << dog.Health << endl;
system("pause");
}
Dog::Dog()//通过限定函数名在外部定义构造函数
{
Bark();
Name = "Default name";
Age = 10;
Health = 100.f;
}
void Dog::Bark()//可通过限定函数名 类里面的函数定义
//限定函数名需要写出其他函数的返回类型,除了构造函数不用
//双冒号::完全限定名字也被称为作用域运算符或者作用域解析操作符
{
cout << "woof!" << endl;
}
结构体中的构造函数:结构体外定义构造函数跟类是一样的
struct Cat//结构体像类一样可以有构造函数
{
Cat();
int age;
float Health;
void Meow();
};
Cat::Cat()
{
cout << "A new cat is born!" << endl;
age = 3;
Health = 75.f;
Meow();
}
void Cat::Meow()
{
cout << "My age is:" << age << ",\n";
cout << "My Health is:" << Health << "\n";
}
int main()
{
Cat cat;
system("pause");
}
继承
面向对象的优点之一
//在面向对象的编程中,可以为父类创建一个子类
//父类也叫基类 //子类也叫派生类
class Creature//父类也叫基类
{
string type;
int eyes;
};
class Spider :public Creature//子类,意味着Spider继承了Creature 也叫派生类
//Spider自动继承Creature所有属性
//现在构造函数不仅可以初始化Spider的变量,还能初始化继承来的变量,eyes,type
{
float PoisonDamage; //定义Spider自己的变量
Spider()
{
PoisonDamage = 100.f;
eyes = 8;
type = "Arachnid";
}
};
class Goblin :pubilc Creature//从Creature派生出另一个子类
{
Goblin()
{
eyes = 2;
type = "Humanoid";
}
};
构造函数重载
class Animal
{
public:
Animal();
Animal(string name, int age, int num_limbs);//构造函数的重载
string Name;
int Age;
int NumberOfLimbs;
void Report();
};
class Dog :public Animal//Animal的子类,Dog的数据类型默认仍然是private,要访问还是要再加public
{
public:
Dog();
Dog(string name, int age, int num_limbs);
void Speak();
};
int main()
{
Animal animal;
animal.Report();
Animal animal_2("Cheetah", 7, 5);//调用重载函数,只调用一个,不是两个构造函数都调用
animal_2.Report();
Dog dog;
Dog dog("Sport", 4, 5);
dog.Speak();
system("pause");
}
Animal::Animal()
{
cout << " AN ANIMAL is born!\n";
Name = "DEFAULT";
Age = 2;
NumberOfLimbs = 4;
}
Animal::Animal(string name, int age, int num_limbs)
{
Name = name;
Age = age;
NumberOfLimbs = num_limbs;
}
另一种办法,初始化列表,与上个初始化等价
Animal::Animal(string name, int age, int num_limbs)
:Name(name), Age(age), NumberOfLimbs(numeric_limits)
{
}
void Animal::Report()
{
cout << endl;
cout << "Name:" << Name << endl;
cout << "Age:" << Age << endl;
cout << "NumberOfLimbs:" << NumberOfLimbs << endl;
cout << endl;
}
Dog::Dog(){cout << "A DOG IS BORN\n";}
Dog::Dog(string name, int age, int num_limbs)//默认情况下,基本不接受输入参数的父构造函数将被调用;
{
Animal(name, age, num_limbs);//总共调用了三个构造函数Dog(string name, int age, int num_limbs),Animal(),Animal(name, age, num_limbs)
}
若不想调用零个参数的父构造函数,只调用想要的构造函数,则:
Dog::Dog(string name, int age, int num_limbs) : Animal(name, age, num_limbs){}
void Dog::Speak(){cout << "Woof!\n";}
指针
指针本质上只是一串整数,这串整数也就是内存地址
大白话来说就像是自己的家庭住址,就像点外卖,需要地址一样
内存地址:通常以16进制格式存储(不需要过分关注)
而指针就是地址,每个变量都有自己的地址,地址可用于访问该内存并读取内容
一个指针只是一个地址,是一个在内存中保存地址的整数
它不需要类型,指针本身也是变量,这些变量也储存在内存中
// 如果给了指针一个类型,只是说明这个地址的数据被假设为我们给的类型,除此之外没有任何意义 // 只是一些在实际的源代码可以编写的东西,使我们的生活在语法层面上更容易理解
为了让自己更轻松,可以使用指针类型,但是类型不会改变一个指针的实质(内存地址的实质)
void* ptr = 0;//0实际上不是一个有效的内存地址,内存地址不会一直到0,0是无效的,意味着这个指针是无效的
void* ptr = NULL;//也可以写成NULL;
void* ptr = nullptr;//还可以用C++关键字nullptr;
void类型指针:意味着我们只想保存一个地址,并不关心代码中这个指针是什么类型
NULL:实际上是一个#define 0;和0是一样的;
define:是替换关键词,可以理解成赋值只是中间少了赋值运算符(等于号);
无效指针(空指针)是完全可以接受的状态,但我们不能从内存地址0中读取或写入,程序会崩溃,所以0意味着没有
使用指针的目的:使用变量的地址而不是变量本身是非常有效的
//例如:当传入一些输入来调用函数时,有时输入参数可能非常大
(如结构体,多个变量和函数的容器,会占用很多字节的储存空间)
//把结构体作为输入参数时,会复制整个结构体并使用它来初始化输入参数
(即为该函数创建的占位符)
//该结构体的每一个元素(如每个变量,每个函数)
都会一一复制到函数的临时局部结构体中(临时局部空间)
//如果结构体非常大,创建的是一个非常大的东西的副本,在内存中传递大的对象是非常低效的 //如果把结构的地址直接传递给函数,而不是结构体本身
(实际中所做的只是传递一个数字,这个数字告诉其他人这个结构体在哪)
//然后指针使函数可以直接访问那块内存,看看想要的是否只是结构体的一个成员变量或者成员函数,使运行更高效
声明指针:指针可以不必初始化
int MyInt=2;
int* ptr;//指向int型的指针,指针不必初始化
这里声明了一个int*型的变量,这是指向int类型的指针
但是它类型不是int:
int类型的变量是一个整数
int*类型是指向int的指针
(就算是指向float的指针,也不会改变指针的本质):它还是一串整数,一个地址而已
另一个便于理解的方式:它是一个额外的变量,或者说有点像排序里面的temp变量
void* ptr = &MyInt;//指针仅仅只是地址,但空指针不能读取写入,因为编译器不知道那是什么
//如果double* ptr = &MyInt; 编译器还会发出警告,不允许这样
但是可以像变量的转换操作一样:
doule* ptr = (double*)&MyInt;
//所以指针跟变量是一样的,仅仅只是地址,一串整数,只是指向内存中的一个位置
类型无关紧要,对指针类型的定义不会影响到变量的内存
但类型对该内存的操作很有用,如果需要对其进行读写,类型可以起到帮助
编译器也需要知道它需要多少字节的数据,所以类型就起到了作用
//这里就是我们告诉编译器,MyInt是整数,所以指针指向Int类型,需要4个字节
//这里我们告诉编译器的就是这个指针指向的内存是4个字节的内存
ptr = &MyInt;//因为ptr是指向int类型的指针,所以只能使用某个int类型变量的地址初始化
cout << ptr << endl;
//结果为0x61ff14(地址)
//地址是存储MyInt的内存的第一个字节的地址
MyInt的地址可以用取地址运算符&得到
//引用符号与取地址运算符都是&,这是不同的
//引用是另一个变量的别名,引用的是相同的内存位置
//但是取地址运算符放在一些变量前面是取地址的作用,是一个十六进制数,所做的是获得这个数并赋予指针
//所以指针只是一个数
//不需要关心地址的数字是多少,没有任何作用
//需要的是通过指针访问内容,可以通过指针解引用来实现
指针的解引用:通过跟随存储在指针中的地址来访问内容
// *ptr(指针的解引)(*号后面跟着指针名字)
// 逆向引用那个指针,意味着正在访问可以读取或写入的数据
(解引用的结果就是指针指向的内存地址的内容)
//ptr在这里本身就是指针地址,*号对其进行解引用会得到实际值
int MyInt = 2;
int* ptr = &MyInt;
cout << *MyInt << endl;
cout << *ptr << endl;//*号对其进行解引用会得到实际值
//将得到的是MyInt里存储的值
//输出2
//所以指针本身就是一个地址
指针本质上是保存其他变量地址的变量
#include<iostream>
int main()
{
int a = 100;
int* aPtr;
aPtr = &a;//取a的地址
std::cout << *aPtr << std::endl;//*解引用,输出100
int numbers[] = { 0,1,2,3,4,5,6,7,8,9,10 };
int* Numptr = numbers;//指针存储的是第一个元素的地址,数组的每个元素在内存里是连续的
std::cout << *Numptr << std::endl;//输出0;
*Numptr++;//指针运算,自增运算符是将指针从当前数组元素移到下一个元素
std::cout << *Numptr << std::endl;//输出1;
//指针指向数组就是指向数组首元素
system("pause");
}
#include<iostream>
#include<string>
using namespace std;
struct Container
{
string Name;
int x;
int y;
int z;
};
int main()
{
Container container = { "Sam",5,6,7 };//先创建结构体的实例
Container* PtrToCont = &container;//创建结构体(是一种类型)指针,Container类型的指针
cout << (*PtrToCont).Name << endl;//访问其中内容,要在解引用指针周围加圆括号(因为是从右往左工作,但
//但PtrToCont是个指针名,不是结构体,所以要先*解引),使用点运算符访问它的内容
//解引用*PtrToCont是一个整体,指向结构体的内容本身所以需要点运算符访问其中特定内容
cout << (*PtrToCont).x << endl;
cout << (*PtrToCont).y << endl;
cout << (*PtrToCont).z << endl;
//糖语法,等价,更易阅读书写 == (*PtrToCont).x
cout << PtrToCont->Name << endl;//箭头已包含解引,给访问权限
cout << PtrToCont->x << endl;//箭头记号可以访问任何由指针指向的对象内容
cout << PtrToCont->y << endl;
cout << PtrToCont->z << endl;
system("pause");
}
使用.访问指针变量中的某个对象内容
通常会用另一种写法 ->
例如:PtrToCont->Name 等价于 (*PtrToCont).Name
引用与指针的另外理解
//传入函数的变量其内容是会改变的
void AddOne(int& Num)//接收i本身的引用
{Num++;}
int main(){
int a = 1;
AddOne(a);
cout << a << endl;//输出2,改变原本的i值
//&引用会传入a变量本身,所改变的值会被保留;
}
指针的做法,引用其实是指针的扩展,更像是语法糖,能使代码简洁
void AddOne(int* Num)//接受一个指向int型的指针,也就是内存地址
{(*Num)++;}
int a = 1;
AddOne(&a);//传入a的内存地址,直接修改内存中的数据
cout << a << endl;
//改变引用的对象的方法可以使用指针
int a = 1;
int b = 2;
int& ref = a;
ref = b;//这里是对ref引用的a进行赋值为b了所以都等于2;
int* ref = &a;
*ref = 2;
ref = &b;
*ref = 1;
//这是指针的用法,改变指向对象,输出为2,1
int& ref_a = a;//ref_a指向的是a的内存,引用的是同一个地址
//创建引用必须要使用变量初始化,同时也是引用该变量的内存,相当于该变量的别名或者同义词
ref_a++;
cout << a << endl;//ref_a = a,so now a was ref_a++;output 2;
//因为指向同一个内存地址,所以改变任何一个值,都会发生改变,所以输出都是2;
静态变量
关键词:static
类或结构体外面的static:
意味着声明为static的符号,链接将只是在内部
意味着只能对定义它的翻译单元可见(cpp文件),有点类似于类中的private
这说明在其他的cpp文件中将找不到这个static声明的符号
它只会在它被声明的C++文件中被"看到"
尽量多使用static,否则将会默认是全局变量,会被链接器链接
类或结构体内部的静态变量static:
类中的static在几乎所有的面向对象的语言中,静态意味着特定的东西
意味着该变量实际上将与类的所有实例共享内存
在类中创建的所有实例中,静态变量只有一个实例;(类似于所有实例引用一个地址?)
静态方法不能访问或调用非静态变量,因为静态方法没有类实例
实际上类中的每一个非静态方法都是获得当前类的一个实例作为参数
所以类中的静态方法其实跟类外函数一样,找不到类中的变量
struct Entity{
static int x,y;
static void Print()
std::cout << x << "," << y << std::enl;
}
//定义静态变量:先写作用域Entity,再写变量名
int Entity::x;
int Entity::y;
//静态变量在类的所有实例中只有一个实例
int mian(){
Entity e;
e.x = 2;
e.y = 3;
Entity e1 = {5,8};//如果变量是static就会初始化失败,因为x和y不再是类成员
//应该写成:
e.x = 5;
e.y = 8;//这里编译出错,因为实际上需要在某个地方定义那些静态变量
Entity::x = 5;
Entity::y = 8;//可以这样引用它们,就像它们在这个作用域内
//这就像在名为Entity的命名空间中创建了两个变量,实际上并不属于类
//当然从这个意义上说,可以是private,也可以是public的,仍然是类的一部分,而不是命名空间
//无论出于何种目的,其实和在命名空间中是一样的
e.Print();
e1.Print();
}
局部作用域中的静态:local static
声明变量需要考虑的两种情况:变量的生存期(变量实际存在的时间)和变量的作用域(可以访问变量的范围)
函数内定义的变量就是相当于函数的局部变量,函数外不可调用
局部静态变量的生存期基本上相当于整个程序的生存期,但作用范围被限制在作用域内
void Function(){
static int i = 0;
i++;
cout << i << endl;
}
int main(){
Function();
Function();
Function();
}
类似于外部定义全局变量,但是作用域限制在函数内:
int i = 0;//全局变量
void Function(){
i++;
cout << i << endl;
}
int main(){
Function();
Function();
Function();
}
输出都是1,2,3;
类似的事情也适用于类中的静态方法