C++ Primer 学习笔记_29_STL实践与分析(3) --顺序容器的操作(下)
2015-06-29 11:28
761 查看
如果容器非空,那么容器类型的front和back成员将返回容器的第一个和最后一个元素的引用。
【与begin和end的对比:】
1)begin和end返回容器类型的迭代器,而不是引用;
2)end返回容器最后一个元素的下一个位置的迭代器,而back返回容器的最后一个元素的引用!
[cpp]
view plaincopyprint?
/*
*必须保证该list容器非空!
*如果容器为空,则if语句内的所有操作都是未定义的!
*/
if (!iList.empty())
{
list<int>::reference bVal1 = *iList.begin();
list<int>::reference bVal2 = iList.front();
list<int>::reference eVal1 = *--iList.end();
list<int>::reference eVal2 = iList.back();
cout << "Begin:" << endl;
cout << bVal1 << endl;
cout << bVal2 << endl;
cout << endl << "End:" << endl;
cout << eVal1 << endl;
cout << eVal2 << endl;
}
使用下标运算的一个可选方案是使用at成员函数,虽然这个函数的行为和下标运算相似,但是如果程序给出的下标无效,at函数会抛出out_of_range异常。
[cpp]
view plaincopyprint?
vector<string> strVec;
cout << strVec[0] << endl; //run-time error
cout << strVec.at(0) << endl; //throw out_of_range
[cpp]
view plaincopyprint?
//P280 习题9.24
int main()
{
vector<string> strVec;
strVec.push_back("o(∩∩)o...");
if (!strVec.empty())
{
cout << strVec.front() << endl;
cout << *strVec.begin() << endl;
string tmp = strVec.at(0);
cout << tmp << endl;
tmp = strVec[0];
cout << tmp << endl;
}
}
七、删除元素
1、删除第一个/最后一个元素
pop_front操作通常与front操作配套使用,实现以栈的方式处理容器:
[cpp]
view plaincopyprint?
while (!iDeq.empty())
{
proccess(iDeq.front());
iDeq.pop_front();
}
【注意:】
pop_front和
pop_back函数的返回值并不是删除的元素值,而是void。要获取删除的元素值,则必须在删除元素之前调用front或
back函数。
2、删除容器内的一个/一段元素
erase的两种形式都返回一个迭代器,它指向被删除元素或元素段后面的元素。也就是说,如果元素j恰好紧跟在元素i后面,则将元素i从容器中删除后,删除操作返回指向j的迭代器。
如同其他操作一样,erase操作也不会检查它的参数。程序员必须确保用作参数的迭代器或迭代器范围是有效的。因此,在删除元素之前,必须确保迭代器不是end迭代器,如果恰巧是end迭代器,则erase的操作未定义!
[cpp]
view plaincopyprint?
void printVec(const vector<string> &strVec)
{
for (vector<string>::const_iterator iter = strVec.begin(); iter != strVec.end(); ++iter)
{
cout << *iter << endl;
}
}
int main()
{
// freopen("input","r",stdin);
vector<string> strVec;
string val;
while (cin >> val)
{
strVec.push_back(val);
}
printVec(strVec);
string searchVal("Quasimodo");
vector<string>::iterator iter = find(strVec.begin(),strVec.end(),searchVal);
if (iter != strVec.end())
{
strVec.erase(iter);
}
printVec(strVec);
}
3、删除容器内的所有元素
[cpp]
view plaincopyprint?
strVec.clear();
strVec.erase(strVec.begin(),strVec.end());
同时,erase函数的迭代器版本也提供了删除部分元素的功能:
[cpp]
view plaincopyprint?
string searchVal("Quasimodo");
vector<string>::iterator iter = find(strVec.begin(),strVec.end(),searchVal);
strVec.erase(strVec.begin(),iter); //不会包含iter指向的元素
printVec(strVec);
如果删除时,两个迭代器指向的元素是同一个元素,则不会删除任何元素;如果两个迭代器指向的元素有一个或两个不存在,则会发生运行时错误:
[cpp]
view plaincopyprint?
strVec.erase(strVec.begin(),strVec.begin());
printVec(strVec);
strVec.erase(strVec.begin(),strVec.end()+1);
printVec(strVec);
【小心地雷o(∩∩)o...,P282】
erase、pop_front和
pop_back函数使指向被删除元素的所有迭代器失效。对于vector容器,指向删除点后面的元素的迭代器通常也会失效。而对于deque容器,如果删除时不包含第一个元素或最后一个元素,那么该deque容器相关的所有迭代器都会失效。
[cpp]
view plaincopyprint?
//P282 习题9.26
void printVecInt(const vector<int> &strVec)
{
for (vector<int>::const_iterator iter = strVec.begin(); iter != strVec.end(); ++iter)
{
cout << *iter << '\t';
}
cout << endl;
}
void printlistInt(const list<int> &strVec)
{
for (list<int>::const_iterator iter = strVec.begin(); iter != strVec.end(); ++iter)
{
cout << *iter << '\t';
}
cout << endl;
}
int main()
{
int ia[] = {0,1,1,2,3,5,8,13,21,55,89};
vector<int> iVec(ia,ia+sizeof(ia)/sizeof(*ia));
list<int> iList(ia,ia+sizeof(ia)/sizeof(*ia));
// printlistInt(iList);
// printVecInt(iVec);
for (vector<int>::iterator iter = iVec.begin(); iter != iVec.end(); ++iter)
{
if (!(*iter % 2))
{
iter = iVec.erase(iter);
-- iter;
}
}
printVecInt(iVec);
for (list<int>::iterator iter = iList.begin(); iter != iList.end(); ++iter)
{
if (*iter % 2)
{
iter = iList.erase(iter);
-- iter;
}
}
printlistInt(iList);
}
[cpp]
view plaincopyprint?
//习题9.27
int main()
{
// freopen("input","r",stdin);
list<string> strList;
string val;
while (cin >> val)
{
strList.push_back(val);
}
string searchVal("dream");
for (list<string>::iterator iter = strList.begin(); iter != strList.end(); ++iter)
{
if (*iter == searchVal)
{
strList.erase(iter);
--iter;
}
}
for (list<string>::iterator iter = strList.begin(); iter != strList.end(); ++iter)
{
cout << *iter << '\t';
}
cout << endl;
}
八、赋值与swap
与赋值相关的操作符都作用于整个容器。除了swap外,其他操作都可以通过erase和insert来替代。赋值操作符首先删除其左操作数容器的所有元素,然后将右操作数容器的所有元素插入到左边容器中:
[cpp]
view plaincopyprint?
vec1 = vec2;
//等效于
vec1.erase(vec1.begin(),vec1.end());
vec1.insert(vec1.begin(),vec2.begin(),vec2.end());
尽管赋值前两个容器的长度可能不相等,但是赋值后两个容器的长度都等于右边容器的长度!
【小心地雷:】
赋值和assign操作使左操作容器的所有迭代器失效,swap操作则不会使迭代器失效。完成swap操作后,尽管被交换的元素已经存放在另一容器中,但迭代器仍然指向相同的元素。
1、使用assign
1)带有一对迭代器参数的assign操作允许我们将一个容器的元素赋给另一个不同类型的容器。但是两种容器类型与元素类型必须相互兼容!
[cpp]
view plaincopyprint?
sList.assign(sVec.begin(),sVec.end());
2)assign运算的第二个版本需要一个整型数值和一个元素值做参数,它将容器重置为存储指定数量的元素,并且每个元素的值都为指定值:
[cpp]
view plaincopyprint?
sList.assign(10,"o(∩∩)o...");
2、使用swap操作以节省删除元素的成本
swap操作实现交换两个容器内所有元素的功能。要交换的容器的类型必须匹配:操作数必须是相同类型的容器,而且所存储的元素类型也必须相同。调用了swap函数后,右操作数原来存储的元素被存放在左操作数中,反之亦然。
[cpp]
view plaincopyprint?
void printListStr(const list<string> &sList)
{
for (list<string>::const_iterator iter = sList.begin(); iter != sList.end(); ++iter)
{
cout << *iter << endl;
}
}
int main()
{
list<string> sList1(3,"o(∩∩)o...");
list<string> sList2(4,"(*^__^*)");
cout << "sList1:" << endl;
printListStr(sList1);
cout << "sList2:" << endl;
printListStr(sList2);
sList1.swap(sList2);
cout << "sList1:" << endl;
printListStr(sList1);
cout << "sList2:" << endl;
printListStr(sList2);
}
关于swap的一个重要问题在于:该操作不会删除或插入任何元素,而且保证在常量时间内实现交换。由于容器内没有移动任何元素,因此迭代器不会失效。
没有移动元素这个事实意味着迭代器不会失效。它们指向同一元素,就像没作swap运算之前一样。虽然,在swap运算后,这些元素已经被存储在不同的容器之中了。例如,在做
swap运算之前,有一个迭代器iter指向
svec1[3]字符串;实现swap运算后,该迭代器则指向svec2[3]字符串(这是同一个字符串,只是存储在不同的容器之中而已)。
[cpp]
view plaincopyprint?
vector<string> sVec1(4,"o(∩∩)o...");
vector<string> sVec2(3,"(*^__^*)");
vector<string>::iterator iter = sVec1.end() - 1;
cout << *iter << endl;
sVec1.swap(sVec2);
cout << *iter << endl;
[cpp]
view plaincopyprint?
//P284 习题9.28
void printListStr(const list<string> &sList)
{
for (list<string>::const_iterator iter = sList.begin(); iter != sList.end(); ++iter)
{
cout << *iter << endl;
}
}
STL实践与分析
--顺序容器的操作(下)
六、访问元素如果容器非空,那么容器类型的front和back成员将返回容器的第一个和最后一个元素的引用。
【与begin和end的对比:】
1)begin和end返回容器类型的迭代器,而不是引用;
2)end返回容器最后一个元素的下一个位置的迭代器,而back返回容器的最后一个元素的引用!
[cpp]
view plaincopyprint?
/*
*必须保证该list容器非空!
*如果容器为空,则if语句内的所有操作都是未定义的!
*/
if (!iList.empty())
{
list<int>::reference bVal1 = *iList.begin();
list<int>::reference bVal2 = iList.front();
list<int>::reference eVal1 = *--iList.end();
list<int>::reference eVal2 = iList.back();
cout << "Begin:" << endl;
cout << bVal1 << endl;
cout << bVal2 << endl;
cout << endl << "End:" << endl;
cout << eVal1 << endl;
cout << eVal2 << endl;
}
/* *必须保证该list容器非空! *如果容器为空,则if语句内的所有操作都是未定义的! */ if (!iList.empty()) { list<int>::reference bVal1 = *iList.begin(); list<int>::reference bVal2 = iList.front(); list<int>::reference eVal1 = *--iList.end(); list<int>::reference eVal2 = iList.back(); cout << "Begin:" << endl; cout << bVal1 << endl; cout << bVal2 << endl; cout << endl << "End:" << endl; cout << eVal1 << endl; cout << eVal2 << endl; }
访问顺序容器内元素的操作 | |
---|---|
c.back() | 返回容器c的最后一个元素的引用,如果c为空,则该操作未定义 |
c.front() | 返回容器c的第一个元素的引用,如果c为空,则该操作未定义 |
c | 返回下标n的元素的引用,如果n<0或n>=c.size(),则该操作未定义 只适用于vector和deque容器 |
c.at(n) | 返回下标为n的元素的引用,如果下标越界,则该操作未定义 只适用于vector和deque容器 |
[cpp]
view plaincopyprint?
vector<string> strVec;
cout << strVec[0] << endl; //run-time error
cout << strVec.at(0) << endl; //throw out_of_range
vector<string> strVec; cout << strVec[0] << endl; //run-time error cout << strVec.at(0) << endl; //throw out_of_range
[cpp]
view plaincopyprint?
//P280 习题9.24
int main()
{
vector<string> strVec;
strVec.push_back("o(∩∩)o...");
if (!strVec.empty())
{
cout << strVec.front() << endl;
cout << *strVec.begin() << endl;
string tmp = strVec.at(0);
cout << tmp << endl;
tmp = strVec[0];
cout << tmp << endl;
}
}
//P280 习题9.24 int main() { vector<string> strVec; strVec.push_back("o(∩∩)o..."); if (!strVec.empty()) { cout << strVec.front() << endl; cout << *strVec.begin() << endl; string tmp = strVec.at(0); cout << tmp << endl; tmp = strVec[0]; cout << tmp << endl; } }
七、删除元素
删除顺序容器内元素的操作 | |
---|---|
c.erase(p) | 删除迭代器p所指向的元素 返回一个迭代器,它指向被删除元素后面的元素。如果p指向容器内的最后一个元素,则返回的迭代器指向容器的超出末端的下一位置。如果p本身就是指向超出末端的下一位置的迭代器,则该函数未定义 |
c.erase(b,e) | 删除迭代器b和e所标记的范围内所有的元素 返回一个迭代器,它指向被删除元素段后面的元素。如果e本身就是指向超出末端的下一位置的迭代器,则返回的迭代器也指向容器的超出末端的下一位置 |
c.clear() | 删除容器c内的所有元素。返回void |
c.pop_back() | 删除容器c的最后一个元素。返回void。如果c为空容器, 则该函数未定义 |
c.pop_front() | 删除容器c的第一个元素。返回void。如果c为空容器,则该函数未定义 只适用于list或deque容器 |
pop_front操作通常与front操作配套使用,实现以栈的方式处理容器:
[cpp]
view plaincopyprint?
while (!iDeq.empty())
{
proccess(iDeq.front());
iDeq.pop_front();
}
while (!iDeq.empty()) { proccess(iDeq.front()); iDeq.pop_front(); }
【注意:】
pop_front和
pop_back函数的返回值并不是删除的元素值,而是void。要获取删除的元素值,则必须在删除元素之前调用front或
back函数。
2、删除容器内的一个/一段元素
erase的两种形式都返回一个迭代器,它指向被删除元素或元素段后面的元素。也就是说,如果元素j恰好紧跟在元素i后面,则将元素i从容器中删除后,删除操作返回指向j的迭代器。
如同其他操作一样,erase操作也不会检查它的参数。程序员必须确保用作参数的迭代器或迭代器范围是有效的。因此,在删除元素之前,必须确保迭代器不是end迭代器,如果恰巧是end迭代器,则erase的操作未定义!
[cpp]
view plaincopyprint?
void printVec(const vector<string> &strVec)
{
for (vector<string>::const_iterator iter = strVec.begin(); iter != strVec.end(); ++iter)
{
cout << *iter << endl;
}
}
int main()
{
// freopen("input","r",stdin);
vector<string> strVec;
string val;
while (cin >> val)
{
strVec.push_back(val);
}
printVec(strVec);
string searchVal("Quasimodo");
vector<string>::iterator iter = find(strVec.begin(),strVec.end(),searchVal);
if (iter != strVec.end())
{
strVec.erase(iter);
}
printVec(strVec);
}
void printVec(const vector<string> &strVec) { for (vector<string>::const_iterator iter = strVec.begin(); iter != strVec.end(); ++iter) { cout << *iter << endl; } } int main() { // freopen("input","r",stdin); vector<string> strVec; string val; while (cin >> val) { strVec.push_back(val); } printVec(strVec); string searchVal("Quasimodo"); vector<string>::iterator iter = find(strVec.begin(),strVec.end(),searchVal); if (iter != strVec.end()) { strVec.erase(iter); } printVec(strVec); }
3、删除容器内的所有元素
[cpp]
view plaincopyprint?
strVec.clear();
strVec.erase(strVec.begin(),strVec.end());
strVec.clear(); strVec.erase(strVec.begin(),strVec.end());
同时,erase函数的迭代器版本也提供了删除部分元素的功能:
[cpp]
view plaincopyprint?
string searchVal("Quasimodo");
vector<string>::iterator iter = find(strVec.begin(),strVec.end(),searchVal);
strVec.erase(strVec.begin(),iter); //不会包含iter指向的元素
printVec(strVec);
string searchVal("Quasimodo"); vector<string>::iterator iter = find(strVec.begin(),strVec.end(),searchVal); strVec.erase(strVec.begin(),iter); //不会包含iter指向的元素 printVec(strVec);
如果删除时,两个迭代器指向的元素是同一个元素,则不会删除任何元素;如果两个迭代器指向的元素有一个或两个不存在,则会发生运行时错误:
[cpp]
view plaincopyprint?
strVec.erase(strVec.begin(),strVec.begin());
printVec(strVec);
strVec.erase(strVec.begin(),strVec.end()+1);
printVec(strVec);
strVec.erase(strVec.begin(),strVec.begin()); printVec(strVec); strVec.erase(strVec.begin(),strVec.end()+1); printVec(strVec);
【小心地雷o(∩∩)o...,P282】
erase、pop_front和
pop_back函数使指向被删除元素的所有迭代器失效。对于vector容器,指向删除点后面的元素的迭代器通常也会失效。而对于deque容器,如果删除时不包含第一个元素或最后一个元素,那么该deque容器相关的所有迭代器都会失效。
[cpp]
view plaincopyprint?
//P282 习题9.26
void printVecInt(const vector<int> &strVec)
{
for (vector<int>::const_iterator iter = strVec.begin(); iter != strVec.end(); ++iter)
{
cout << *iter << '\t';
}
cout << endl;
}
void printlistInt(const list<int> &strVec)
{
for (list<int>::const_iterator iter = strVec.begin(); iter != strVec.end(); ++iter)
{
cout << *iter << '\t';
}
cout << endl;
}
int main()
{
int ia[] = {0,1,1,2,3,5,8,13,21,55,89};
vector<int> iVec(ia,ia+sizeof(ia)/sizeof(*ia));
list<int> iList(ia,ia+sizeof(ia)/sizeof(*ia));
// printlistInt(iList);
// printVecInt(iVec);
for (vector<int>::iterator iter = iVec.begin(); iter != iVec.end(); ++iter)
{
if (!(*iter % 2))
{
iter = iVec.erase(iter);
-- iter;
}
}
printVecInt(iVec);
for (list<int>::iterator iter = iList.begin(); iter != iList.end(); ++iter)
{
if (*iter % 2)
{
iter = iList.erase(iter);
-- iter;
}
}
printlistInt(iList);
}
//P282 习题9.26 void printVecInt(const vector<int> &strVec) { for (vector<int>::const_iterator iter = strVec.begin(); iter != strVec.end(); ++iter) { cout << *iter << '\t'; } cout << endl; } void printlistInt(const list<int> &strVec) { for (list<int>::const_iterator iter = strVec.begin(); iter != strVec.end(); ++iter) { cout << *iter << '\t'; } cout << endl; } int main() { int ia[] = {0,1,1,2,3,5,8,13,21,55,89}; vector<int> iVec(ia,ia+sizeof(ia)/sizeof(*ia)); list<int> iList(ia,ia+sizeof(ia)/sizeof(*ia)); // printlistInt(iList); // printVecInt(iVec); for (vector<int>::iterator iter = iVec.begin(); iter != iVec.end(); ++iter) { if (!(*iter % 2)) { iter = iVec.erase(iter); -- iter; } } printVecInt(iVec); for (list<int>::iterator iter = iList.begin(); iter != iList.end(); ++iter) { if (*iter % 2) { iter = iList.erase(iter); -- iter; } } printlistInt(iList); }
[cpp]
view plaincopyprint?
//习题9.27
int main()
{
// freopen("input","r",stdin);
list<string> strList;
string val;
while (cin >> val)
{
strList.push_back(val);
}
string searchVal("dream");
for (list<string>::iterator iter = strList.begin(); iter != strList.end(); ++iter)
{
if (*iter == searchVal)
{
strList.erase(iter);
--iter;
}
}
for (list<string>::iterator iter = strList.begin(); iter != strList.end(); ++iter)
{
cout << *iter << '\t';
}
cout << endl;
}
//习题9.27 int main() { // freopen("input","r",stdin); list<string> strList; string val; while (cin >> val) { strList.push_back(val); } string searchVal("dream"); for (list<string>::iterator iter = strList.begin(); iter != strList.end(); ++iter) { if (*iter == searchVal) { strList.erase(iter); --iter; } } for (list<string>::iterator iter = strList.begin(); iter != strList.end(); ++iter) { cout << *iter << '\t'; } cout << endl; }
八、赋值与swap
顺序容器的赋值与swap操作 | |
---|---|
c1= c2 | 删除容器c1的所有元素,然后将c2的元素复制给c1。 c1和c2的类型(包括容器类型和元素类型)必须相同 |
c.assign(b,e) | 重新设置c的元素:将迭代器b和e标记的范围内所有的元素复制到c中。b和e必须不是指向c中元素的迭代器 |
c.assign(n,t) | 将容器c重新设置为存储n个值为t的元素 |
c1.swap(c2) | 交换内容:调用完该函数后,c1中存放的是c2原来的元素,c2中存放的则是c1原来的元素。 c1和c2的类型必须相同。 该函数的执行速度通常要比将c2复制到c1的操作快 |
[cpp]
view plaincopyprint?
vec1 = vec2;
//等效于
vec1.erase(vec1.begin(),vec1.end());
vec1.insert(vec1.begin(),vec2.begin(),vec2.end());
vec1 = vec2; //等效于 vec1.erase(vec1.begin(),vec1.end()); vec1.insert(vec1.begin(),vec2.begin(),vec2.end());
尽管赋值前两个容器的长度可能不相等,但是赋值后两个容器的长度都等于右边容器的长度!
【小心地雷:】
赋值和assign操作使左操作容器的所有迭代器失效,swap操作则不会使迭代器失效。完成swap操作后,尽管被交换的元素已经存放在另一容器中,但迭代器仍然指向相同的元素。
1、使用assign
1)带有一对迭代器参数的assign操作允许我们将一个容器的元素赋给另一个不同类型的容器。但是两种容器类型与元素类型必须相互兼容!
[cpp]
view plaincopyprint?
sList.assign(sVec.begin(),sVec.end());
sList.assign(sVec.begin(),sVec.end());
2)assign运算的第二个版本需要一个整型数值和一个元素值做参数,它将容器重置为存储指定数量的元素,并且每个元素的值都为指定值:
[cpp]
view plaincopyprint?
sList.assign(10,"o(∩∩)o...");
sList.assign(10,"o(∩∩)o...");
2、使用swap操作以节省删除元素的成本
swap操作实现交换两个容器内所有元素的功能。要交换的容器的类型必须匹配:操作数必须是相同类型的容器,而且所存储的元素类型也必须相同。调用了swap函数后,右操作数原来存储的元素被存放在左操作数中,反之亦然。
[cpp]
view plaincopyprint?
void printListStr(const list<string> &sList)
{
for (list<string>::const_iterator iter = sList.begin(); iter != sList.end(); ++iter)
{
cout << *iter << endl;
}
}
int main()
{
list<string> sList1(3,"o(∩∩)o...");
list<string> sList2(4,"(*^__^*)");
cout << "sList1:" << endl;
printListStr(sList1);
cout << "sList2:" << endl;
printListStr(sList2);
sList1.swap(sList2);
cout << "sList1:" << endl;
printListStr(sList1);
cout << "sList2:" << endl;
printListStr(sList2);
}
void printListStr(const list<string> &sList) { for (list<string>::const_iterator iter = sList.begin(); iter != sList.end(); ++iter) { cout << *iter << endl; } } int main() { list<string> sList1(3,"o(∩∩)o..."); list<string> sList2(4,"(*^__^*)"); cout << "sList1:" << endl; printListStr(sList1); cout << "sList2:" << endl; printListStr(sList2); sList1.swap(sList2); cout << "sList1:" << endl; printListStr(sList1); cout << "sList2:" << endl; printListStr(sList2); }
关于swap的一个重要问题在于:该操作不会删除或插入任何元素,而且保证在常量时间内实现交换。由于容器内没有移动任何元素,因此迭代器不会失效。
没有移动元素这个事实意味着迭代器不会失效。它们指向同一元素,就像没作swap运算之前一样。虽然,在swap运算后,这些元素已经被存储在不同的容器之中了。例如,在做
swap运算之前,有一个迭代器iter指向
svec1[3]字符串;实现swap运算后,该迭代器则指向svec2[3]字符串(这是同一个字符串,只是存储在不同的容器之中而已)。
[cpp]
view plaincopyprint?
vector<string> sVec1(4,"o(∩∩)o...");
vector<string> sVec2(3,"(*^__^*)");
vector<string>::iterator iter = sVec1.end() - 1;
cout << *iter << endl;
sVec1.swap(sVec2);
cout << *iter << endl;
vector<string> sVec1(4,"o(∩∩)o..."); vector<string> sVec2(3,"(*^__^*)"); vector<string>::iterator iter = sVec1.end() - 1; cout << *iter << endl; sVec1.swap(sVec2); cout << *iter << endl;
[cpp]
view plaincopyprint?
//P284 习题9.28
void printListStr(const list<string> &sList)
{
for (list<string>::const_iterator iter = sList.begin(); iter != sList.end(); ++iter)
{
cout << *iter << endl;
}
}
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- Jquery 表单取值赋值的一些基本操作
- Lua教程(一):在C++中嵌入Lua脚本
- Lua教程(二):C++和Lua相互传递数据示例
- PowerShell中定义多个变量并赋值的例子
- C++联合体转换成C#结构的实现方法
- C++编写简单的打靶游戏
- C++变位词问题分析
- C/C++数据对齐详细解析
- C++基于栈实现铁轨问题
- C++中引用的使用总结
- C++中调用Lua函数实例
- Lua和C++的通信流程代码实例
- C与C++之间相互调用实例方法讲解
- C++中拷贝构造函数的应用详解
- C++中引用(&)的用法与应用实例分析
- 浅析STL中的常用算法