Effective STL 学习笔记 Item 16:vector, string & C API
有时需要支持 C 的接口,但这并不复杂。
对于 vector 来讲, \(v[0]\) 的地址 \(\&v[0]\) 即可作为数组指针传递给 C API:
1: // Legacy C API.
2: extern void doSomething(const int* pInts, size_t numInts);
3:
4: vector<int> v;
5: // ...
6: // Operations on v.
7: // ...
8:
9: if (!v.empty())
10: {
11: doSomething(&v[0], v.size());
12: }
也许有人会说:可以用 v.begin() 来替代 \(\&v[0]\), 但并非永远如此, v.begin() 返回的是一个迭,迭代器指向的对象的地址才是真正的 \(\&v[0]\) ,即:
&*v.begin() == &v[0]
String 对象没有要求保证所有字符串都存放在连续的内存空间,而且 string 内部不会保证内存中对象会以 NULL 结尾,上面对 \(\&v[0]\) 的方法对 string 不一定行得通,对 string 来讲,我们应该使用它提供的成员函数: c_str() , 下面的代码中无需检查 ss 是否为空,因为如果 ss 为空, ss.c_str() 会返回 NULL 。
13: // Legacy C API:
14: extern void doSomething(const char* str);
15:
16: string ss;
17: // ...
18: // Do something with ss
19: // ...
20:
21: doSomething(ss.c_str());
注意第 2 和第 14 行中 C API 中的 const 限定符,调用的函数不应该修改指针指向的内容,但如果我们需要通过调用 C API 来初始化 vector 或 string,应该怎么做?
对于 vector 来讲, Item 14 提到,通过 reserve() 可以预留出足够的空间,而且是连续空间,这样我们可以在调用 C API 进行初始化之前来分配好足够空间,并在初始化之后调用 resize() 来改变容器的大小:
// C API: this function takes a pointer to an array of at most arraySize
// doubles and writes data to it. It returns the number of doubles written,
// which is never more than maxNumDoubles.
size_t fillArray(double *pArray, size_t arraySize); vector<double> vd;
vd.reserve(maxNumDoubles);
vd.resize(fillArray(&vd[0], maxNumDoubles))
或者更简单的:
vector<double> vd(maxNumDouble);
vd.resize(fillArray(&vd[0], vd.size()));
String 提供的 c_str() 指向的指针是只读的,不能将其传给 C API 进行初始化,但我们可以通过前面提到的方法:将 vector<char> 的指针传给 C API,然后再用这个 vector 来初始化 string
// C API: this function takes a pointer to an array of at most arraySize
// chars and writes data to it. It returns the number of chars written,
// which is never more than maxNumChars. size_t fillString(char* pArray, size_t arraySize); vector<char> vc(maxNumChars);
size_t charsWritten = fillString(&vc[0], vc.size());
string s(vc.begin(), vc.begin()+charsWritten));
上面的这个技巧,可以适用于任何的容器,例如如果我们想用 C API 来初始化一个 set:
size_t doSomething(int* pints, size_t numInts); // C API to initialize int array.
vector<int> v(maxNumInts); // This is media
size_t sz = doSomething(&v[0], v.size());
set<int> intSet(v.begin(), v.begin()+sz);
(使用许可:署名-非商业性使用-相同方式共享 3.0 中国大陆许可协议 。)
Effective STL 学习笔记 Item 16:vector, string & C API的更多相关文章
- Effective STL 学习笔记: 多用 vector & string
Effective STL 学习笔记: 多用 vector & string 如果可能的话, 尽量避免自己去写动态分配的数组,转而使用 vector 和 string . 原书作者唯一想到的一 ...
- Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据
Effective STL 学习笔记 Item 34: 了解哪些算法希望输入有序数据 */--> div.org-src-container { font-size: 85%; font-fam ...
- Effective STL 学习笔记 Item 30: 保证目标区间足够大
Effective STL 学习笔记 Item 30: 保证目标区间足够大 */--> div.org-src-container { font-size: 85%; font-family: ...
- Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor
Effective STL 学习笔记 Item 26: Prefer Iterator to reverse_iterator and const_rever_itertor */--> div ...
- Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value
Effective STL 学习笔记 Item 38 : Design functor classes for pass-by-value */--> div.org-src-container ...
- Effective STL 学习笔记 Item 21:Comparison Function 相关
Effective STL 学习笔记 Item 21:Comparison Function 相关 */--> div.org-src-container { font-size: 85%; f ...
- Effective STL 学习笔记 Item 18: 慎用 vector<bool>
vector<bool> 看起来像是一个存放布尔变量的容器,但是其实本身其实并不是一个容器,它里面存放的对象也不是布尔变量,这一点在 GCC 源码中 vector<bool> ...
- Effective STL 学习笔记 Item 17: Swap Trick
假设有若干对象存于一个 vector 中: class Widget; vector<Widget> vw; 后来由于某些原因,从该容器中删除了若干对象(参考erase-remove id ...
- Effective STL 学习笔记: Item 22 ~ 24
Effective STL 学习笔记: Item 22 ~ 24 */--> div.org-src-container { font-size: 85%; font-family: monos ...
随机推荐
- ASP.NET MVC 3 常用
http://blog.csdn.net/churujianghu/article/details/7297358 1.ASP.NET MVC 3 如何去除默认验证 这个默认验证是在web.confi ...
- STM32 ------ HardFault_Hander 中断函数
1.数组越界(对数组赋值) 正常情况,数组越界会进入 HardFault_Hander 中断函数的无线循环. 避免数组越界的一个方法是:每次使用数组前,检查要放入数据的数据长度是否大于数组长度,大于则 ...
- 初学SQL语句练习1
--[1 ]查询出每个月倒数第三天受雇的所有员工SELECT * FROM EMP WHERE HIREDATE=LAST_DAY(HIREDATE)-2; --[2 ]找出早于30 年前受雇的员工S ...
- Oracle的基本语法,存储函数及触发器
1.PL/SQL PL/SQL是Oracle对 ql语言的过程化扩展,指在 SQL 命令语言中增加了过程处理语句,使SQL语言具有过程处理能力.把 SQL 语言的数据操纵能 力与过程语言的数据 ...
- python字符中加入变量
有时候,我们需要在字符串中加入相应的变量,以下提供了几种字符串加入变量的方法: 1.+ 连字符 name = 'zhangsan' print('my name is '+name) #结果为 my ...
- iview组件 eslint校验出错 Parsing error: x-invalid-end-tag
如下: 解决: 在.eslintrc.js文件中加上: rules: { // allow async-await 'generator-star-spacing': 'off', // allow ...
- highCharts参数实例解释
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...
- Java压缩/解压.zip、.tar.gz、.tar.bz2(支持中文)
本文介绍Java压缩/解压.zip..tar.gz..tar.bz2的方式. 对于zip文件:使用java.util.zip.ZipEntry 和 java.util.zip.ZipFile,通过设置 ...
- ASP.NET对无序列表批量操作的三种方法
在网页开发中,经常要用到无序列表.事实上在符合W3C标准的div+css布局中,无序列表被大量使用,ASP.NET虽然内置了BulletedList控件,用于创建和操作无序列表,但感觉不太好用.本篇介 ...
- 38、使用IO流进行文件拷贝
使用IO流进行文件拷贝 需求:在项目的根目录里面创建一个java.txt的文件,然后将这个文件拷贝到file文件夹里面并且重命名为good.txt文件先以流的方式将java.txt文件读取到内存中,然 ...