c++学习笔记

1、helloworld

#include <iostream>

int main()
{
	std::cout << "Hello World!" << std::endl;// 以std::cout<<开始  以<< std::endl结束,中间打印出来。
	//std是标准的意思c-out,读作standard-c-out
	return 0;
}

2、输出加减乘和空格

#include <iostream>
using namespace std;
int main()
{
	int x = 9;
	int y = 6;
	cout << endl;
	cout<<x-y<<" "<<x*y<<x+y;//3, ,54,15
	cout<<endl;
	return 0;
}

3、预处理器编译指令#include

预处理器编译指令是向预处理器发出的命令,总是以#打头。#include<filename>是让预处理器获取指定文件,并将它放在编译指令所在的位置。iostream是一个标准的头文件,这里包含他是因为使用了std::cout将文字打印到屏幕上,而改头文件包含了std::cout的定义。

专业人员编写的c++应用程序中,包含的文件并非都是标准头文件。编写复杂的应用程序时,通常将其代码放在多个文件中,这使得需要在某些文件中包含其他文件。比如

#include "...路径\文件名"

这里使用引号而不是尖括号来包含自己创建的头文件,尖括号(<>)通常用于包含标准头文件。

4、程序主体main()

执行c++程序总是从main开始。声明main()时,总是在它的前面加上int,这是一种标准化约定,表示main()函数的返回类型位int。

在很多c++应用程序中都是用了类似这样的变种:

int main(int argc,char* argv[])

这符合标准且可以接受,因为其返回类型为int。括号内的内容是提供给程序的参数。该程序可能允许用户执行时提供命令行参数,如:

program.exe/DoSomethingSpecific

其中/DoSomethingSpecific是操作系统传递给程序的参数,以便在main中处理。

5、控制台输出

cout,读作c-out,是(conlse-out)的意思,将文字打印到屏幕上。cout是在标准名称空间中定义的一个流,因此这里使用了std::cout。这里使用流插入运算符<<将文本放到这个流中。std::endl用于换行,将其插入流中相当于插入回车。

6、c++流的优点

c++流的优点是,将类是的语义用于另一种类型的流时,将执行不同的操作,如插入到文件而不是控制台。因此流的用法非常直观,使用过一种流后,其他流(比如帮助将文本文件写入磁盘的fstream)使用起来就非常容易。

7、main的返回值

main返回一个整数给操作系统,根据应用程序的性质,这可能很有用,因为大多数操作系统都提供了查询公跟那个,让您能够获悉正常终止的应用程序的返回值。在很多情况下,一个应用程序被另一个应用程序启动,而父应用程序(启动者)想知道子应用程序(被启动者)是否成功地完成了其任务,程序员可以使用main()的返回值向父应用程序传递成功或错误状态。

根据约定,程序员在程序运行成功时返回0,并在出现错误时返回-1。然而,返回值为整数,程序员可以利用整个整数范围,指出众多不同的成功或失败状态。

8、名称空间

使用std::cout而不是cout,原因在于cout位于标准std名称空间中。名称控件有助于降低命名冲突的风险。

std名称空间用来调用获得ISO标准委员会批准,并在该名称空间中声明的函数、流和工具。

为了避免繁琐地在每个函数前面添加名称空间,可以使用声明:

#include <iostream>

int main()
{
	using namespace std;

	cout << "Hello World" << endl;

	return 0;
}

9、std::cin输入(2.6)

#include <iostream>
#include <string>
using namespace std;

int main()
{
	cout<<"Enter an integer:";
	int InputNumber;
	cin>>InputNumber;
	cout<<"Enter your name:";
	string InputName;
	cin>>InputName;

	cout<<InputName<<" entered "<<InputNumber<<endl;

	return 0;
}

10、c++变量类型的长度

#include <iostream>
//short,int,long,long long
//这里的单位是bit,也就是位,一个bit就是一个0或1
//8个bit是一个字节byte
//1个byte可以存一个英文字母,2个byte可以存一个汉字
int main()
{
	using namespace std;
	cout<<"Computing the size of some c++ inbuilt variable types"<<endl;

	cout<<"Size of bool:"<<sizeof(bool)<<endl;//1
	cout<<"Size of char:"<<sizeof(char)<<endl;//1

	cout<<"Size of short int:"<<sizeof(short)<<endl;//2
	cout<<"Size of unsigned short int:"<<sizeof(unsigned short)<<endl;//2

	cout<<"Size of int:"<<sizeof(int)<<endl;//4
	cout<<"Size of unsigned int:"<<sizeof(unsigned int)<<endl;//4
	
	cout<<"Size of long:"<<sizeof(long)<<endl;//4
	cout<<"Size of unsigned long int:"<<sizeof(unsigned long)<<endl;//4
	
	cout<<"Size of long long:"<<sizeof(long long)<<endl;//8
	cout<<"Size of unsigned long long:"<<sizeof(unsigned long long)<<endl;//8

	cout<<"Size of float:"<<sizeof(float)<<endl;//4
	cout<<"Size of double:"<<sizeof(double)<<endl;//8

	cout<<"The output changes with compiler,hardware and OS"<<endl;

	return 0;
}

11、auto,编译器的类型推断功能

#include <iostream>
using namespace std;
//编译的时候要加上"-std=c++11"
int main()
{
	auto Flag=true;
	auto Number=2500000000000;

	cout<<"Flag="<<Flag;
	cout<<",sizeof(Flag)="<<sizeof(Flag)<<endl;
	cout<<"Number="<<Number;
	cout<<",sizeof(Number)="<<sizeof(Number)<<endl;

	return 0;
}

12、常量

这样声明:

const int 常量名 = 1;

13、枚举

enum RainbowColors
{
	Violet = 0;// 可以定义值也可以不定义。如果不定义则会自动从0开始,每个item累加1。也可以对每个item设置值。
	Indigo,
	Blue,
	Green,
	Yellow,
	Orange,
	Red
	
};

14、静态数组

// 静态数组
int MyNumbers[5] = {0};//定义数组,5个元素,每个都为5
char MyCharacters[5];// 定义5个元素的数组但是没有赋值
int MyNumbers[5] = {20,30};// 给前2个赋值
int MyNumbers[] = {1,2,3};// 直接赋值可以不指定长度

15、动态数组

#include <iostream>
#include <vector>

using namespace std;

int main()
{
	vector<int> DynArrNums(3);// 原定义的数组长度为3

	// DynArrNums[0] = 365;// 赋值,即使没有赋值,位置也一直留着
	// DynArrNums[1] = -421;
	// DynArrNums[2] = 789;

	cout<< "Number of integers in array:"<<DynArrNums.size()<<endl;// 数组原长度

	cout<< "Enter another number for the array"<<endl;

	int AnotherNum = 0;
	cin>>AnotherNum;
	DynArrNums.push_back(AnotherNum);

	cout<<"Number of integers in array:"<<DynArrNums.size()<<endl;

	cout<<"Last element in array: ";
	cout<< DynArrNums[DynArrNums.size()-1]<<endl;
	return 0;	
}

16、字符串字面量-c风格字符串

#include <iostream>

int main()
{
	char SayHello[] = {'H','e','l','l','o',' ','W','o','r','l','d','\0'};// \0不能少,否则打印出来也有问题,少了这个,打印会跨越边界,导致程序崩溃
	// std::cout<<"Hello World";// 这两种是等价的,
	std::cout<<SayHello<<std::endl;
	return 0;
}

c风格字符串充斥着危险性。

17、安全的标准c++字符串string

#include <iostream>
#include <string>

using namespace std;

int main()
{
	string Greetings ("Hello std::string!");// 标准c++字符串
	cout << Greetings << endl;// 

	cout << "Enter a line of text: "<< endl;
	string FirstLine;
	getline(cin,FirstLine);// 输入第一行数据

	cout << "Enter another: " << endl;
	string SecLine;
	getline(cin,SecLine);// 输入第二行数据

	cout << "Result of concatenation: " << endl;
	string Concat = FirstLine+" "+SecLine;// 连接第一行和第二行
	cout << Concat << endl;// 输出连接后的字符串

	cout << "Copy of concatenation: " << endl;
	string Copy;
	Copy = Concat;
	cout << Copy << endl;// 输出拷贝的连接后的字符串

	cout << "Length of concat string: "<< Concat.length() << endl;// 统计连接后的字符串长度

	return 0;
}

18、指针和引用

指针是一个变量,这个变量也占内存空间,指针存放的值指向内存地址。指针是一种指向内存单元的特殊变量。

(1)声明指针

通常将指针声明位指向特定的类型,如果int,这意味着指针包含的地址对应的内存单元存储了一个整数。

也可以将指针声明为指向一个内存块,这种指针被成为void指针。

声明:

指针类型 * 指针变量名;

与大多数变量一样,除非对指针进行初始化,否则它包含的值将是随机的。如果不初始化一个值,应该将指针初始化为NULL。

int * pInteger = NULL;

注意:除非对指针进行初始化,否则它包含的将是垃圾值。对指针来说,这种垃圾值是非常危险的,因为指针包含的值被视为地址。未初始化的指针可能导致程序访问非法内存单元,进而导致程序崩溃。

(2)引用运算符

变量,能够让您处理内存中的数据;

指针,存放的是内存的地址,而不是内存中的数据本身;

如果Varname是一个变量,那么&Varname将是存储该变量的内存地址。

比如声明:

int Age = 30;

那么&Age将是存储该变量的值(30)的内存的地址。

#include <iostream>
using namespace std;

int main()
{
	int Age=30;
	const double Pi=3.1416;

	cout<<"Integer Age is at:"<< hex <<&Age<<endl;// Age存放在内存中,地址为:0x28ff20
	cout<<"Double Pi is located at:"<< hex <<&Pi<<endl;// Pi存放在内存中,地址为:0x28ff20
	// cout<<"test age:"<< dec << Age <<endl;//30
	cout<<"test age2:"<< Age << endl;// 30


	return 0;
}

(3)使用指针存储地址

指针这样使用:

先定义变量,再通过&获取变量的内存地址,再赋值给指针。

#include <iostream>
using namespace std;

int main()
{
	int Age=30;// 变量赋值
	int* pInteger=&Age;// 获取变量的指针

	cout<<"Integer Age is at:"<<pInteger<<endl;

	return 0;
}

(4)用解除引用运算符(*)访问指向的数据

#include <iostream>
using namespace std;

int main()
{
	int Age = 30;
	int DogsAge = 9;

	cout<<"Integer Age="<<Age<<endl;
	cout<<"Integer DogsAge="<<DogsAge<<endl;

	int* pInteger = &Age;
	cout<<"pInteger points to Age"<<endl;
	cout<<"pInteger(16)="<<hex<<pInteger<<endl;// 指针的值(内存地址)为0x28ff28
	cout<<"pInteger(10)="<<dec<<pInteger<<endl;// 指针的值(内存地址)为0x28ff28
	cout<<"*pInteger(16)="<<hex<<*pInteger<<endl;// 对内存地址用星号则取出其值(16进制):1e
	cout<<"*pInteger(10)="<<dec<<*pInteger<<endl;// 对内存地址用星号则取出其值(10进制):30

	pInteger=&DogsAge;
	cout<<"pInteger points to DogsAge now"<<endl;// 指针指向狗的年龄
	cout<<"pInteger="<<hex<<pInteger<<endl;// 指针的值0x28ff24
	cout<<"*pInteger="<<dec<<*pInteger<<endl;// 9

	return 0;
}

(5)使用解除引用赋值

#include <iostream>
using namespace std;

int main()
{
	int DogsAge=30;
	cout<<"Initialized DogsAge="<<DogsAge<<endl;

	int* pAge=&DogsAge;// 获得内存地址
	cout<<"pAge points to DogsAge:"<<pAge<<endl;// 显示内存地址(第一次)0x28ff28
	cout<<"Enter an age for your dog:";
	cin>>*pAge;// 注意这上下两行是等价的,即:*pAge与*&DogsAge是等价的,他们都是指向内存相同的地方的值,修改之
	// cin>>*&DogsAge;// 修改内存地址对应的值,输入15

	cout<<"Input stored using pAge at "<<pAge<<endl;// 指针发生变化了没,没有0x28ff28
	cout<<"Integer DogsAge="<<dec<<DogsAge<<endl;// 变量发生变化了没,变量变为输入值15

	return 0;
}

(6)sizeof用于指针

#include <iostream>
using namespace std;

int main()
{
	int Age=30;
	double Pi=3.1416;
	char SayYes='y';

	int* pInt=&Age;
	double* pDouble=&Pi
	char* pChar=&SayYes;

	cout<<"sizeof fundamental types -"<<endl;
	cout<<"sizeof(int)="<<sizeof(int)<<endl;//4
	cout<<"sizeof(double)="<<sizeof(double)<<endl;//8
	cout<<"sizeof(char)="<<sizeof(char)<<endl;//1

	//指针的sizeof与变量类型无关,这是显而易见的,因为这个指向的是地址的头,而不是整个物理地址
	cout<<"sizeof pointers to fundamental types -"<<endl;
	cout<<"sizeof(pInt)="<<sizeof(pInt)<<endl;//4
	cout<<"sizeof(pDouble)="<<sizeof(pDouble)<<endl;//4
	cout<<"sizeof(pChar)="<<sizeof(pChar)<<endl;//4

	return 0;
}
指针的sizeof总是4字节,这是因为不管指针指向的内存单元是1字节还是8字节,存储指针所需的内存量都相同。如果使用32位编译器编译代码得到的,都是4字节;如果使用的是64位的编译器,并在64位系统上运行该程序,可能为8字节。

(7)动态内存分配

int Numbers[100];

此声明有问题,1:无法存储100个以上的元素;2、如果只存了1个数字,却预留了100个数字的存储空间,将降低系统的性能。

因此必须使用动态内存分配才可以提供系统的性能。

(8)使用new和delete动态分配和释放内存

Type * Pointer = new Type;//使用new来分配新的内存块,如果成功,将返回一个指针

需要为多个元素分配内存,还可以指定要为多少个元素分配:

Type * Pointer = new Type[NumElements];//请求为NumElements个元素的分配内存

int * pNumber = new int;// 获得一个整型的指针

int * pNumbers = new int[10];// 获取一个指向10个整型的内存块的指针

使用new分配的内存最终都需要使用对应的delete进行释放:

Type * Pointer = new Type;

delete Pointer;//释放内存

这种规则也适用于为多个元素分配的内存:

Type * Pointer = new Type[NumElements];

delete[] Pointer;//释放整个内存块

#include <iostream>
using namespace std;

int main()
{
	int* pAge=new int;// new一个指针,指针名称为pAge
	cout<<"Enter your dog's age:";
	cin>>*pAge;// 为此指针赋值,10

	cout<<"Age="<<*pAge<<" is stored at "<<hex<<pAge<<endl;// Age的值为10,他的指针是0x5d1580

	delete  pAge;//只能delete new产生的指针,而非所有指针,删除此指针

	cout<<"test Age="<<dec<<*pAge<<" is stored at "<<pAge<<endl;//地址还在但是值已经变了,删了之后,值已经变为6099224,但是指针还是一样0x5d1580

	return 0;
}

(9)拷贝到指针指定的地址里面

#include <iostream>
#include <string>
#include <string.h>
using namespace std;

int main()
{
	cout<<"Enter your name:";
	string Name;
	cin>>Name;//输入一个字符串

	int CharsToAllocate=Name.length()+1;//计算这个字符串的长度并+1
	char* CopyOfName=new char[CharsToAllocate];//创建一个指针,指向一个元素类型为char的内存地址块,并指定了长度为上一步所计算出来的长度
	strcpy(CopyOfName,Name.c_str());// 将字符拷贝放到此地址内
	cout<<"Dynamically allocated buffer contains:"<<CopyOfName<<endl;//buffer就是内存
	delete[] CopyOfName;

	return 0;
}

(10)、通过移动指针赋值,以及通过移动指针读取值

#include <iostream>
using namespace std;

int main()
{
	cout<<"How many integers you wish to enter?";
	int InputNums=0;
	cin>>InputNums;// 输入数字

	int* pNumbers=new int [InputNums];// 初始化一个数组并返回指针
	int* pCopy=pNumbers;// 定义另一个指针并让其等于上面那个指针

	cout<<"Successfully allocated memory for "<<InputNums<<" integers"<<endl;// 成功初始化n个整型
	for(int Index=0;Index<InputNums;++Index)
	{
		cout<<"Enter numbers "<<Index<<":";// 输入的数字序号:n
		cin>>*(pNumbers+Index);//指针在加index,就是在移动内存块的位置
	}
	cout<<"Displaying all numbers input: "<<endl;
	for(int Index=0;Index<InputNums;++Index)
	{
		//cout<<*(pCopy++)<<" ";
		cout<<*(pNumbers++)<<" ";//此处会修改指针,如果不用copy的指针,而直接用那个new的指针,它已经变化,delete也已经不同...
	}
	cout<<endl;
  // 注意指针操作:1、申请时是数组,删除时也是数组;2、申请的地址是a,删除的地址也必须是a,否则内存泄漏,如须移动请用copy
	//delete[] pNumbers;//这个要不要delete都是一样的,因为指针已经被移动。之所以上面要移动指针拷贝,而不用移动这个指针本身,是因为在delete的时候,希望delete的是一个不变的值

	cout<<"after delete:\n";
	cout<<"addr:"<<pNumbers<<"\n";//指针是还存在的,就是说内存地址是存在的,但是内存中并没有值
	cout<<"value:"<<dec<<*pNumbers<<endl;//此时指针指向已经没有值,是0

	return 0;
}

(11)、const用于指针

<1>常量指针:在星号前加const,即不能通过*p修改指针指向的内存的值。

#include <iostream>
using namespace std;

int main()
{
	int HoursInDay = 24;// 定义一个变量
	int const * pInteger = &HoursInDay;// 变量的指针地址,这里最奇怪的是,*pInteger是常量不可修改,但是HoursInDay可以修改

	cout<< pInteger <<endl;// 0x28ff24
	cout<< *pInteger <<endl;// 24

	//________________________第一次修改:修改变量然后看指针指向的值有没有变化____________________
	HoursInDay = 25;

	cout<< pInteger <<endl;// 0x28ff24,指针的地址没有变化
	cout<< *pInteger <<endl;// 25,指针的值是有变化的,就是直接操作*pInteger来修改值是不可以的,但是修改变量是可以的

	//________________________第二次修改:修改指针的指向___________________________
	int MonthsInYear = 12;// 定义另一个变量
	pInteger = &MonthsInYear;// ok,将指针指向另一个地址
	// *pInteger = 13;// 这个赋值不会成功,因为*pInteger是一个常量
	// int * pAnotherPointerToInt = pInteger;// 这个赋值不会成功,因为不能将一个常量指针赋值给变量指针
	//int const * pAnotherPointerToInt = pInteger;// ok

	cout<< pInteger <<endl;// 0x28ff20 地址已经发生了变化
	cout<< *pInteger <<endl;// 12,值也发生变化,但是这个值发生变化是通过修改指向发生的,而非*pInteger直接修改原地址的值
}
<2>指针常量:在星号后加const,不能修改指针地址,即此指针不可以指向别的地址
#include <iostream>
using namespace std;

int main()
{
	int DaysInMonth = 30;
	int * const pDaysInMonth = &DaysInMonth;
	*pDaysInMonth = 30;//ok
	int DaysInLunarMonth = 28;
	pDaysInMonth = &DaysInLunarMonth;// 不可以,此指针常量不可修改指针地址
}
<3>双常量
#include <iostream>
using namespace std;

int main()
{
	int HoursInDay = 24;
	int const * const pHoursInDay = &HoursInDay;

	// *pHoursInDay = 25;// 不可以

	int DaysInMonth = 30;
	// pHoursInDay = &DaysInMonth;// 不可以

	return 0;
}

(12)、指针传递给函数

#include <iostream>
using namespace std;

// void CalcArea(const double * const pPi,//pi指针值和地址都不能改变
// 			  const double * const pRadius,//半径指针值和地址都不能改变
// 			  double * const pArea)//面积指针值可以改变地址不能改变
// {
// 	if (pPi && pRadius && pArea)
// 	{
// 		*pArea = (*pPi) * (*pRadius) * (*pRadius);
// 	}
// }

void CalcArea(double const * pPi,double * pRadius,double * pArea)
{
	if (pPi && pRadius && pArea)// 检查有效性
	{
		*pArea = (*pPi) * (*pRadius) * (*pRadius);
	}
}

int main()
{
	const double Pi = 3.1416;//因为这里是常量,所以他的指针的值不能改(而非指针变量)

	cout << "Enter radius of circle: ";
	double Radius = 0;
	cin >> Radius;

	double Area = 0;
	CalcArea(&Pi, &Radius, &Area);

	cout << "Area is = " << Area << endl;

	return 0;
}

(13)、数组和指针的相似之处

<1>数组的引用可以直接赋值给指针

#include <iostream>
using namespace std;

int main()
{
	int MyNumbers[5];// 可以说这个MyNumbers就是一个指针

	int * pNumbers = MyNumbers;//这个引用他返回了第一个元素的指针地址

	cout << "pNumbers=" << hex << pNumbers << endl;// 0x28ff18
	cout << "&MyNumbers[0]=" << &MyNumbers[0] << endl;// 0x28ff18
}
<2>分别用数组下标和指针访问数组的值
#include <iostream>
using namespace std;

int main()
{
	const int ARRAY_LEN = 5;

	int MyNumbers[ARRAY_LEN]={24,-1,365,-999,2011};

	// int * pNumbers = MyNumbers;

	// cout << "Displaying array using pointer syntax,operator*" << endl;

	// for(int Index = 0; Index < ARRAY_LEN;++Index)
	// 	cout << "Element " << Index << " = " << * (MyNumbers + Index) << endl;

	// cout << "Displaying array using pointer with array syntax,operator[]" << endl;

	// for(int Index = 0; Index < ARRAY_LEN;++Index)
	// 	cout << "Element " << Index << " = " << pNumbers[Index] << endl;





	int * pNumbers = &(MyNumbers[1]);

	cout << "Displaying array using pointer syntax,operator*" << endl;

	for(int Index = 0; Index < ARRAY_LEN-1;++Index)
		cout << "Element " << Index << " = " << * (MyNumbers + Index) << endl;// 24,-1,365,-999

	cout << "Displaying array using pointer with array syntax,operator[]" << endl;

	for(int Index = 0; Index < ARRAY_LEN-1;++Index)
		cout << "Element " << Index << " = " << pNumbers[Index] << endl;// -1,365,-999,2011使用下标取出来就是值

}

(14)、无效指针

#include <iostream>
using namespace std;

int main()
{
	int * pTemperature;// 没有初始化一个指针(这样不好),在这里仅仅是定义,但是没有完成初始化

	cout << "Is it sunny (y/n)?" << endl;
	char UserInput = 'y';
	cin >> UserInput;

	if (UserInput == 'y')
	{
		pTemperature = new int;// 初始化
		*pTemperature = 30;
	}

	cout << "Temperature is: " << *pTemperature;// 如果按的是n,则指针还未初始化,程序崩溃

	delete pTemperature;// 如果一个指针没有new,也是不可以delete的,另外指针多个拷贝只需delete一个,应避免指针有很多拷贝
	return 0;
}

(15)、指针编程最佳实践

<1>务必初始化指针变量,否则它将包含垃圾值。这些垃圾值被解读为地址。如果不能将指针初始化为new返回的有效地址或其他有效变量,可将其初始化为NULL;
<2>使用指针前,务必检查它是否为NULL,这样,如果指针声明后未赋给有效地址,但声明时将其初始化为NULL了,就不会引起无效指针的问题了;
<3>务必仅在指针有效时才使用它,否则程序可能崩溃;
<4>对于使用new分配的内存,一定要记得使用delete进行释放,否则应用程序将泄漏内存,进而降低系统的性能;
<5>使用delete释放内存块或指针后,不要访问它;
<6>不要对同一个内存地址调用delete多次;
<7>使用动态分配的内存块后,不要忘了对其调用delete,以免内存泄漏。

#include <iostream>
using namespace std;

int main()
{
	cout << "Is it sunny(y/n)? ";
	char UserInput = 'y';
	cin >> UserInput;

	if (UserInput == 'y')
	{
		int * pTemperature = new int;
		* pTemperature = 30;
		//____________delete前调用_______________
		cout << "pTemperature is: " << pTemperature << endl;// 0x3f1840
		cout << "Temperature is: " << * pTemperature << endl;// 30

		delete pTemperature;

		//____________delete后调用_______________
		cout << "pTemperature is: " << pTemperature << endl;// 0x3f1840,指针删除后,他包含的这个地址还是在的,但是地址指向的值已经不在,内存已经释放
		cout << "Temperature is: " << * pTemperature << endl;// 4157184,这是一个垃圾值

		delete pTemperature;// 再次调用删除并不会引起什么后果

	}

	return 0;
}

(16)、处理new失败

<1>异常处理

#include <iostream>
using namespace std;

int main()
{
	try
	{
		int * pAge = new int [53687000009101];

		delete [] pAge;
	}
	catch(bad_alloc)
	{
		cout << "Memory allocation failed. Ending program" << endl;
	}

	return 0;
}
<2>用nothrow会返回空指针

#include <iostream>
using namespace std;

int main()
{
	int * pAge = new(nothrow) int[234254350044534];//在mac下还是抛出异常

	if (pAge)
	{
		delete [] pAge;
	}else
	{
		cout << "Memory allocation failed. Ending program" << endl;
	}

	return 0;
}

(17)、引用

<1>引用,就是值类型的变量,通过添加&可以变成引用传递;对引用添加&则可以取到对应的内存地址

#include <iostream>
using namespace std;

int main()
{
	int Original = 30;// 等同于 *pOriginal
	cout << "Original = " << Original << endl;// 30,值
	cout << "Original is at address: " << hex << &Original <<endl;// 0x28ff24,地址,加&相当于给*pOriginal去掉星号

	int & Ref = Original;// 注意这个加了个引用标志,表示此Ref与Original的引用相同,因为int是值类型,如果没这个标志则值相同,但是它变成一个新值,有自己的引用
	// int Ref = Original;
	cout << "Ref is at address: " << hex << &Ref << endl;// 0x28ff24,地址,

	int & Ref2 = Ref;
	cout << "Ref2 is at address: " << hex << &Ref2 << endl;// 0x28ff24,地址
	cout << "Ref2 gets value, Ref2 = " << dec << Ref2 << endl;// 30,值

	return 0;
}
<2>传递引用

传递引用在c#里也有类似的,比如一个局部变量,传递引用至一个函数里,经过一番计算,都不用return一个值回来,这个局部变量可能已经改变,我们使用这个新值即可

引用传递最大的好处是避免形参复制,极大提高性能(传递一个数字过去,在新函数那里会重新自动new那些数字)

#include <iostream>
using namespace std;


void ReturnSquare(int & num)
{
	num *= num;
}

int main()
{
	cout << "Enter a number you wish to square: ";
	int Number = 0;
	cin >> Number;

	ReturnSquare(Number);
	cout << "Square is: " << Number << endl;

	return 0;
}
<3>引用加const

#include <iostream>

int main()
{
	int Original = 30;
	int const & ConstRef = Original;
	ConstRef =40;//not allowed.引用被加上const,则不可被赋值

	int & Ref2 = ConstRef;//not allowed.被加上const的引用不可被赋值给没有加const的新引用
	int const & ConstRef2 = ConstRef;//ok.但是可以被赋值给同样加了const的新引用
}
<4>通过添加const控制传递参数可被修改以及不可被修改

#include <iostream>
using namespace std;

void CalculateSquare(const int & Number,int & Result)
{
	Result = Number * Number;// Number不可被改变,Result可以被改变
}

int main()
{
	cout << "Enter a number you wish to square: ";
	int Number = 0;
	cin >> Number;

	int Square = 0;
	CalculateSquare(Number,Square);
	cout << Number << "^2 = " << Square << endl;

	return 0;
}

19、STL(standard template library)标准模版库

(1)迭代器访问向量数组

#include <iostream>
#include <vector>
#include <algorithm>

using namespace std;

int main()
{
	vector <int> vecIntegerArray;// 定义数组(向量)

	vecIntegerArray.push_back(50);
	vecIntegerArray.push_back(2991);
	vecIntegerArray.push_back(23);
	vecIntegerArray.push_back(9999);

	cout<<"The contents of the vector are:"<<endl;

	// vector <int>::iterator iArrayWalker = vecIntegerArray.begin();// 用迭代器访问
	auto iArrayWalker = vecIntegerArray.begin();// 可以简化为这样

	while(iArrayWalker != vecIntegerArray.end())
	{
		cout<<*iArrayWalker<<endl;
		++iArrayWalker;
	}
}

(2)初始化字符串

#include <iostream>
#include <string>

using namespace std;

int main()
{
	const char * constCStyleString = "Hello String!";// 初始化一个c语言风格的字符串

	std::string strFromConst (constCStyleString);// 这样可以
	//std::string strFromConst = constCStyleString;// 这样也可以

	std::string str2 ("HelloString!");//一句话代替就这样

	// stl string类构造函数自动完成字符串长度的设定和内存分配

	cout<<str2<<endl;
}

#include <string>
#include <iostream>

int main()
{
	using namespace std;

	const char * constCStyleString = "Hello String!";
	cout << "Constant string is: " << constCStyleString << endl;

	std::string strFromConst (constCStyleString);
	cout << "strFromConst is: " << strFromConst << endl;

	std::string str2 ("Hello String!");
	std::string str2Copy (str2);// 从已有的string生成string
	cout << "str2Copy is: " << str2Copy << endl;

	std::string strPartialCopy (constCStyleString,5);// 取前5个字符
	cout << "strPartialCopy is: " << strPartialCopy << endl;

	std::string strRepeatChars (10,'a');// 生成10个重复的a,即"aaaaaaaaaa"
	cout << "strRepeatChars is: " << strRepeatChars << endl;

	return 0;
}

(3)访问字符串

#include <string>
#include <iostream>

int main()
{
	using namespace std;

	string strSTLString("Hello String");
	// 用下标法访问
	cout<<"Displaying the elements in the string using array-syntax:"<<endl;
	for(size_t nCharCounter = 0;nCharCounter<strSTLString.length();++nCharCounter)
	{
		cout<<"Character ["<<nCharCounter<<"] is: ";
		cout<<strSTLString[nCharCounter]<<endl;
	}
	cout<<endl;

	cout<<"Displaying the contents of the string using iterators: "<<endl;
	int charOffset = 0;
	string::const_iterator iCharacterLocator;
	for(iCharacterLocator = strSTLString.begin();iCharacterLocator!=strSTLString.end();++iCharacterLocator)
	{
		cout<<"Character ["<<charOffset++<<"] is:";
		cout<<*iCharacterLocator<<endl;
	}
	cout<<endl;
}

(4)连接字符串

#include <string>
#include <iostream>

int main()
{
	using namespace std;

	string strSample1("Hello");
	string strSample2(" String!");

	strSample1 += strSample2;//用+连接字符串
	cout<<strSample1<<endl<<endl;

	string strSample3(" Fun is not needing to use pointers!");
	strSample1.append(strSample3);// 用append连接字符串
	cout<<strSample1<<endl<<endl;

	const char*constCStyleString = " You however still can!";
	strSample1.append(constCStyleString);// append也可以用于c风格字符串
	cout<<strSample1<<endl;

	return 0;
}

(5)查找字符串

#include <string>
#include <iostream>

int main()
{
	using namespace std;

	string strSample("Good day String! Today is beautiful!");
	cout<<"The sample string is: "<<endl;
	cout<<strSample<<endl<<endl;

	size_t charPos = strSample.find("day",0);

	// 根据返回的值来进行判断,如果是string::npos即-1,没中找到;否则找到
	if (charPos!=string::npos)
		cout<<"First instance of \"day\" was found at position "<<charPos;
	else
		cout<<"Substring not found."<<endl;

	cout<<endl<<endl;

	cout<<"Locating all instances of substring \"day\""<<endl;
	size_t SubstringPos = strSample.find("day",0);

	while(SubstringPos!=string::npos)
	{
		cout<<"\"day\"found at position "<< SubstringPos<<endl;

		// 找到之后再将定位往前移继续寻找
		size_t nSearchPosition = SubstringPos+1;
		SubstringPos = strSample.find("day",nSearchPosition);
	}
	return 0;
}

(6)擦除,删除

#include <string>
#include <algorithm>
#include <iostream>

int main()
{
	using namespace std;

	//擦除,删除
	string strSample("Hello String! Wake up to a beautiful day!");
	cout<<"The Original sample string is: "<<endl;
	cout<<strSample<<endl<<endl;
	cout<<"The Original sample addr is: "<<endl;
	cout<<&strSample<<endl<<endl;//0x28fefc

	cout<<"Truncating the second sentence: "<<endl;
	strSample.erase(0,5);// 删除从a开始删除b个
	cout<<strSample<<endl<<endl;
	cout<<"Truncated the smaple addr is: "<<endl;
	cout<<&strSample<<endl<<endl;//0x28fefc,地址是不变的

	// 擦除指定字符
	string::iterator iCharS = find(strSample.begin(),strSample.end(),'S');

	cout<<"Erasing character 'S' from the sample string: "<<endl;
	if (iCharS!=strSample.end())// 这个即使是最后一个字符也是可以删掉的,因为这里的end指的是\0
		strSample.erase(iCharS);
	
	cout<<strSample<<endl<<endl;

	// 擦除所有
	cout<<"Erasing a range between begtin() and end(): "<<endl;

	strSample.erase(strSample.begin(),strSample.end());

	if (strSample.length()==0)
		cout<<"The string is empty"<<endl;

	return 0;


}

(7)字符串反转

#include <string>
#include <iostream>
#include <algorithm>

int main()
{
	using namespace std;

	string strSample("Hello String! We will reverse you!");
	cout<<"The original sample string is: "<<endl;
	cout<<strSample<<endl<<endl;

	reverse(strSample.begin(),strSample.end());

	cout<<"After applying the std::reverse algorithm: "<<endl;
	cout<<strSample<<endl;

	return 0;
}

(8)转大小写

#include <string>
#include <iostream>
#include <algorithm>

using namespace std;

int main()
{
	

	cout<<"Please enter a string for case-convertion:"<<endl;
	cout<<"> ";
	string strInput;
	getline(cin,strInput);
	cout<<endl;

	transform(strInput.begin(),strInput.end(),strInput.begin(),::toupper);
	cout<<"The string converted to upper case is: "<<endl;
	cout<<strInput<<endl<<endl;

	transform(strInput.begin(),strInput.end(),strInput.begin(),::tolower);
	cout<<"The string converted to lower case is: "<<endl;
	cout<<strInput<<endl<<endl;

	return 0;
}

20、vector

(1)实例化

#include <vector>

int main()
{
	std::vector <int> vecIntegers;// 用默认构造函数实例化

	std::vector <int> vecWithTenElements(10);// 实例化包含10个元素,注意并没有限制最终大小只能为10

	std::vector <int> vecWithTenInitializedElements(10,90);// 

	std::vector <int> vecArrayCopy(vecWithTenInitializedElements);// 复制

	std::vector <int> vecSomeElementsCopied(vecWithTenElements.cbegin(),vecWithTenElements.cbegin()+5);// 复制前5个元素

	return 0;
}

(2)push_back在末尾插入

#include <iostream>
#include <vector>
using namespace std;

int main()
{
	vector <int> vecIntegers;

	// 通过push_back初始化
	vecIntegers.push_back(1);
	vecIntegers.push_back(34);
	vecIntegers.push_back(53);
	vecIntegers.push_back(77);

	// // 直接初始化1
	// vector <int> vecIntegers = {23,45,3,45};

	// 直接初始化2
	// vector <int> vecIntegers{33,56,76,5};


	cout<<"The vector contains ";
	cout<<vecIntegers.size()<<" Elements"<<endl;
	return 0;
}

(3)insert在指定位置插入

#include <vector>
#include <iostream>
using namespace std;

void DisplayVector(const vector<int>& vecInput)
{
	for(auto iElement = vecInput.cbegin();iElement!=vecInput.cend();++iElement)
	{
		cout<<*iElement<<' ';
	}
	cout<<endl;
}

int main()
{
	vector <int> vecIntegers(4,90);//90,90,90,90

	cout<<"The initial contents of the vector: ";
	DisplayVector(vecIntegers);

	vecIntegers.insert(vecIntegers.begin(),25);//在头部插入一个25

	vecIntegers.insert(vecIntegers.end(),2,45);//在尾部插入2个45

	cout<<"Vector after inserting elements at beginning and end: ";
	DisplayVector(vecIntegers);

	vector <int> vecAnother(2,30);//30,30

	vecIntegers.insert(vecIntegers.begin()+1,vecAnother.begin(),vecAnother.end());// 在开头的第2个元素的位置,插入另一个数组的从头到尾所有元素
	cout<<"Vector after inserting contents from another vector: ";
	cout<<"in the middle:"<<endl;
	DisplayVector(vecIntegers);
	
	return 0;
}

(4)访问元素

#include <iostream>
#include <vector>

int main()
{
	using namespace std;

	vector <int> vecIntegerArray;

	vecIntegerArray.push_back(4);
	vecIntegerArray.push_back(6);
	vecIntegerArray.push_back(80);
	vecIntegerArray.push_back(34);

	for(size_t Index = 0;Index < vecIntegerArray.size();++Index)
	{
		cout<<"Element["<<Index<<"]= ";
		//cout<<vecIntegerArray[Index]<<endl;
		cout<<vecIntegerArray.at(Index)<<endl;
	}

	vecIntegerArray[2] = 2011;// 直接用下标设置值
	cout<<"After replacement: "<<endl;
	// cout<<"Element[2]= "<<vecIntegerArray[2]<<endl;

	// 也可以用at()取元素值,他会判断是否越界
	cout<<"Element[2]= "<<vecIntegerArray.at(2)<<endl;

	return 0;
}

(5)使用指针访问



#include <iostream>
#include <vector>

int main()
{
	using namespace std;
	vector <int> vecIntegers;

	vecIntegers.push_back(34);
	vecIntegers.push_back(54);
	vecIntegers.push_back(59);
	vecIntegers.push_back(23);

	auto iElementLocator = vecIntegers.begin();
	while(iElementLocator != vecIntegers.end())
	{
		size_t Index = distance(vecIntegers.begin(),iElementLocator);// 从0开始,计算他在什么位置

		cout<<"Element at position ";
		cout<<Index<<" is: "<<*iElementLocator<<endl;
		++iElementLocator;
	}
	return 0;
}

(6)删除元素

#include <iostream>
#include <vector>
using namespace std;

template <typename T>// 如果这个参数用了T,则要声明这个template;如果定义为int则不需要
void DisplayVector(const vector<T>& vecInput)
{
	for(auto iElement = vecInput.cbegin();iElement != vecInput.cend();++iElement)
		cout<<*iElement<<' ';

	cout<<endl;
}

int main()
{
	vector <int> vecIntegers;

	vecIntegers.push_back(34);
	vecIntegers.push_back(45);
	vecIntegers.push_back(65);
	vecIntegers.push_back(33);

	cout<<"Vector contains "<<vecIntegers.size()<<" elements: ";
	DisplayVector(vecIntegers);//34 45 65 33

	vecIntegers.pop_back();// 删除最后一个

	cout<<"After a call to pop_back()"<<endl;
	cout<<"Vector contains "<<vecIntegers.size()<<" elements: ";
	DisplayVector(vecIntegers);//34 45 65

	return 0;
}

(7)长度和容量

#include <iostream>
#include <vector>

int main()
{
	using namespace std;

	vector <int> vecIntegers(5);

	// 初始化的时候,他的长度和容量都等于初始值
	cout<<"Vector of integers was instantiated with "<<endl;
	cout<<"Size: "<<vecIntegers.size();//5
	cout<<", Capacity:"<<vecIntegers.capacity()<<endl;//5

	vecIntegers.push_back(666);

	// push之后,长度+1,容量翻倍
	cout<<"After inserting an additional element..."<<endl;
	cout<<"Size: "<<vecIntegers.size();//6
	cout<<", Capacity: "<<vecIntegers.capacity()<<endl;//10

	vecIntegers.push_back(777);

	// 继续push,长度+1,容量在还够用的情况下不变
	cout<<"After inserting yet another element..."<<endl;
	cout<<"Size: "<<vecIntegers.size();//7
	cout<<", Capacity: "<<vecIntegers.capacity()<<endl;//10

	return 0;
}

21、deque(17.4)

(1)在开头插入和删除

#include <deque>
#include <iostream>
#include <algorithm>

int main()
{
	using namespace std;

	deque<int>dqIntegers;

	dqIntegers.push_back(3);
	dqIntegers.push_back(4);
	dqIntegers.push_back(5);

	dqIntegers.push_front(2);
	dqIntegers.push_front(1);
	dqIntegers.push_front(0);

	cout<<"The contents of the deque after inserting elements ";
	cout<<"at the top and bottom are:"<<endl;

	for(size_t nCount = 0;nCount<dqIntegers.size();++nCount)
	{
		cout<<" Element ["<<nCount<<"]=";
		cout<<dqIntegers[nCount]<<endl;// 0 1 2 3 4 5
	}

	cout<<endl;

	dqIntegers.pop_front();// 从头删除一个

	dqIntegers.pop_back();// 从尾删除一个

	cout<<"The contents of the deque after erasing an element ";
	cout<<"from the top and bottom are:"<<endl;

	for(auto iElementLocator = dqIntegers.begin();iElementLocator != dqIntegers.end();++iElementLocator)
	{
		size_t Offset = distance(dqIntegers.begin(),iElementLocator);
		cout<<"Element["<<Offset<<"]="<<*iElementLocator<<endl;// 1 2 3 4
	}
	return 0;
}

22、list

(1)初始化list

#include <list>
#include <vector>

int main()
{
	using namespace std;

	list <int> listIntegers;// 初始化一个空列表

	list<int>listWith10Integers(10);// 初始化一个有10个int的列表

	list<int>listWith4IntegerEach99(4,99);// 初始化一个有4个int的列表并赋值每个值为99

	list<int>listCopyAnother(listWith4IntegerEach99);// 从一个已存在的list拷贝

	vector<int>vecIntegers(10,2011);// 一个vector,10个元素,值都为2011

	list<int>listContainsCopyOfAnother(vecIntegers.cbegin(),vecIntegers.cend());// 从vector拷贝到list

	return 0;
}

(2)在开头或末尾插入元素

#include <list>
#include <iostream>
using namespace std;

template<typename T>
void DisplayContents(const T&Input)
{
	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
	{
		cout<<*iElement<<' ';
	}
	cout << endl;
}

int main()
{
	std::list<int>listIntegers;

	listIntegers.push_front(10);
	listIntegers.push_front(2011);
	listIntegers.push_back(-1);
	listIntegers.push_back(9999);

	DisplayContents(listIntegers);

	return 0;
}

(3)insert

#include <list>
#include <iostream>
using namespace std;

template<typename T>
void DisplayContents(const T&Input)
{
	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
		cout<<*iElement<<' ';

	cout<<endl;
}

int main()
{
	list<int>listIntegers1;

	listIntegers1.insert(listIntegers1.begin(),2);//在list1的头部插入2
	listIntegers1.insert(listIntegers1.begin(),1);//在list1的头部插入1

	listIntegers1.insert(listIntegers1.end(),3);//在list1的尾部插入3

	cout<<"The contents of list 1 after inserting elements:"<<endl;
	DisplayContents(listIntegers1);// 1 2 3

	list<int>listIntegers2;

	listIntegers2.insert(listIntegers2.begin(),4,0);//在list2的头部插入4个元素,值都为0

	cout<<"The contents of list 2 after inserting '";
	cout<<listIntegers2.size()<<"' elements of a value:"<<endl;
	DisplayContents(listIntegers2);// 0 0 0 0

	list<int>listIntegers3;

	listIntegers3.insert(listIntegers3.begin(),listIntegers1.begin(),listIntegers1.end());// 在list3的头部插入所有list1的元素

	cout<<"The contents of list 3 after inserting the contents of ";
	cout<<"list 1 at the beginning:"<<endl;
	DisplayContents(listIntegers3);// 1 2 3

	listIntegers3.insert(listIntegers3.end(),listIntegers2.begin(),listIntegers2.end());// 在list3的尾部插入所有list2的元素

	cout<<"The contents of list 3 after inserting ";
	cout<<"the contents of list 2 at the beginning:"<<endl;
	DisplayContents(listIntegers3);//1 2 3 0 0 0 0

	return 0;
}

(4)删除

#include <list>
#include <iostream>
using namespace std;

template<typename T>
void DisplayContents(const T&Input)
{
	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
		cout<<*iElement<<' ';

	cout<<endl;
}

int main()
{
	list<int>listIntegers;

	listIntegers.push_back(4);
	listIntegers.push_front(3);
	listIntegers.push_back(5);

	auto iValue2 = listIntegers.insert(listIntegers.begin(),2);// 2 3 4 5,返回index:0

	cout<<"Initial contents of the list:"<<endl;
	DisplayContents(listIntegers);

	listIntegers.erase(listIntegers.begin(),iValue2);// 这个相当于删除范围0-0
	cout<<"Contents after erasing a range of elements:"<<endl;
	DisplayContents(listIntegers);// 2 3 4 5

	cout<<"After erasing element '"<<*iValue2<<"':"<<endl;
	listIntegers.erase(iValue2);// 删除index:0
	DisplayContents(listIntegers);// 3 4 5

	listIntegers.erase(listIntegers.begin(),listIntegers.end());
	cout<<"Number of elements after erasing range: ";
	cout<<listIntegers.size()<<endl;// 全删,size为0

	return 0;
}

(5)反转

#include <list>
#include <iostream>
using namespace std;

template<typename T>
void DisplayContents(const T&Input)
{
	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
		cout<<*iElement<<' ';

	cout<<endl;
}

int main()
{
	list<int>listIntegers;

	listIntegers.push_front(4);
	listIntegers.push_front(3);
	listIntegers.push_front(2);
	listIntegers.push_front(1);
	listIntegers.push_front(0);
	listIntegers.push_back(5);

	cout<<"Initial contents of the list:"<<endl;
	DisplayContents(listIntegers);// 012345

	listIntegers.reverse();

	cout<<"Contents of the list after using reverse():"<<endl;
	DisplayContents(listIntegers);//543210

	return 0;

}

(6)排序

#include <list>
#include <iostream>
using namespace std;

bool SortPredicate_Descending(const int&lsh,const int&rsh)
{
	return (lsh>rsh);// 升序还是降序取决于这个是大于号还是小于号,如果>则降序,因为左边大
}

template<typename T>
void DisplayContents(const T&Input)
{
	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
		cout<<*iElement<<' ';

	cout<<endl;
}

int main()
{
	list<int> listIntegers;

	listIntegers.push_front(444);
	listIntegers.push_front(2011);
	listIntegers.push_front(-1);
	listIntegers.push_front(0);
	listIntegers.push_back(-5);

	cout<<"Initial contents of the list are:"<<endl;
	DisplayContents(listIntegers);//0 -1 2011 444 -5

	listIntegers.sort();

	cout<<"Order of elements after sort():"<<endl;
	DisplayContents(listIntegers);// -5 -1 0 444 2011 升序排列

	listIntegers.sort(SortPredicate_Descending);
	cout<<"Order of elements after sort() with a predicate:"<<endl;
	DisplayContents(listIntegers);//2011 444 0 -1 -5 降序排列

	return 0;
}

(7)对包含对象的list进行排序和删除

#include <list>
#include <string>
#include <iostream>

using namespace std;

template<typename T>
void DisplayContents(const T&Input)
{
	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
		cout<<*iElement<<endl;

	cout<<endl;
}

struct ContactItem
{
	string strContactsName;
	string strPhoneNumber;
	string strDisplayRepresentation;
	// 此构造函数把名字跟电话连接起来
	ContactItem(const string&strName,const string&strNumber)
	{
		strContactsName = strName;
		strPhoneNumber = strNumber;
		strDisplayRepresentation = (strContactsName+": "+strPhoneNumber);
	}
	// 此等于运算符是用来删除的
	bool operator == (const ContactItem&itemToCompare) const
	{
		return (itemToCompare.strContactsName == this->strContactsName);
	}

	// sort 会检查是否定义小于运算符
	bool operator < (const ContactItem&itemToCompare) const
	{
		return (this->strContactsName<itemToCompare.strContactsName);
	}

	operator const char*() const
	{
		return strDisplayRepresentation.c_str();// 这个相当于tostring?
	}

};

bool SortOnPhoneNumber(const ContactItem& item1,const ContactItem&item2)
{
	return (item1.strPhoneNumber<item2.strPhoneNumber);// 降序
}

int main()
{
	list<ContactItem>Contacts;
	Contacts.push_back(ContactItem("Jack Welsch","+1 3454 433 567"));
	Contacts.push_back(ContactItem("Bill Gates","+1 3455 555 745"));
	Contacts.push_back(ContactItem("Angela Meerkel","+1 4355 456 256"));
	Contacts.push_back(ContactItem("Vladimir Putin","+1 3455 533 952"));
	Contacts.push_back(ContactItem("Manmohan Singn","+1 5433 694 230"));
	Contacts.push_back(ContactItem("Barack Obama","+1 6445 244 866"));

	cout<<"List in initial order: "<<endl;
	DisplayContents(Contacts);// 初始列表"Jack Welsch:+1 3454 433 567"...

	Contacts.sort();
	cout<<"After sorting in alphabetical order via operator:"<<endl;
	DisplayContents(Contacts);// 默认排序之后就用首字母的顺序排列:A B B J M V

	Contacts.sort(SortOnPhoneNumber);
	cout<<"After sorting in order of phone numbers via predicate:"<<endl;
	DisplayContents(Contacts);// 按电话号码排序就是:3454,3455,3455,4355,5433,6445

	cout<<"After erasing Putin from the list:";
	Contacts.remove(ContactItem("Vladimir Putin",""));
	DisplayContents(Contacts);// 删除之后就剩5个

	return 0;

}

(8)forward_list

#include <forward_list>
#include <iostream>
using namespace std;

template<typename T>
void DisplayContents(const T&Input)
{
	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
		cout<<*iElement<<' ';

	cout<<endl;
}

int main()
{
	forward_list<int> flistIntegers;
	flistIntegers.push_front(0);
	flistIntegers.push_front(2);
	flistIntegers.push_front(2);
	flistIntegers.push_front(4);
	flistIntegers.push_front(3);
	flistIntegers.push_front(1);

	cout<<"Contents of forward_list: "<< endl;
	DisplayContents(flistIntegers);// 134220

	flistIntegers.remove(2);
	flistIntegers.sort();
	cout<<"Contents after removing 2 and sorting: "<<endl;
	DisplayContents(flistIntegers);//0134

	return 0;

}

20、STL集合类

(1)实例化set、multiset

#include <set>

template<typename T>
struct SortDescending
{
	bool operator()(const T&lhs,const T&rhs) const
	{
		return (lhs>rhs);
	}
};

int main()
{
	using namespace std;

	set<int> setIntegers1;// 简单的int集合(默认排序),默认升序
	multiset<int> msetIntegers1;

	set<int,SortDescending<int>> setIntegers2;//用户定义的排序,此为降序
	multiset<int,SortDescending<int>> msetIntegers2;

	set<int> setIntegers3(setIntegers1);// 从另一个集合复制过来
	multiset<int> msetIntegers3(setIntegers1.cbegin(),setIntegers1.cend());

	return 0;

}

(2)插入元素

#include <set>
#include <iostream>
using namespace std;

template<typename T>
void DisplayContents(const T&Input)
{
	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
		cout<<*iElement<<' ';

	cout<<endl;
}

int main()
{
	set<int> setIntegers;
	multiset<int> msetIntegers;

	setIntegers.insert(60);
	setIntegers.insert(-1);
	setIntegers.insert(3000);
	cout<<"Writing the contents of the set to the screen"<<endl;
	DisplayContents(setIntegers);//-1,60,3000

	msetIntegers.insert(setIntegers.begin(),setIntegers.end());
	msetIntegers.insert(3000);

	cout<<"Writing the contents of the multiset to the screen"<<endl;
	DisplayContents(msetIntegers);//-1,60,3000,3000

	cout<<"Number of instances of '3000' in the multiset are:'";
	cout<<msetIntegers.count(3000)<<"'"<<endl;//统计有多少个3000,2个

	return 0;
}

(3)查找

#include <set>
#include <iostream>
using namespace std;

int main()
{
	set<int> setIntegers;

	setIntegers.insert(43);
	setIntegers.insert(78);
	setIntegers.insert(-1);
	setIntegers.insert(124);

	for(auto iElement = setIntegers.cbegin();iElement!=setIntegers.cend();++iElement)
		cout<<*iElement<<endl;//-1,43,78,124

	auto iElementFound = setIntegers.find(-1);// 寻找-1

	if (iElementFound != setIntegers.end())
		cout<<"Element "<<*iElementFound<<" found!"<<endl;// 找到
	else
		cout<<"Element not found in set!"<<endl;

	auto iAnotherFind = setIntegers.find(12345);

	if(iAnotherFind != setIntegers.end())
		cout<<"Element "<<*iAnotherFind<<" found!"<<endl;
	else
		cout<<"Element 12345 not found in set!"<<endl;// 没找到

	return 0;
}

(4)删除

#include <set>
#include <iostream>
using namespace std;

template<typename T>
void DisplayContents(const T&Input)
{
	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
		cout<<*iElement<<' ';

	cout<<endl;
}

typedef multiset<int> MSETINT;

int main()
{
	MSETINT msetIntegers;

	msetIntegers.insert(43);
	msetIntegers.insert(78);
	msetIntegers.insert(78);
	msetIntegers.insert(-1);
	msetIntegers.insert(124);

	cout<<"multiset contains "<<msetIntegers.size()<<" element.";//5个
	cout<<" These are: "<<endl;

	DisplayContents(msetIntegers);// -1,43,78,78,124

	cout<<"Please enter a number to be erased from the set"<<endl;
	int nNumberToErase = 0;
	cin>>nNumberToErase;// 43

	cout<<"Erasing "<<msetIntegers.count(nNumberToErase);// 1个
	cout<<" instances of value "<<nNumberToErase<<endl;// 43

	msetIntegers.erase(nNumberToErase);// 删除

	cout<<"multiset contains "<<msetIntegers.size()<<" elements.";
	cout<<" These are: "<<endl;
	DisplayContents(msetIntegers);// -1,78,78,124

	return 0;

}

(5)应用

#include <set>
#include <iostream>
#include <string>
using namespace std;

template<typename T>
void DisplayContents(const T&Input)
{
	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
		cout<<*iElement<<endl;

	cout<<endl;
}

struct ContactItem
{
	string strContactsName;
	string strPhoneNumber;
	string strDisplayRepresentation;

	ContactItem(const string & strName,const string& strNumber)
	{
		strContactsName = strName;
		strPhoneNumber = strNumber;
		strDisplayRepresentation = (strContactsName+": "+strPhoneNumber);
	}

	bool operator == (const ContactItem & itemToCompare) const
	{
		return (itemToCompare.strContactsName == this->strContactsName);
	}

	bool operator < (const ContactItem & itemToCompare) const
	{
		return (this->strContactsName < itemToCompare.strContactsName);// 按名字字母降序排列
	}

	operator const char*() const
	{
		return strDisplayRepresentation.c_str();
	}

};

int main()
{
	set<ContactItem> setContacts;
	setContacts.insert(ContactItem("Jack Welsch","+1 3443 566 764"));
	setContacts.insert(ContactItem("Bill Gates","+1 3345 544 656"));
	setContacts.insert(ContactItem("Angela Merkel","+1 5456 645 456"));
	setContacts.insert(ContactItem("Vladimir Putin","+1 6567 364 675"));
	setContacts.insert(ContactItem("Manmohan Singh","+1 3564 333 668"));
	setContacts.insert(ContactItem("Barack Obama","+1 3567 656 754"));

	DisplayContents(setContacts);

	cout<<"Enter a person whose number you wish to delete: ";
	string NameInput;
	getline(cin,NameInput);// 输入要删除的人的名字

	auto iContactFound = setContacts.find(ContactItem(NameInput,""));
	if(iContactFound != setContacts.end())
	{
		setContacts.erase(iContactFound);
		cout<<"Displaying contents after erasing: "<<NameInput<<endl;
		DisplayContents(setContacts);
	}
	else
		cout<<" Contact not found"<<endl;

	return 0;


	
}

(6)unorder_set

#include <unordered_set>
#include <iostream>
using namespace std;

template<typename T>
void DisplayContents(const T&Input)
{
	cout<<"Number of elements, size()="<<Input.size()<<endl;// 8,元素的数量
	cout<<"Max bucket count = "<<Input.max_bucket_count()<<endl;// 536870911
	cout<<"Load factor: "<<Input.load_factor()<<endl;// 0.727273
	cout<<"Max load factor = "<<Input.max_load_factor()<<endl;// 1
	cout<<"Unordered set contains: "<<endl;// -1000,989,1000,300,111,-300,-3,2011

	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
		cout<<*iElement<<' ';

	cout<<endl;
}

int main()
{
	unordered_set<int> usetInt;

	usetInt.insert(1000);
	usetInt.insert(-3);
	usetInt.insert(2011);
	usetInt.insert(300);
	usetInt.insert(-1000);
	usetInt.insert(989);
	usetInt.insert(-300);
	usetInt.insert(111);
	DisplayContents(usetInt);// -1000,989,1000,300,111,-300,-3,2011
	usetInt.insert(999);
	DisplayContents(usetInt);// -1000,989,1000,300,111,-300,-3,999,2011

	// find
	cout<<"Enter int you want to check for existence in set: ";
	int key = 0;
	cin>>key;
	auto iPairThousand = usetInt.find(key);//999

	if(iPairThousand != usetInt.end())
		cout<<*iPairThousand<<" found in set"<<endl;// 存在
	else
		cout<<key<<" not available in set"<<endl;

	return 0;

}

21、STL映射类

(1)实例化

#include <map>
#include <string>

template<typename KeyType>
struct ReverseSort
{
	bool operator()(const KeyType & key1,const KeyType & key2)
	{
		return (key1 > key2);
	}
};

int main()
{
	using namespace std;

	map<int,string> mapIntToString1;
	multimap<int,string> mmapIntToString1;

	map<int,string> mapIntToString2(mapIntToString1);
	multimap<int,string> mmapIntToString2(mmapIntToString1);

	map<int,string> mapIntToString3(mapIntToString1.cbegin(),mapIntToString1.cend());
	multimap<int,string> mmapIntToString3(mmapIntToString1.cbegin(),mmapIntToString1.cend());

	map<int,string,ReverseSort<int>> mapIntToString4(mapIntToString1.cbegin(),mapIntToString1.cend());
	multimap<int,string,ReverseSort<int>> mmapIntToString4(mapIntToString1.cbegin(),mapIntToString1.cend());

	return 0;
}

(2)插入

#include <map>
#include <iostream>
#include <string>

using namespace std;

typedef map<int,string> MAP_INT_STRING;
typedef multimap<int,string> MMAP_INT_STRING;

template<typename T>
void DisplayContents(const T & Input)
{
	for(auto iElement = Input.cbegin();iElement != Input.cend();++iElement)
		cout<<iElement->first<<"->"<<iElement->second<<endl;

	cout<<endl;
} 

int main()
{
	MAP_INT_STRING mapIntToString;

	// 这些插入方式都是等价的
	mapIntToString.insert(MAP_INT_STRING::value_type(3,"Three"));

	mapIntToString.insert(make_pair(-1,"Minus One"));

	mapIntToString.insert(pair<int,string>(1000,"One Thousand"));

	mapIntToString[1000000] = "One Million";

	cout<<"The map contains "<<mapIntToString.size();
	cout<<" key-value pairs. They are: "<<endl;
	DisplayContents(mapIntToString);//-1->Minus One,3->Three,1000->One Thousand,1000000->One Million

	MMAP_INT_STRING mmapIntToString(mapIntToString.cbegin(),mapIntToString.cend());// 从上面那个map拷贝过来

	mmapIntToString.insert(make_pair(1000,"Thousand"));// 然后再插入一个值对

	cout<<endl<<"The multimap contains "<<mmapIntToString.size();
	cout<<" key-value pairs. They are: "<<endl;
	cout<<"The elements in the multimap are: "<<endl;
	DisplayContents(mmapIntToString);// -1->Minus One,3->Three,1000->One Thousand,1000->Thousand,1000000->One Million

	cout<<"The number of pairs in the multimap with 1000 as their key: "
	<<mmapIntToString.count(1000)<<endl;// 1000有2个,所以这个count是2

	return 0;
}

(3)查找

#include <map>
#include <iostream>
#include <string>
using namespace std;

template<typename T>
void DisplayContents(const T & Input)
{
	for(auto iElement = Input.cbegin();iElement != Input.cend();++iElement)
		cout<<iElement->first<<" -> "<<iElement->second<<endl;

	cout<<endl;
}

int main()
{
	map<int,string> mapIntToString;

	mapIntToString.insert(make_pair(3,"Three"));
	mapIntToString.insert(make_pair(45,"Forty Five"));
	mapIntToString.insert(make_pair(-1,"Minus One"));
	mapIntToString.insert(make_pair(1000,"Thousand"));

	cout<<"The multimap contains "<<mapIntToString.size();
	cout<<" key-value pairs. They are: "<<endl;

	DisplayContents(mapIntToString);// -1->Miuns One,3->Three,45->Forty Five

	cout<<"Enter the key you wish to find: ";
	int key = 0;
	cin>>key;// 输入想要查找的key:45

	auto iPairFound = mapIntToString.find(key);
	if(iPairFound != mapIntToString.end())
	{
		cout<<"key "<<iPairFound->first<<" points to value: ";// 值为Forty Five
		cout<<iPairFound->second<<endl;
	}
	else
		cout<<"Sorry, pair with key "<<key<<" not in map"<<endl;

	return 0;

}

(4)删除

#include <map>
#include <iostream>
#include <string>
using namespace std;

template<typename T>
void DisplayContents(const T& Input)
{
	for(auto iElement = Input.cbegin();iElement!=Input.cend();++iElement)
		cout<<iElement->first<<" -> "<<iElement->second<<endl;

	cout<<endl;
}

int main()
{
	multimap<int,string> mmapIntToString;

	mmapIntToString.insert(make_pair(3,"Three"));
	mmapIntToString.insert(make_pair(45,"Forty Five"));
	mmapIntToString.insert(make_pair(-1,"Minus One"));
	mmapIntToString.insert(make_pair(1000,"Thousand"));

	// 插入重复的key
	mmapIntToString.insert(make_pair(-1,"Minus One"));
	mmapIntToString.insert(make_pair(1000,"Thousand"));

	cout<<"The multimap contains "<<mmapIntToString.size();
	cout<<" key-value pairs. "<<"They are: "<<endl;
	DisplayContents(mmapIntToString);// -1->Minus One,-1->Minus One,3->Three,...,1000->Thousand 按升序排列

	auto NumPairsErased = mmapIntToString.erase(-1);
	cout<<"Erased "<<NumPairsErased<<" pairs with -1 as key."<<endl;// 2,删除了2个

	auto iPairLocator = mmapIntToString.find(45);
	if(iPairLocator!=mmapIntToString.end())
	{
		mmapIntToString.erase(iPairLocator);// 删除45
		cout<<"Erased a pair with 45 as key using an iterator"<<endl;
	}

	cout<<"Erasing the range of pairs with 1000 as key."<<endl;//通过范围查找删除1000
	mmapIntToString.erase(mmapIntToString.lower_bound(1000),mmapIntToString.upper_bound(1000));

	cout<<"The multimap now contains "<<mmapIntToString.size();
	cout<<" key-value pair(s)."<<"They are: "<<endl;
	DisplayContents(mmapIntToString);// 最后只剩下3->Three

	return 0;
}

(5)自定义排序

#include <map>
#include <algorithm>
#include <string>
#include <iostream>
using namespace std;

template<typename T>
void DisplayContents(const T & Input)
{
	for(auto iElement = Input.cbegin();iElement != Input.cend();++iElement)
		cout<<iElement->first<<" -> "<<iElement->second<<endl;

	cout<<endl;
}

struct PredIgnoreCase
{
	bool operator()(const string & str1,const string & str2) const
	{
		string str1NoCase(str1),str2NoCase(str2);
		std::transform(str1.begin(),str1.end(),str1NoCase.begin(),tolower);// 这两行为什么编译不过
		std::transform(str2.begin(),str2.end(),str2NoCase.begin(),tolower);

		return (str1NoCase<str2NoCase);
	};
};

typedef map<string,string> DIRECTORY_WITHCASE;
typedef map<string,string,PredIgnoreCase> DIRECTORY_NOCASE;

int main()
{
	DIRECTORY_NOCASE dirCaseInsensitive;

	dirCaseInsensitive.insert(make_pair("John","2345764"));
	dirCaseInsensitive.insert(make_pair("JOHN","2345764"));
	dirCaseInsensitive.insert(make_pair("Sara","42367236"));
	dirCaseInsensitive.insert(make_pair("Jack","32435348"));

	cout<<"Displaying contents of the case-insensitive map:"<<endl;
	DisplayContents(dirCaseInsensitive);

	DIRECTORY_WITHCASE dirCaseSensitive(dirCaseInsensitive.begin(),dirCaseInsensitive.end());

	cout<<"Displaying contents of the case-senstive map:"<<endl;
	DisplayContents(dirCaseSensitive);

	cout<<"Please enter a name to search:"<<endl<<"> ";
	string strNameInput;
	cin>>strNameInput;

	auto iPairInNoCaseDir = dirCaseInsensitive.find(strNameInput);
	if(iPairInNoCaseDir != dirCaseInsensitive.end())
	{
		cout<<iPairInNoCaseDir->first<<"'s number in the case-insensitive";
		cout<<" directory is: "<<iPairInNoCaseDir->second<<endl;
	}else
	{
		cout<<strNameInput<<"'s number not found ";
		cout<<"in the case-insensitive directory"<<endl;
	}

	auto iPairInCaseSensDir = dirCaseSensitive.find(strNameInput);
	if(iPairInCaseSensDir != dirCaseSensitive.end())
	{
		cout<<iPairInCaseSensDir->first<<"'s number in the case-senstive";
		cout<<" directory is: "<<iPairInCaseSensDir->second<<endl;
	}else
	{
		cout<<strNameInput<<"'s number was not found ";
		cout<<"in the case-senstive directory"<<endl;
	}

	return 0;


}

(6)散列表unorder_map

#include <iostream>
#include <string>
#include <unordered_map>
using namespace std;

template<typename T1,typename T2>
void DisplayUnorderedMap(unordered_map<T1,T2>&Input)
{
	cout<<"Number of pairs,size(): "<<Input.size()<<endl;
	cout<<"Max bucket cout = "<<Input.max_bucket_count()<<endl;
	cout<<"Load factor: "<<Input.load_factor()<<endl;
	cout<<"Max load factor = "<<Input.max_load_factor()<<endl;
	cout<<"Unordered Map contains: "<<endl;

	for(auto iElement = Input.cbegin();iElement != Input.cend();++iElement)
		cout<<iElement->first<<" -> "<<iElement->second<<endl;
}

int main()
{
	unordered_map<int,string> umapIntToString;
	umapIntToString.insert(make_pair(1,"One"));
	umapIntToString.insert(make_pair(45,"Forty Five"));
	umapIntToString.insert(make_pair(1001,"Thousand One"));
	umapIntToString.insert(make_pair(-2,"Minus Two"));
	umapIntToString.insert(make_pair(-1000,"Minus One Thousand"));
	umapIntToString.insert(make_pair(100,"One Hundred"));
	umapIntToString.insert(make_pair(12,"Twelve"));
	umapIntToString.insert(make_pair(-100,"Minus One Hundred"));

	DisplayUnorderedMap<int,string>(umapIntToString);// size 8,134217727,0.727273,1

	cout<<"Inserting one more element"<<endl;
	umapIntToString.insert(make_pair(300,"Three Hundred"));
	DisplayUnorderedMap<int,string>(umapIntToString);

	cout<<"Enter key to find for: ";
	int key = 0;
	cin>>key;

	auto iElementFound = umapIntToString.find(key);
	if(iElementFound != umapIntToString.end())
	{
		cout<<"Found!key "<<iElementFound->first<<" points to value ";
		cout<<iElementFound->second<<endl;
	}else
	{
		cout<<"Key has no corresponding value in unordered map!"<<endl;
	}

	return 0;
}

22、类

(1)一个类的例子,并且 在main里调用

#include <iostream>
#include <string>
using namespace std;

class Human
{
private:
	string Name;
	int Age;
public:
	void SetName(string HumansName)
	{
		Name = HumansName;
	}
	void SetAge(int HumansAge)
	{
		Age = HumansAge;
	}
	void IntroduceSelf()
	{
		cout<<"I am "+Name<<" and am ";
		cout<<Age<<" years old"<<endl;
	}
};

int main()
{
	Human FirstMan;
	FirstMan.SetName("Adam");
	FirstMan.SetAge(30);

	Human FirstWoman;
	FirstWoman.SetName("Eve");
	FirstWoman.SetAge(28);

	FirstMan.IntroduceSelf();
	FirstWoman.IntroduceSelf();
}

(2)构造函数的声明及实现

class Human
{
public:
	Human();//声明构造函数
};

class Human
{
public:
	Human()
	{
		// 在类中声明构造函数并实现
	}
};

// 在类中声明构造函数并在类外实现
class Human
{
public:
	Human();
};

Human::Human()
{
	// code  here.
}

(3)当提供重载构造函数时,系统不会自动生成默认(无参)构造函数

(4)析构函数声明及实现

class Human
{
	~Human();// 定义析构函数
};

class Human
{
public:
	~Human()
	{
		// 定义析构函数并实现
	}
};

// 定义析构函数并在类外实现
class Human
{
public:
	~Human();
};

Human::~Human()
{
	// 实现
}

(5)std:string等类都可以自动分配内存,c风格的char缓冲区则要自己管理内存分配

凡是手动分配内存的,都需要手动去删除他

#include <iostream>
#include <string>
#include <string.h>
using namespace std;

class MyString
{
private:
	char* Buffer;
public:
	MyString(const char* InitialInput)
	{
		if(InitialInput != NULL)
		{
			Buffer = new char [strlen(InitialInput)+1];
			strcpy(Buffer,InitialInput);
		}else
			Buffer = NULL;
	}
	~MyString()
	{
		cout<<"Invoking destructor,clearing up"<<endl;
		if(Buffer!=NULL)
			delete [] Buffer;
	}
	int GetLength()
	{
		return strlen(Buffer);
	}
	const char* GetString()
	{
		return Buffer;
	}
};

int main()
{
	MyString SayHello("Hello from String Class");
	cout<<"String buffer in MyString is "<<SayHello.GetLength();
	cout<<" characters long"<<endl;

	cout<<"Buffer contains: ";
	cout<<"Buffer contains: "<<SayHello.GetString()<<endl;
}


(6)深层复制

#include <iostream>
#include <string>
#include <string.h>
using namespace std;

class MyString
{
private:
	char * Buffer;
public:
	MyString(const char * InitialInput)
	{
		cout<<"Constructor: creating new MyString"<<endl;
		if(InitialInput != NULL)
		{
			Buffer = new char [strlen(InitialInput)+1];
			strcpy(Buffer,InitialInput);

			cout<<"Buffer points to:"<<hex;
			cout<<(unsigned int*)Buffer<<endl;
		}else
			Buffer = NULL;
	}

	MyString(const MyString & CopySource)
	{
		cout<<"Copy constructor: copying form MyString"<<endl;
		if(CopySource.Buffer!=NULL)
		{
			Buffer = new char [strlen(CopySource.Buffer)+1];
			strcpy(Buffer,CopySource.Buffer);
			cout<<"Buffer points to:"<<hex;
			cout<<(unsigned int*)Buffer<<endl;
		}else
			Buffer = NULL;
	}

	~MyString()
	{
		cout<<"Invoking destructor, clearing up"<<endl;
		if(Buffer != NULL)
			delete [] Buffer;
	}

	int GetLength()
	{
		return strlen(Buffer);
	}

	const char * GetString()
	{
		return Buffer;
	}
};

void UseMyString(MyString Input)// 注意,参数在此即完成实例化
{
	cout<<"String buffer in MyString is "<<Input.GetLength();
	cout<<" characters long"<<endl;

	cout<<"Buffer contains: "<<Input.GetString()<<endl;
	return;
}

int main()
{
	MyString SayHello("Hello from String Class");
	UseMyString(SayHello);// 调用此函数的时候,此函数会自动去调用MyString(const MyString & CopySource)进行深层赋值
	UseMyString(SayHello);

	return 0;
}




注意:按值传递的类必须实现深层复制构造函数,这是一个特殊的构造函数,只有实现了这个构造函数,才能真正的按值传递(值和值存储在不同的位置)

MyString(const MyString & CopySource)

(7)禁止在栈上实例化

即禁止 ClassName instanceName;这样实例化,这样实例化是在栈上实例化。如果是一个数据库对象,那么数据量会很大,应该在堆上实例化;

禁止栈上实例化的方法是,析构函数声明为private。但是这种做法导致无法在main函数中调用析构函数,那么应该再添加一个静态公开函数,在次函数里调用析构函数。


26、函数

(1)按引用传递参数

如果是引用型参数,则本身就会按引用传递;如果是数值型参数,在函数的形参定义上加上引用标志,则会将引用传递进去,在函数里面改变定义在外部的引用的值。

void Area(double Radius,double & Result)
{
	Result = Pi * Radius * Radius;
}

int main()
{
	cout<<"Enter radius:";
	double Radius = 0;
	cin>>Radius;

	double AreaFetched = 0;
	Area(Radius,AreaFetched);

	cout<<"The area is:"<<AreaFetched<<endl;
	return 0;
}

注意:按指针传递其实与按引用传递有一样的效果,他们都区别于按值传递。即:加了&和加了*都是一样的效果。

(2)参数可以不要变量名

函数的定义及实现,可以只有变量类型,以及引用或指针标识,但没有变量名。

(3)void参数

//此两者相同,void只是为了增加可读性
//void是一个语法性的类型而非数据类型
void func(void);
void func();

//调用相同,都是没有传入参数
func();
//此函数在调用时还可以在前面加上void:
(void)func();

(4)void*参数

void*表示任意类型的一个指针。只要是一个指针就可以,类型不重要。

比如:

void func(int,void*);

第一个参数是一个int,第二个参数是一个指针,类型是任意的。



































































评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值