C 11学习笔记 9

发布 2022-06-17 16:01:28 阅读 1475

大多数算法都是定义在头文件algorithm中。标准库还在头文件numeric中定义了一组数值泛型算法。

算法不依赖于容器,但依赖于元素类型。

泛型算法本身不会执行容器的操作,它们只会运行于迭代器之上,执行迭代器的操作。因此,算法不会改变底层容器的大小。

find(bigin(ia),end(ia),val);

int sum=accumulate( )0);

这条语句将sum设置为vec中元素的和,和的初始值为0,第三个参数说明了函数中使用哪个加法运算符以及返回值得类型。

vec中的元素必须可以是int,或者是double,long long或者其他任何可以加到int上的类型,string sum = accumulate( )string正确。

string sum = sccumulate( "错误,const char*上么有定义+运算符。

另一个只读算法equal(),用于确定两个序列是否保存相同的值。

equal(

两个容器的元素不必一样,只要可以用==比较。而且有一个假设,第二个序列至少与第一个序列一样长。

写入元素:fill( 0);

vector vec; /空vector;

fill_n( ,10,0); 灾难,修改vec中不存在的元素。

fill_n ( 0 );将所有元素置零。

插入迭代器 back_inserter,定义在头文件iterator中的一个函数。接受一个指向容器额引用。返回一个与该容器绑定的插入迭代器。

vector vec;

auto it=back_inserter(vec);

it = 42;

vectorvec://空向量。

fill_n(back_inserter(vec) ,10 ,0);/正确,back_inserter创建一个插入迭代器,可用来添加元素。

int a1[ ]

int a2[sizeof(a1)/sizeof(*a1)];a2 和 a1大小一样。

/ ret指向拷贝到a2的尾元素之后的位置。

auto ret = copy(begin(a1), end(a1), a2);

前两个迭代器是被拷贝元素范围,第三个是目的序列的其实位置。

replace(将所有的0都替换为42;

replace_copy( 0, 42);

ilist中的元素不变,ivec包含ilst的一份拷贝,不过原来在ilst中的值为0的元素用42替换。

sort 用元素类型的《来实现排序。

重排容器元素的算法:

void elimdups(vector &words)

sort(auto end_unique = unique(将重复元素移到末尾,并返回最后一个不重复元素之后的位置。

删除元素。标准库算法对迭代器而不是容器进行操作。因此,算法不能(直接)添加或删除元素。删除是调用成员函数。

若果使用sort时,比较元素么有定义< 我们可以使用谓词:一个可调用的表达式,其返回结果是一个能用作条件的值。

一元谓词,意味着只接受单一参数,二元谓词,元素类型必须可以转换成谓词的参数,定义的是元素之间的一种关系。

bool isshorter (const string &s1,const string &s2)

return <

sort(通常我们不在意排序时相等元素的相对位置,但是我们可以通过stable_sort这种稳定的排序算法来排序,保证排序后相等元素相对位置不变。

elimdups(words);

stable_sort(

for(const auto &s : words)

cout<< s <<

cout

它返回第一个使谓词返回非0值得元素,如果不存在则返回尾迭代器,find_if接受的一元谓词。

对于一个对象或表达式,如果可以对其使用调用运算符,则称它为可调用的。如果e是一个可调用的表达式,则我们可以编写**e(args),args是用逗号分隔的参数列表。

可调用的对象:函数,函数指针,重载了函数调用符的类,lambda表达式。

一个lambda表达式表示一个可调用的**单元。我们可以将其理解为一个未命名的内联函数。

capature list](parameter) -return type

capture list (捕获列表) 是一个lambda所在函数中定义的局部变量的列表(通常为空),lambda表达式必须使用尾置返回。

auto f = 我们定义了可调用对象f,不接受参数,返回42;

cout<< f() 如果忽略返回类型,函数体中只有一个return,lambda根据函数中的**推断出返回类型,如果lambda的函数体包含任何单一return 语句之外的内容,且未指定返回类型,则返回void

lambda不能有默认参数,因此一个lambda调用的实参数目永远和形参数目相等。

空的捕获列表表示lambda不使用它所在函数中的任何局部变量。

一个lambda表达式通过局部变量包含在捕获列表中来指出将会使用这些变量。

sz](const string &a) ;注意,花括号后的分号!

auto wc = find_if( )words. end( )sz](const string &a)

for_each(wc , string &a));

cout<完整的biggles:

string make_plural(size_t ctr, const string &word, const string &ending)

return (ctr > 1) ?word + ending : word;

void biggies ( vector &words, vector::size_type sz)

elimdups(words); 将words按字典顺序排序,删除重复单词。

stable_sort( )const string& a ,const string &b)

);/获得一个迭代器,指向第一个满足size() sz 的元素。

auto count = wc;

cout<< count <

当定义一个lambda时,编译器会生成以个与lambda对应的新的(未命名)类类型。当使用lambda初始化的变量时,定义一个从lambda生成的对象。默认情况,从lambda生成的类包含一个对应这个lambda所捕获的变量的数据成员,类似普通成员,lambda的数据成员也在lambda对象被创建时被初始化。

捕获变量的值在lambda创建时拷贝,因而随后对变量的修改不会影响到对应lambda内对应的值。

auto f2 = v1] ;返回的是v1指向的对象的值。

io对象不可拷贝,所以对于io对象来说,我们就可以用引用来传递了。特别的,对于捕获引用来说,必须保证引用是存在的,且有预期的值。

C11学习笔记 5

参数传递时,如果是引用类型,它将绑定到对应的实参上,否者,将实参的值拷贝后赋给形参。引用可避免拷贝,如果不需要改变参数,最好定义成常量引用。和其他初始化一样,当用实参初始化时会忽略顶层const,当形参有顶层const时,传给它常量对象或非常量对象都可以。我们可以用非常量初始化一个底层const对象...

C 11学习笔记 11

动态分配的内存,只有在显式释放是,这些对象才会销毁。但是标准库中的两智能指针可以确保自动释放。除了静态内存和栈内存,每个程序还拥有一个内存池。这部分内存被称作自由空间或堆。静态内存用来保存局部static对象 类static数据成员以及定义在任何函数之外的变量。栈内存用来保存定义在函数没得非stat...

C 11学习笔记 16

tuple是类型pair的模板。不同tuple类型的成员类型也不同,但一个tuple可以有任意数量的成员。每个确定的tuple类型的成员数目是固定的。当我们希望将一些数据组合成单一对象,但有不想麻烦地定义一个新数据结构来表示时,tuple是非常有用的。快速而随意 的数据结构 tuple类型及其伴随类...