张德长

导航

C++学习笔记(1)

C++学习笔记(1)

 

泛型模板排序

template<typename T> //定义一个泛型类型T
/// <summary>
/// 定义一个模板方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="a"></param>
/// <param name="b"></param>
void mySwap(T& a, T& b)
{
	T temp = a;
	a = b;
	b = temp;
}

template<class T>
void mySort(T arry[], int len)
{
	for (int i = 0; i < len; i++)
	{
		int max = i;
		for (int j = i + 1; j < len; j++)
		{
			if (arry[max] < arry[j]) { max = j; }
		}
		if (max != i)mySwap(arry[max], arry[i]);
	}
}


template<class T>
void mySort2(T arry[], int len)
{
	for (int i = 0; i < len; i++)
	{
		int min = i;
		for (int j = i + 1; j < len; j++)
		{
			if (arry[min] > arry[j]) { min = j; }
		}
		if (min != i)mySwap(arry[min], arry[i]);
	}
}
#include<iomanip>
void test5()
{

	char ca[] = "adkblnvg";
	int len = sizeof(ca) / sizeof(ca[0]) - 1;
	
	cout  << setw(20) << "排序前		"  << ca << endl;
	mySort(ca,len);
	cout << setw(20) <<"从大到小排序后		" << ca << endl;
	mySort2(ca, len);
	cout << setw(20) << "从小到大排序后		" << ca << endl;
	cout << "----------------------------------------\n";
	int ai[] = {1,5,9,6,3,4,7,2,8,0};
	 len = sizeof(ai) / sizeof(ai[0]) - 1;
	cout << setw(20) << "排序前		" ;
	for (size_t i = 0; i < len; i++)
	{
		cout << ai[i] << ",";
	}
	cout << endl;
	mySort(ai, len);
	cout << setw(20) << "从大到小排序后		" ;
	for (size_t i = 0; i < len; i++)
	{
		cout << ai[i] << ",";
	}
	cout << endl;
	mySort2(ai, len);
	cout << setw(20) << "从小到大排序后		" ;
	for (size_t i = 0; i < len; i++)
	{
		cout << ai[i] << ",";
	}
	cout << endl;
}

运行结果

模板和泛型template

template<typename T> //定义一个泛型类型T
/// <summary>
/// 定义一个模板方法
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="a"></param>
/// <param name="b"></param>
void mySwap(T &a,T &b)
{
	T temp=a;
	a = b;
	b = temp;
}
//模板测试
void test4()
{
	char a = 'A',b='B';
	mySwap(a, b);//隐式类型推导
	cout << "a=" << a << "	b=" << b << endl;
	string s1 = "黑马程序员";
	string s2 = "C++教程从0到1入门编程";
	mySwap(s1,s2);//隐式类型推导
	cout << "s1=" << s1 << "	s2=" << s2 << endl;
	double b1 = 3.14, b2 = 5.678;
	mySwap<double>(b1, b2);//显式指定类型<T>
	cout << "b1=" << b1 << "	b2=" << b2 << endl;
}

运行结果

模板定义:将类型参数化,提高代码复用性;模板关键字template,

模板使用方法:1自动类型推导2显式指定类型

模板注意事项:

  • 自动类型推导,必须推导出一致的数据类型T,才可以使用模板;
  • 模板必须确定出T的类型,才可以使用;

-------------------------------------------------------------

参数传递的三种方式

  • 值传递
  • 引用传递
  • 指针传递
void test14()
{
	int a = 666, b = 888;
	cout << "数值交换前" << "	a=" << a << "	b=" << b << endl;
	swapv(a, b);
	
	cout<<"数值交换后" << "	a=" << a << "	b=" << b << endl;
	cout << "-----------------------------" << endl;
	int* pa = &a; int* pb = &b;
	cout << "指针交换前" << "	a=" << a << "	b=" << b << endl;
	swapp(pa,pb);
	cout << "指针交换后" << "	a=" << a << "	b=" << b << endl;
	cout << "-----------------------------" << endl;
	int& ra = a; int& rb = b;
	cout << "引用交换前" << "	a=" << a << "	b=" << b << endl;
	swapr(ra,rb);
	cout << "引用交换后" << "	a=" << a << "	b=" << b << endl;

}

运行结果

 

引用&测试

void test13()
{
	int a = 100; 
	int& b = a;
	
	cout << "b=" << b << "	a=" << a << endl;
	cout << "(int)&b=" << (int)&b << "	(int)&a=" << (int)&a << endl;
	//b = 100   a = 100
	//(int)&b = 13629100        (int)&a = 13629100
	a++;
	cout << "b=" << b << "	a=" << a << endl;
	cout << "(int)&b=" << (int)&b << "	(int)&a=" << (int)&a << endl;
	b++;
	cout << "b=" << b << "	a=" << a << endl;
	cout << "(int)&b=" << (int)&b << "	(int)&a=" << (int)&a << endl;
	int* p = &a;
	(*p)++;
	cout << "b=" << b << "	a=" << a << endl;
	cout << "(int)&b=" << (int)&b << "	(int)&a=" << (int)&a << endl;

	//int& c;//错误,引用不可以先声明,再赋值
	//int* p1;//正确,指针可以先声明,再赋值
	int c = 66;
	b = c;
	cout << "b=" << b << "	a=" << a << "	c=" << c << endl;
	cout << "(int)&b=" << (int)&b << "	(int)&a=" << (int)&a << "	(int)&c=" << (int)&c << endl;
}

运行结果

b虽然被赋值成了c,但是b的地址依然指向第一次赋值的a,只是把c的值复制过来了;

可见引用的地址不可改变,相当于指针常量int  * const p;

指针常量可以更改指针所指向的值,而不可以更改指针的指向(地址);

编译器自动类型转换int--double--int

void cheers(uint n)
{
	for (size_t i = 0; i < n; i++)
	{
		cout << "Cheers!" << endl;
	}
}
double cube(double side)
{
	return side * side * side;
}
void test12()
{
	//编译器:首先将int类型2转换为double类型2.0,以匹配cube函数的类型要求
	//编译器:将cube(2)的double类型返回值8.0转换为usigned int类型8,以匹配cheers函数的类型要求;
	cheers(cube(2));
}

运行结果

数组的替代选项---模板类vector、array

void test11()
{
	unsigned short n = 10;
	const unsigned short m =10;
	vector<int> vi;
	vector<double>vd(n);
	array<int, 5> ai;
	//m必须是常量,而不能是变量,可以是一个数值10,或者const unsigned int类型的变量
	array<double, m> ad = { 1.0,2.0,3.0,4.0 };

	//-------------------------------------

	double a1[4] = { 1.1,2.2,3.3,4.4 };//静态数组,必须在定义时指定长度
	//a1[-1] = -1.0;//错误,索引值超出索引范围0-3
	
	//double a2[];//错误,静态数组必须在定义时指定长度
	//double a2[4]=a1;//错误,应该使用{}初始化聚合对象
	//a2 = a1;//错误,应该使用{}初始化聚合对象
	vector<double> vd1={ 2.22,3.25,5.65,6.74 };
	vector<double>vd2{ 2.22,3.25,5.65,6.74 };//可以省略等号进行便捷初始化
	vector<double> vd3(4);//不能直接初始化
	vd3= { 2.22,3.25,5.65,6.74 };
	vector<double>vd4(3);
	vd4[0] = 1.23;
	vd4[1] = 3.22;
	cout << "vd4[0]		" << vd4[0] << endl;
	cout << "vd4[1]		" << vd4[1] << endl;
	cout << "vd4[2]		" << vd4[2] << endl;
	cout << "-------------------------" << endl;
	vector<double> vd5 = vd4;
	cout << "&vd4[i]	" << "&vd5[i]" << endl;
	cout << &vd4[0]	<<"	" << &vd5[0] << endl;
	cout << &vd4[1] << "	" << &vd5[1] << endl;
	cout << &vd4[2] << "	" << &vd5[2] << endl;

	array<double, 4> arr1{ 5.0,6.0,7.0,8.0 };
	//array<double, 5> arr2=arr1;//错误,必须长度相等才可以赋值
	//array<long double, 4>arr3 = arr1;//错误,必须类型相同才可以赋值
	array<double, 4>arr4 = arr1;
	cout << "-------------------------" << endl;

	cout << "&arr4[i]	" << "&arr1[i]" << endl;
	cout << &arr4[0] << "	" << &arr1[0] << endl;
	cout << &arr4[1] << "	" << &arr1[1] << endl;
	cout << &arr4[2] << "	" << &arr1[2] << endl;
}

运行结果

vector之间可以直接=赋值,赋值后的vector是原vector的一个拷贝;

array之间可以直接=赋值,必须满足两个条件

1、array长度必须相等;

2、元素类型必须完全相同;

赋值后的array是原array的一个拷贝;

指向指针的指针

struct years
{
	int year;
	bool isLeepYear;

};
void test10()
{
	years y1, y2, y3;
	y1.year = 1998;			//成员运算符,用变量名访问成员
	years* py = &y2;
	py->year = 1999;		//间接成员运算符,用指针访问成员
	years arry[3];		//结构体数组
	arry[0].year = 2003; arry[1].year = 2004; arry[2].year = 2005;

	cout<<"arry->year		" << arry->year << endl;
	cout << "arry[1].year		" << arry[1].year << endl;
	cout << "arry->year		" << arry->year << endl;
	cout << "-------------------------"<<endl;
	years* arryp[3] = { &y1,&y2,&y3 };//结构体指针数组
	cout << "arryp[1]->year		" << arryp[1]->year << endl;
	//数组元素本身是指针(指向结构体),
	//而数组名也是指针(指向数组的第一个元素),
	//所以这里的数组名是指向指针的指针years**
	years** ppa = arryp;
	auto ppb = arryp;
	cout << "-------------------------" << endl;
	cout << "(*ppa)->year		" << (*ppa)->year << endl;
	cout << "(*(ppb + 1))->year		" << (*(ppb + 1))->year << endl;
}

运行结果

字符串测试

typedef unsigned int uint;

char* getname()
{
	char temp[80];
	cout << "Enter name (less than 80 characters)" << endl;
	cin >> temp;
	uint len = strlen(temp);
	cout << "len=" << len << endl;
	//通过一个小的内存空间来存放输入,以节省内存
	char* pc = new char[len + 1];
	//len表示字符串中字符的个数,而没有包含字符串结束标识"\0"
	//字符串所占字节数应当包含结束标识"\0",所以为len+1
	//strcpy已过时弃用,这里使用更加安全的strcpy_s
	//第一个参数表示拷贝的目标指针,char*类型
	//第二个参数表示需要拷贝的字节数,包含结束标识"\0",所以为len+1,
	// rsize_t类型,rsize_t类型属于size_t类型,而size_t类型属于unsigned int类型
	// rsize_t类型实际就是unsigned int类型,二者等效
	//第三个参数表示需要拷贝的数据源const char*类型
	strcpy_s(pc, len+1, temp);
	return pc;

}

void test9()
{
	char* name;
	name = getname();
	cout << "name=" << name << "	name at=" << (int*)name << endl;
	//只能释放new的资源
	delete name;
	name = getname();
	cout << "name=" << name << "	name at=" << (int*)name << endl;
	//只能释放new的资源
	delete name;
}

运行结果

打开文件是否成功的测试

void test2()
{
	ifstream instream;
	instream.open("in.dat");
	string s = instream.fail() ? "fail" : "succeed";
	cout <<"instream.fail()?	" << instream.fail() << endl;
	cout << "instream.fail()?	" << s << endl;
	if (!instream.fail())instream.close();
	instream.open("inFile.dat");
	s = instream.fail() ? "fail" : "succeed";
	cout << "instream.fail()?	" << instream.fail() << endl;
	cout << "instream.fail()?	" << s << endl;
	if (!instream.fail())instream.close();
}

运行结果

文件流测试

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


void test1()
{
	ifstream inStream;
	ofstream outStream;
	inStream.open("inFile.dat");
	outStream.open("outFile.dat");
	int first, second, third;
	inStream >> first >> second >> third;
	cout << "first=" << first << "	second=" << second << "	third=" << third << endl;
	cout << "sum=" << first + second + third << endl;
	outStream << "first=" << first << "	second=" << second << "	third=" << third << endl;
	outStream << "sum=" << first + second + third << endl;
	inStream.close();
	outStream.close();
}

运行结果

posted on 2022-05-14 00:28  张德长  阅读(84)  评论(0编辑  收藏  举报