【修炼C++】基础知识点笔记-第3章 字符串,向量和数组

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/albert19891108/article/details/84112172

重新学习c++的东西,此为《C++ Primer》读书笔记,主要记录零碎的知识。另外所有的C++11新标准也会被列出。

1,位于头文件的代码一般来说不应该使用using声明。这是因为头文件的内容会拷贝到所有引用它的文件中。

2,拷贝 初始化,直接初始化。【???】

3,string对象上的操作

os<<s                         将s写到输出流os当中,返回os

is>>s                          从is中读取字符串赋给s,字符串以空白分隔,返回is

getline(is,s)                从is中读取一行赋值给是,返回is

注意

(1)这三个操作的返回值,这使得多个输入和多个输出可以连起来写

string s1,s2;
cin>>s1>>s2; //将第一个输入读到s1中,第二个输入读到s2中。
cout<<s1<<s2;

(2)在执行读取操作(<<)时,string对象会自动忽略开头的空白(即空格符,换行符,制表符等)并从第一个真正的字符开始读起,直到遇到下一个空白为止。

(3)getline(is,s) 没有上边的问题,可以完整读取一行,知道遇到换行符号。

(4)上述操作返回的是流参数,所以可以作为判断条件读取未知长度或者是未知行数的字符串。知道其返回非法输入或者是文件结束。

4 string::size_type类型

s.empty()                      判断一个字符串是否为空

s.size()                          返回s中字符的个数

(1)size()函数返回值为string::size_type类型的值,它是一个无符号类型的值而且能足够放下任何string对象的大小。为了不产生潜在的问题,那么如果一条表达式中已经有了size()函数就不要再使用int了。

5、C++11新标准范围for(range for)语句范围for语句:遍历给定序列中的每个元素并对序列中的每个值执行某种操作,其语法形式为:

       for(declaration:expression)

             statement

expression 表示的必须是一个序列,比如花括号括起来的初始值列表、数组、或者vector或string等类型的对象,这些类型 的共同特点是拥有能返回迭代器的begin和end

每次迭代,declaration 部分的变量会被初始化为expression部分的下一个元素值,但是看第二个例子对引用类型进行初始化(这样可以修改序列中的值),则应该是什么类型呢?另一个变量。

注意:范围for语句不可以用于增加vector对象的元素,因为在范围for语句中,预存了end()的值,一旦序列中添加或者删除了元素,end函数可能变得无效。

string s("Hello World!!!");

decltype(s.size()) punct_cnt = 0;

for(auto c : s)
    if(ispunct(s))
        ++punct_cnt;

cout<<punct_cnt
    <<"punctuation characters in "<<s<<endl;

//为了改变string对象中字符的值,把循环变量定义成引用类型。
for(auto&c : s)
    c =toupper(c);
cout<<s<<endl;

6、vector能容纳绝大多数类型的对象作为其元素,但是因为引用不是对象,所以不存在包含引用的vector。除此之外,其他大多数内置类型和类类型都可以构成vector对象,甚至组成vector的元素也可以是vector。

/*初始化vector对象的方法*/
vector<T> v1                /*v1是一个空vector,它潜在的元素是T类型的,执行默认的初始化*/
vector<T> v2(v1)            /*v2中包含有v1所有元素的副本*/
vector<T> v2=v1             /*等价于v2(v1),v2中包含v1所有元素的副本*/
vector<T> v3(n,val)         /*v3包含n个重复的元素,每个元素的值都是val*/
vector<T> v4(n)             /*v4包含那个重复执行了值初始化的对象*/
vector<T> v5{a,b,c...}      /*v5包含了初始值个数的元素,每个元素被赋予相应的初始值*/
vector<T> v5={a,b,c...}     /*等价于v5{a,b,c...}*/

7、在某些情况下,初始化的真实含义依赖于传递初始值时用的是花括号还是圆括号。如果用的是花括号,初始化过程中尽可能地把花括号内的值当成是元素初始值的列表来处理,只有无法执行列表初始化时才会考虑其他初始化方式。

vector<string> v5{"hi"}        /*列表初始化:v5有一个元素*/
vector<string> v6("hi")        /*错误:不能用字符串字面值构建vector对象*/
vector<string> v7{10}          /*v7 有10个默认初始化的元素*/
vector<string> v8{10,"hi"}     /*v8有10个值为“hi”的元素*/

8,只允许对已存在的元素执行下标操作,对vector如此,对string也是如此,注意不可以用下标操作对元素进行赋值。

9,有效的迭代器或者指向某个元素,或者指向容器中尾元素的下一个位置end迭代器或者叫尾迭代器(off-the-end iterator)。

10,迭代器类型,iterator 和 const_iterator。

const_iterator 和常量指针差不多,能读取但不能修改它所指的元素值。若vector或者string对象是一个常量,则只能用const_iterator;

对于begin和end,其返回的具体类型由对象是否是常量决定。如果对象是常量,则返回const_iterator;若对象不是常量,返回iterator。

C++11新标准,引进cbegin和cend两个新函数,针对对象只需要读操作而无须写操作的行为。

11,C++语言定义了箭头运算符(->),箭头运算符把解引用和成员访问两个操作结合在一起,也就是说it->mem和(*it).mem()表达的意思相同

12,二分搜索程序中,使用mid=beg+(end-beg)/2

//使用迭代器完成二分搜索

//text 必须是有序的
//beg和end表示我们搜索的范围

auto beg = text.begin(),end = text.end();
auto mid = beg +(end-beg)/2;//初始状态下的中间点

//当还有元素尚未检查并且我们还没有找到sought时执行循环
while(mid!=end && *mid!=sought)
{
    if(sought<*mid)
        end=mid;
    else
        begin = mid+1;
    mid = beg+(end-beg)/2;         //新的中间点
}

13,数组中元素的个数也属于数组类型的一部分,编译时维度应该是已知的。因此,维度必须是一个常量表达式。数组与vector不同的一点是数组在定义时大小确定不变,vector在运行时可以动态调整, 也有维度限制。

14,

int *ptrs[10];                //ptrs是含有10个整型指针的数组
int (*Patrray)[10] = &arr;    //Parray指向一个含有10个整数的数组
int (&arrRef)[10] = arr;      //arrRef引用一个含有10个整数的数组

int *(&arry)[10] = ptrs;      //arry是数组的引用,该数组有10个指针

猜你喜欢

转载自blog.csdn.net/albert19891108/article/details/84112172