c++模板的概念全新解释

2023-11-05


前言

我们都知道在c++与c语言的区别中,最大的不同就是c++訲多了对象和模板,前面我们介绍了面向对象的编程,现在我们来认识一下c++中模板的知识。
模板八函数或类要处理的数据类型参数化,即表现为数据的多态性。在面向对象技术中,模板是另一种代码重用机制。


提示:以下是本篇文章正文内容,下面案例可供参考

一、模板的概念

强类型的严格性和灵活性

在强类型程序设计语言中,参与运算的所有对象的类型在编译时即可确定下来,并且编译程序将进行严格的类型检查,这样就可以在程序未运行之前就检查出类型不兼容的错误。
但是由于这种强类型语言在提高程序的可靠性的同时又带来了一些负作用。
例如我们在使用函数求某一个计算类容的时候,会出现参数类型不一样,他们的算法相同,但是参数不同,所以程序员就必须写两个程序。这就不利于程序的扩展和维护。

解决冲突的路径

如何解决强类型的严格性与灵活性的冲突?以往有三种方法。
第一种:利用宏函数,使用宏函数虽然确实会简便问题,但是我们知道引入宏函数后可能会导致程序出现以些意想不到的问题。所以在c++中一般不会使用宏函数。
第二种:为各种类型重载这一函数,但是重载函数又显得麻烦。增加工作量。
第三种:放松类型检查,在编译期间忽略这些类型的匹配问题。而在运行期间进行类型匹配检查,但是在程序运行的时候可能会出现类型不兼容的错误。
综和上面的方法,我们发现无论何种方法,都会有漏洞,那么最理想的方法是什么?最理想的方法是直接将数据类型作为类的参数,就像函数可以将数据作为参数一样。这种机制叫做“类属”(genericity),强类型程序设计语言(如Ada,Eiffel等语言)通常都采用这种方式

模板的概念

模板是一种参数化多态性的工具,可以为逻辑功能相同而类型不同的程序提供代码共享的机制。
由于c+程序结构的主要构件是类和函数,所以在c++中,模板被分为函数模板和类模板。模板并非一个实实在在的函数或类,仅仅是函数或类的描述,模板运算对象的类型不是实际的数据类型,而是一种参数化的类型(又称为类属类型)。带类属参数的函数叫做函数模板,带类属参数的类叫做类模板。
在这里插入图片描述

一(1).函数模板

通常,设计的算法是可以处理多种数据类型的,c++提供的函数模板可以一次定义出具有共性(除类型参数外,其余全相同)的一组函数,同时也可以处理多种不同类型数据的函数。从而大大增强了函数设计的通用性。

函数模板的定义

函数模板定义的格式:
template<模板参数表>
<返回值类型><函数名>(<参数表>)
{
<函数体>
}
其中,关键字template是定义模板的关键字,<模板参数列表>中包含一个或多个用逗号分开的模板参数项,每一项又保留字class或者typename开始,后跟用户命名的标识符,此标识符为模板参数,表示数据类型。函数模板中可以利用这些模板参数定义函数返回值类型,参数类型和函数体中的变量类型。它同基本数据类型一样,可以在函数中的任何地方使用。
在这里插入图片描述

函数模板的实例化
#include<iostream>
#include<string>
using namespace std;
template <typename T>  //函数模板;
T Max(T a, T b)
{
	return a > b ? a : b;
}
int main()
{
	int a, b;
	cout << "Input two integers to a&b:" << endl;
	cin >> a >> b;
	cout << "max(" << a << "," << b << ")=" << Max(a, b) << endl;        //有些编译软件不能使用max模板函数,是由于系统自带max函数;
	char c, d;
	cout << "Input two chars to c&d:" << endl;
	cin >> c >> d;
	cout << "max(" << "\'" << c << "\'" << "," << "\'" << d << "\'" << ")=";
	cout<< Max(c, d) << endl;
	float x, y;
	cin >> x >> y;
	cout << "Input two float x&y:" <<endl;
	cout << "max(" << x << "," << y << ")=" << Max(x, y) << endl;
	cout << "Input two string to p&h:" << endl;
	string p, h;
	cin >> p >> h;
	cout << "max(" << "\"" << p << "\"" << "," <<"\"" << h <<"\"" << ")=";
	cout << Max(p, h) << endl;
	return 0;
}

在这里插入图片描述
在程序中,我们可以发现在使用相同的函数时,不再需要多次定义数据类型,编译器会根据语句中的实际数据类型而产生相应的函数。
这就极大的减轻了程序员的工作负担。
下面我们来看看他的图示:
在这里插入图片描述
函数模板的声明和定义必须是全局作用域,而且模板不能被声明成类的成员函数。

函数模板的重载

函数模板有多种重载方式,可以定义同名的函数模板,提供不同的参数和实现;也可以用其他非模板函数重载。

1.函数模板的重载

重载函数模板和重载函数类似,重载函数模板便于定义类属参数,或者函数参数的类型。个数不同所进行的操作。

#include<iostream>
using namespace std;
template <typename T>
T Max(T a, T b)
{
	return a > b ? a : b;
}
//重载;
template<typename T>
T Max(T a[], T n)
{
	T temp;
	temp = a[0];
	for (int i = 0; i < n; i++)
	{
		if (temp < a[i])
			temp = a[i];
	}
	return temp;
}
int main()
{
	int a, b;
	cout << "Input two integers to a&b" << endl;
	cin >> a >> b;
	cout << "Max(" << a << "," << b << ")=" << Max(a, b) << endl;
	int i, aa[10] = { 3,7,9,11,0,6,7,5,4,2 };
	cout << "The original array:" << endl;
	for (i = 0; i < 10; i++)
	{
		cout << aa[i] << ",";
	}
	cout << endl;
	cout << "Max of 10 integers is" << Max(aa, 10) << endl;
	return 0;
}
2.用普通函数重载函数模板

函数模板实例化时,实际参数类型将替换模板参数,虽然这种参数替换具有类型检查功能,但是却没有普通传值参数的类型转换机制。
也就是说,函数模板没办法预知隐式的类型转换。这个时候我们就可以用非模板函数重载一个同名的函数模板;

#include<iostream>
using namespace std;
template <typename T>
T Max(T a,T b)
{
	return a > b ? a : b;
}
int Max(int a, float b)            //用普通函数重载函数模板;
{
	return a > b ? a : b;
}
int main()
{
	char a = '4', b = '5';
	float c = 5.7;
	int d = 10;
	cout<<Max(a, b) << endl;
	cout << Max(d, c) << endl;
	return 0;
}
3.用特定函数重载函数模板
#include<iostream>
#include<cstring>
using namespace std;
template <typename T>
T Max(T a, T b)
{
	return a > b ? a : b;
}

int Max(int a, float b)
{
	return a > b ? a : b;
}
char* Max(char* a,char* b)
{
	return strcmp(a, b) > 0 ? a : b;
}
int main()
{
	char a = '4', b = '5';
	int c = 5;
	cout << "Max(" << "\'" << a << "\'" << "," << "\'" <<b << "\'" << ")=";
	cout << Max(a, b) << endl;
	cout << "Max(" << "\'" << a << "\'" << "," << "\'" << c << "\'" << ")=" << Max(a, c) << endl;
	const char* p, * h;
	p = "qaz";
	h = "wsx";
	cout << "Max(" << "\"" << p << "\"" << "," << "\"" << h << "\"" << ")=" << Max(p,h) << endl;
}

类模板

同函数模板一样,使用类模板可以为类定义一种模式,使得类中的某些数据成员。某些成员函数的参数以及某些成员函数的返回值能取任意类型。类模板是对一批仅有成员数据类型不同类的抽象,程序员只要为这一批类所组成的整个类家族创建一个类模板,然后给出一套程序代码,就可以用来生成多种具体的类,即模板类。

类模板定义

类是对一组对象的公共性质的抽象,而类模板则是对不同类的公共性质的抽象,英雌类模板属于是更高层次的抽象。
格式:
template<模板参数表>
class <类模板名>
{
<类成员声明>
}
其中,<模板参数表>中包含一个或多个用逗号隔开的类型,参数项可以包含数据类型,也可以包含类属类型,如果是类属类型,则必须加class或者typename做前缀。
类模板中的成员函数的定义:
template<模板参数表>
返回值类型<类模板名><类型列表>::<函数名>(参数表)
{
函数体
}
<类型名表>既是类模板中定义中的类型形式参数表中的参数名。
类模板中的成员函数放在类模板的外部的时候,也可以在前面加inline表明内连函数函数。

类模板的实例化

在这里插入图片描述
与函数模板不同的是,函数模板的实例化是由编译系统在处理函数调用时自动完成,而类模板的实例化必须由程序员在程序中显示的指定。

在这里插入图片描述
代码演示:

#include<iostream>
#include<process.h>
using namespace std;
const int size = 10;
template <typename AType>
class atype
{
public:
	atype()
	{
		int i;
		for (i = 0; i < size; i++)
		{
			array[i] = i;
		}
	}
	AType& operator[](int n);
private:
	AType array[size];
};
template <typename AType>
AType& atype<AType>::operator[](int n)
{
	if (n<0 || n>size)
	{
		cout << "下标" << n << "超出范围!" << endl;
		exit(1);
	}
	return array[n];
}
int main()
{
	const int size = 10;
	atype<int>intob;
	atype<double>doubleob;
	int i;
	cout << "Integer 数组:";
	for (i = 0; i < size; i++)
		intob[i] = i;
	for (i = 0; i < size; i++)
	{
		cout << intob[i] << " ";
	}
	cout << endl;
	cout << "Double 数组:";
	for (i = 0; i < size; i++)
	{
		doubleob[i] = (double)i / 2;
	}
	for (i = 0; i < size; i++)
	{
		cout << doubleob[i] << " ";
	}
	cout << endl;
	intob[12] = 100;         //下标越界;
	return 0;
}

在这里插入图片描述
类模板的实例化创建的结果是一种类型,而类的实例化创建的结果则是一个对象。
在这里插入图片描述

使用函数类型参数的类模板

在类模板的《模板参数表中》,必须至少有一个类参数,当然也可以有多个类参数。还可以有非类参数的参数,这样的参数一般称之为函数类型参数,也可以称之为无类型模板参数。
函数参数类型只限于整型,指针和引用,其他的类型(例如浮点型float)则不能使用。传递给函数参数类型的实参要么是整型常量,要么由指向全局函数或对象的指针或引用组成。由于函数参数类型的值不能改变,所以函数参数类型参数本身被看作常量,因此,函数类型参数可以用来设定数组大小。

#include<iostream>
#include<process.h>
using namespace std;
template <typename AType,int size>             //size作为函数参数类型参数
class atype          //模板类;
{
public:
	atype()
	{
		int i;
		for (i = 0; i < size; i++)
			array[i] = i;
	}
	AType& operator[](int n);    //"[]"运算符重载;至少含有一个参数;
private:
	AType array[size];
};
template <typename AType,int size>
AType& atype<AType, size>::operator[](int n)
{
	//下标越界检查;
	if (n<0 || n>size)
	{
		cout << "下标" <<n<<"超出范围" << endl;
		exit(1);
	}
	return array[n];
}
int main()
{
	//10个元素的integer数组类,intob为该类的一个对象;
	atype<int, 10>intob;
	//10个元素的double数组类,doublob为该类的一个对象
	atype<double, 10>doublob;
	int i;
	cout << "integer[]数组类: ";
	for (i = 0; i < 10; i++)
	{
		intob[i] = i;
		cout << intob[i] << "  ";
	}
	cout << endl;
	cout << "doublob[]数组类: ";
	for (i = 0; i < 10; i++)
	{
		doublob[i] = (double)i / 2;
		cout << doublob[i] << "  ";
	}
	cout << endl;
	intob[12] = 100;
	return 0;
}

在这里插入图片描述

使用默认参数的类模板

类模板可以包含于通用类型相关的默认参数。当类模板被实例化时,如果没有指定其他的数据类型,则使用默认数据类型。

#include<iostream>
#include<process.h>
using namespace std;
template<typename AType=int,int size=10>
class atype           //使用默认参数的模板类;
{
public:
	atype()
	{
		int i;
		for (i = 0; i < size; i++)
		{
			array[i] = i;
		}
	}
	AType& operator[](int n);
private:
	AType array[size];
};
template<typename AType,int size>
AType& atype<AType, size>::operator[](int n)
{
	if (n<0 || n>size)
	{
		cout << "下标" << n << "越界" << endl;
		exit(1);
	}
	return array[n];
}
int main()
{
	//12个元素的integer数组类,inton为模板类的一个对象;
	atype<int,12>intob;
	//double数组类,默认10个元素长度,
	atype<double>doubleob;
	//数组类,默认int型,默认10个元素长度;
	atype<>defaultob;
	int i;
	cout << "Integer 数组类:";
	for (i = 0; i < 12; i++)
	{
		intob[i] = i;
		cout << intob[i] << "  ";
	}
	cout << endl;
	cout << "double 数组类:";
	for (i = 0; i < 10; i++)
	{
		doubleob[i] = (double)i / 2;
		cout << doubleob[i] << "  ";
	}
	cout << endl;
	cout << "默认参数类型:";
	for (i = 0; i < 10; i++)
	{
		cout << defaultob[i] << "  ";
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

标准模板库STL

c++中包含一个有许多组件的标准库。标准模板库(Standard Template Library,STL)是标准c++标准库的一部分。

容器

“容器”是数据结构,是包含对象的对象。例如,数组,队列,堆栈,树,图等数据结构中的每一个节点都是一个对象。这些结构按照某种特定的逻辑关系组合在一起,就成为了一个新的对象。

容器的分类

在这里插入图片描述
在这里插入图片描述
在前面介绍c++基础知识的时候,就已经介绍了STL模板库,但是很多人并不知道他的原理,而要想弄懂这个问题就要知道容器的接口是什么。
我们所使用的STL模板斗都是将一些代码封装为一个容器,从而使用它,正是由于这样才使得我们的工作减轻很多负担。要想正确的使用模板,了解他们所对应的函数原型显得很重要。下面我们以vector模板为例,介绍他的原函数:
在这里插入图片描述

顺序容器和关联容器

顺序容器将一组具有相同类型的元素一样额的线性形式组织起来。顺序容器分为vector,list,deque三种类型。他们在某些方面很相似。前面已经介绍过了,就不过多介绍。
关联容器具有根据一组索引来快速提取元素的能力,其中元素可以通过键值(key)来访问。四种关联容器可以分为两种:set和map
(1).set是一种集合,其中可以包含0个或多个不重复的以及不排序的元素,这些元素被称为键值。
例如,set集合s
{-2,34,56}
中包含三个键值,不能通过下标来访问集合;
(2).map是一种映像,其中包含0个或多个不排序的元素对,一个元素是不重复的键值,另一个是与键相关联的值。
例如,map集合m
{(first,4),(second,-99),(third,50)}
中包含3对元素。每对元素都由一个键值和相关联的值构成。
map和multimap容器的元素是按照关键字顺序排列的,因此提供按关键字快速查找元素。成员函数find(),count(),lower_bound(),upper_bound()基于元素键值的查找和计数。

#include<iostream>
#include<vector>
#include<process.h>
using namespace std;
int main()
{
	int i;
	vector<int>nums;        //整型向量,长度为0;
	nums.insert(nums.begin(), -99);    //在第一处插入数据-99
	nums.insert(nums.begin(), 50);
	nums.insert(nums.end(), 4);
	for (i = 0; i < nums.size(); i++)
	{
		if (nums[i])
		cout << nums[i] << " ";
	}
	cout << endl;
	nums.erase(nums.begin());  //删除向量中第一处的值
	nums.erase(nums.begin());
	for (i = 0; i < nums.size(); i++)
	{
		if(nums[i])
		cout << nums[i] << "  ";
	}
	cout << endl;
	return 0;
}

在这里插入图片描述

迭代器

对于迭代器的理解,可以理解为面向对象版本的指针,但是和指针又有一些不同。通俗点来说就是指针是迭代器,但迭代器又不仅仅是指针,指针可以指向内存中的一个地址,然后通过这个地址访问相应的内存单元。而迭代器更抽象,它可以指向容器中的一个位置,然后就可以直接访问这个位置的元素。

迭代器的分类

STL迭代器主要包括5中基本类别:输入(input)迭代器,输出(output)迭代器,前向(forward)迭代器,双向(bidirectional)迭代器和随机访问(random access)迭代器。
在这里插入图片描述
迭代器在头文件iterator中声明。因为不同类型的容器支持不同的迭代器,所以不必显式指定包含iterator文件也可以使用迭代器。
vector和deque容器支持随机访问。list,map,set,multiset和multimap支持双向访问;

迭代器的使用

可以定义各种容器的迭代器对象(iterator类型对象)。迭代器对象通常被称为迭代子或迭代算子。
eg:

#include<iostream>
#include<list>
#include<iterator>      //迭代器头文件可以省略;
using namespace std;
int main()
{
	list<int>nums;  //整型双向链表
	for (int i = 0; i < 10; i++)
	{
		nums.insert(nums.end(), i * 10);
	}
	list<int>::const_iterator p1; //p1是双向链表的迭代子;
	cout << "整型双向链表的正向输出:" << endl;
	for (p1 = nums.begin(); p1 != nums.end(); p1++)     //这里p1不再是用循环中常用的小于来判断循环结束条件;
	{
		cout << *p1 << "  ";
	}
	cout << endl;
	list<int>::reverse_iterator p2;
	p2 = nums.rbegin();           //反向迭代指向最后一个元素;
	cout << "逆向输出双向链表中所有元素:" << endl;
	while (p2 != nums.rend())
	{
		cout << *p2 << "  ";
		p2++;
	}
	cout << endl;
	return 0;
}

在这里插入图片描述
上面的程序中在使用迭代器的时候,我们发现迭代器的定义有点不一样,那么他们的差距在哪里?

预定义迭代器
预定义迭代器 ++操作方向
iterator 向前
const_iterator 向前
reverse_iterator 向后
const_ireverse_terator 向后
算法

c++中的STL中包含大约70种标准算法。这些算法是用于对容器的数据施加特定操作的函数模板。
STL中几乎所有的算法的头文件都是#include
从对容器的访问性质来说,算法分为只读(及不允许改写元素)和改写(即可以修改元素)两种。从功能上来说可以分为查找,比较,计算,排序,置值,合并,集合,管理等。

通用算法的调用形式

如同STL容器是常用数据结构的类模板一样,STL算法是用于对容器的数据施加特定操作的函数模板。
例如STL中的排序算法:
第一种形式:

template<typename RandomAcessIterator>
void sort(RandomAcessIterator first,RandomAcessIterator last);

按照升序排列;
第二种形式:

template<RandomAcessIterator,class Compare>
void sort(RandomAcessIterayor first,RandomAcessIterator last,Compare pr)

按照pr函数的排序方式来排序。

通用算法应用

//reverse和sort的应用

#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;
bool inoder(int, int);
int main()
{
	vector<int>nums;      //整型向量,长度为;
	for (int i = 0; i < 10; i++)
	{
		nums.insert(nums.end(), i * 10);
	}
	cout << "向量的初始顺序:";
	vector<int>::const_iterator p1;
	for (p1 = nums.begin(); p1 != nums.end(); p1++)
	{
		cout << *p1 << "   ";
	}
	cout << endl;
	//函数逆置;
	reverse(nums.begin(), nums.end());
	cout << "逆置排列:";
	for (int i = 0; i < 10; i++)
	{
		cout << nums[i] << "  ";
	}
	cout << endl;
	//调用第一种排序方式排序;
	sort(nums.begin(), nums.end());
	cout << "使用第一种方式排序后的结果为:";
	for (int i = 0; i < 10; i++)
	{
		cout << nums[i] << "  ";
	}
	cout << endl;
	//调用第二种方式排序
	sort(nums.begin(), nums.end(), inoder);
	vector<int>::const_iterator p2;
	cout << "第二种排序方式的输出结果:";
	for (p2 = nums.begin(); p2 != nums.end(); p2++)
	{
		cout << *p2 << "  ";
	}
	cout << endl;
}
bool inoder(int a, int b)
{
	return a > b;
}

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

c++模板的概念全新解释 的相关文章

  • 使用 gcc 在 Linux 上运行线程构建块 (Intel TBB)

    我正在尝试为线程构建块构建一些测试 不幸的是 我无法配置 tbb 库 链接器找不到库 tbb 我尝试在 bin 目录中运行脚本 但这没有帮助 我什至尝试将库文件移动到 usr local lib 但这又失败了 任何的意见都将会有帮助 确定您
  • 删除文件的最后 10 个字符

    我想删除文件的最后 10 个字符 说一个字符串 hello i am a c learner 是文件内的数据 我只是希望该文件是 hello i am a 文件的最后 10 个字符 即字符串 c learner 应在文件内消除 解决方案 将
  • 通过引用传递 [C++]、[Qt]

    我写了这样的东西 class Storage public Storage QString key const int value const void add item QString int private QMap
  • 机器Epsilon精度差异

    我正在尝试计算 C 中双精度数和浮点数的机器 epsilon 值 作为学校作业的一部分 我在 Windows 7 64 位中使用 Cygwin 代码如下 include
  • std::list 线程push_back、front、pop_front

    std list 线程安全吗 我假设不是这样 所以我添加了自己的同步机制 我认为我有正确的术语 但我仍然遇到问题 每个函数都由单独的线程调用 Thread1 不能等待 它必须尽可能快 std list
  • 随着时间的推移,添加到 List 变得非常慢

    我正在解析一个大约有 1000 行的 html 表 我从一个字符串中添加 10 个字符串 td 每行到一个list td
  • 如何在 C# 中打开 Internet Explorer 属性窗口

    我正在开发一个 Windows 应用程序 我必须向用户提供一种通过打开 IE 设置窗口来更改代理设置的方法 Google Chrome 使用相同的方法 当您尝试更改 Chrome 中的代理设置时 它将打开 Internet Explorer
  • free 和 malloc 在 C 中如何工作?

    我试图弄清楚如果我尝试 从中间 释放指针会发生什么 例如 看下面的代码 char ptr char malloc 10 sizeof char for char i 0 i lt 10 i ptr i i 10 ptr ptr ptr pt
  • -webkit-box-shadow 与 QtWebKit 模糊?

    当时有什么方法可以实现 webkit box shadow 的工作模糊吗 看完这篇评论错误报告 https bugs webkit org show bug cgi id 23291 我认识到这仍然是一个问题 尽管错误报告被标记为RESOL
  • C++ 多行字符串原始文字[重复]

    这个问题在这里已经有答案了 我们可以像这样定义一个多行字符串 const char text1 part 1 part 2 part 3 part 4 const char text2 part 1 part 2 part 3 part 4
  • 需要帮助优化算法 - 两百万以下所有素数的总和

    我正在尝试做一个欧拉计划 http projecteuler net问题 我正在寻找 2 000 000 以下所有素数的总和 这就是我所拥有的 int main int argc char argv unsigned long int su
  • ASP.NET Core 3.1登录后如何获取用户信息

    我试图在登录 ASP NET Core 3 1 后获取用户信息 如姓名 电子邮件 id 等信息 这是我在登录操作中的代码 var claims new List
  • 在 Unity 中实现 Fur with Shells 技术

    我正在尝试在 Unity 中实现皮毛贝壳技术 http developer download nvidia com SDK 10 5 direct3d Source Fur doc FurShellsAndFins pdf Fins 技术被
  • C# xml序列化必填字段

    我需要将一些字段标记为需要写入 XML 文件 但没有成功 我有一个包含约 30 个属性的配置类 这就是为什么我不能像这样封装所有属性 public string SomeProp get return someProp set if som
  • 实例化类时重写虚拟方法

    我有一个带有一些虚函数的类 让我们假设这是其中之一 public class AClassWhatever protected virtual string DoAThingToAString string inputString retu
  • 为什么使用小于 32 位的整数?

    我总是喜欢使用最小尺寸的变量 这样效果就很好 但是如果我使用短字节整数而不是整数 并且内存是 32 位字可寻址 这真的会给我带来好处吗 编译器是否会做一些事情来增强内存使用 对于局部变量 它可能没有多大意义 但是在具有数千甚至数百万项的结构
  • 如何在 Linq to SQL 中使用distinct 和 group by

    我正在尝试将以下 sql 转换为 Linq 2 SQL select groupId count distinct userId from processroundissueinstance group by groupId 这是我的代码
  • 当文件流没有新数据时如何防止fgets阻塞

    我有一个popen 执行的函数tail f sometextfile 只要文件流中有数据显然我就可以通过fgets 现在 如果没有新数据来自尾部 fgets 挂起 我试过ferror and feof 无济于事 我怎样才能确定fgets 当
  • C# 中最小化字符串长度

    我想减少字符串的长度 喜欢 这串 string foo Lorem ipsum dolor sit amet consectetur adipiscing elit Aenean in vehicula nulla Phasellus li
  • 如何确定 CultureInfo 实例是否支持拉丁字符

    是否可以确定是否CultureInfo http msdn microsoft com en us library system globalization cultureinfo aspx我正在使用的实例是否基于拉丁字符集 我相信你可以使

随机推荐

  • R语言:cbind()和rbind()

    可以利用函数cbind 和rbind 把向量和矩阵拼成一个新的矩阵 概略地说 cbind 把矩阵横向合并成一个大矩阵 列方式 而rbind 是纵向合并 行方式 cbind 根据列进行合并 即叠加所有列 m列的矩阵与n列的矩阵cbind 最后
  • ant design of vue 之文件上传组件(腾讯云)封装

    原理 通过调用后台接口获取腾讯云秘钥 然后将秘钥以及文件信息上传到腾讯云 获取文件腾讯云存储信息 最后组件将腾讯云存储信息返回出去 在组件外部调用后台接口将腾讯云信息存到后台 安装cos js sdk v5依赖 npm i cos js s
  • 2021数据治理工具图谱研究报告 附下载

    根据2021年4月发布的 国家数据资源调查报告 2020 显示 2019年我国数据产量总规模为3 9ZB 同比增加29 3 占全球数据总产量 42ZB 的9 3 人均数据产量方面 2019年我国人均数据产量为3TB 数据来源结构方面 数据资
  • 机器学习中的高斯过程

    0 前言 写这篇文章的目的就是为了总结一下最近在学习的高斯过程的一些内容 但是由于我是初学者可能有些地方理解不到位 请大家多多谅解 文末附上了一些数学方面的推导 1 高斯过程定义 高斯过程是在连续域上定义的一种随机过程 可以看成连续域中所有
  • vue中通过js把从接口取到的url中的{}里的参数替换成对应的值

    最近工作中遇到个需求 首先在一个页面中给按钮配置个点击跳转的链接 手动输入需要跳转的url及其需要的参数 后续要在另一个页面中通过接口取到配置的这个url 并替换掉当中的参数 第一次处理这种情况 所以记录一下 前端页面配置url 参数值通过
  • 【YOLO系列】YOLOv5超详细解读(网络详解)

    前言 吼吼 终于来到了YOLOv5啦 首先 一个热知识 YOLOv5没有发表正式论文哦 为什么呢 可能YOLOv5项目的作者Glenn Jocher还在吃帽子吧 hh 目录 前言 一 YOLOv5的网络结构 二 输入端 1 Mosaic数据
  • m118w重置墨粉_富士施乐 Fuji Xerox DocuPrint M118w/M118z重置墨粉页面计数器及重置硒鼓...

    富士施乐M118w的硒鼓和分仓是独立的 前几天M118w就提示墨粉已经不足 于是Pop就看了一下机器 打印了约1200张了 随机器来的原装可能就是这样而已 于是就了解了一下富士施乐M118w如何加粉 如何换硒鼓 以及如何清零重置硒鼓的操作
  • Mac os 10.14装virtualbox 失败的解决方案

    1 Mac 系统装virtualbox 失败如下 2 由于Mac 10 14的安全级别更高 所以导致这个软件安装过程失败 需要一下操作安装就没问题 2 1 开启通用里的允许任何来源 sudo spctl master disable 2 2
  • LeetCode 44 Wildcard Matching (通配符匹配 记忆化搜索 剪枝 推荐)

    Given an input string s and a pattern p implement wildcard pattern matching with support for and Matches any single char
  • Freertos中vTaskDelay()是怎么用的

    1 常见的使用场景 void vLED Task void pvParameters while 1 Heartbeat LED vTaskDelay 1000 portTICK RATE MS 说明 上面这段代码的意思是 led翻转后经过
  • Exception in thread "main" java.lang.NoClassDefFoundError解决

    1 错误描述 Exception in thread main java lang NoClassDefFoundError HelloWorld wrong name org xuwei HelloWorld at java lang C
  • 2018年最好的8款杀毒软件

    如今 网络犯罪和欺骗和攻击电脑的病毒 特洛伊木马和网络钓鱼诈骗导致损失的事件并没有像人们想像的那么频繁发生 这意味着很多人正在使用最强大的安全软件保护自己的电脑 而其一如既往地重要 这就是为什么推出这个2018年全球最佳防病毒软件名单的原因
  • 搭建商城的微服务架构-1

    创建父项目 mall 先创建一个 父项目 mall 再在这个父项目中创建多个子项目 修改pom文件 最终mall的pom文件如下
  • 目标检测算法回顾之Anchor free篇章

    基于anchor free的目标检测方法 一 背景与定义 1 1 anchor based的特征 1 2 anchor的好处 1 3 anchor的局限 1 4 anchor free 与anchor based的区别 二 概述 三 早期探
  • 以太坊2.0 节点搭建:共识端+执行端

    1 配置 本人使用配置 共识端 prysm 版本 3 1 1 执行端 geth 版本 1 10 23 当前使用1 10 25 OS centos7 6 CPU 8核 Memory 16GB RAM Storage 3T SSD Networ
  • 算法梳理boosting\bagging\RF(1)

    LeetCode题目记录 1 集成学习概念 1 1 集成学习分类 1 2 集成学习步骤 2 个体学习器概念 3 boosting bagging 3 1 boosting 3 2 bagging 3 3 二者的区别 4 随机森林的思想 5
  • mlxtend实现简单的Apriori算法(关联算法)

    关联算法有几个重要的概念 下面以官方教程为例 Apple Beer Rice Chicken Apple Beer Rice Apple Beer Apple Bananas Milk Beer Rice Chicken Milk Beer
  • springmvc使用JSR-303进行校验

    下面提供一种springmvc的校验方案 一般没有校验或者手动写validator的话都要写好多代码好多if判断 使用JSR 303规范校验只需要在Pojo字段上加上相应的注解就可以实现校验了 1 依赖的jar包 我直接贴pom了
  • cannot find -l 问题处理

    graalvm打包最后一步 第七步 报错 主要错误简述 It appears as though libstdc a is missing Please install it cannot find lstdc 几个要点 1 l是link的
  • c++模板的概念全新解释

    文章目录 前言 一 模板的概念 强类型的严格性和灵活性 解决冲突的路径 模板的概念 一 1 函数模板 函数模板的定义 函数模板的实例化 函数模板的重载 1 函数模板的重载 2 用普通函数重载函数模板 3 用特定函数重载函数模板 类模板 类模