• 第3章 字符串、向量和数组


    这是在看完了C++ Primer这本书之后又回过头来码的笔记,在看的时候也发现,看到后面,前面就忘了,有点像狗熊掰玉米。。。所以决定回过头来再过一遍,这一次只看那些比较重要的知识点,太详细了也终归还是记不住。另外,这篇博客是使用 Markdown写的,第一次用,估计写出来的格式可能会有点丑。。

    1.位于头文件中的代码一般不应该使用 using声明。这是因为该文件还会被其他文件包含,在头文件中使用 using声明的话,其他文件中就也有了这个声明,可能造成名字冲突。
    2.使用形如 cin >> s的形式读入 string对象,会自动忽略开头的空白(空格、换行、制表符等)并从第一个真正的字符开始读起,直到遇见下一处空白为止。不过标点符号还是会被读取进来的。
    3.getline一遇到换行符就结束读取操作并返回结果,哪怕输入的一开始就是换行符也是如此,不过读入的换行符也还是会被丢弃。
    4.与 string下标和长度有关的变量应该使用 size::type类型,千万不要将 size::type和 int型混用!
    5.string下标访问运算符 []返回值是该位置上字符的引用。
    6.vector中存储的元素类型必须可以被赋值,所以元素类型不能是引用和常量。另外,因为新标准中有一个 vector(n, val)的构造函数,所以元素类型必须要有默认构造函数。
    7.初始化时使用了花括号的形式但是提供的值又不能用来列表初始化,编译器会尝试使用提供的值来构造 vector对象。

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

    8.vector本身是一个模板,对象类型总是包含着元素类型

    vector<int>::size_type        // 正确  
    vector::size_type                // 错误
    

    9.for循环中应尽量使用 !=或 ==,而非 <、>、<=、>=等关系运算符,因为并不是所有类型都定义了关系运算符。使用相等性操作,这种编程风格在标准库提供的所有容器上都有效,适用性更广泛。
    10.it是一个迭代器类型,则对于以下形式,圆括号必不可少。因为点运算符优先级更高。
    (*it).empty();
    11.容器的下标类型 size_type,迭代器的距离类型 difference-type;
    内置数组,下标类型为 size_t,指针距离类型为 ptrdiff_t。
    12.对于内置数组,元素类型和个数都是类型的一部分,因此,定义数组时,其维度要是已知的,必须为一个常量表达式。
       1. 与内置类型一样,在函数内部定义的内置类型的数组,默认初始化会令数组含有未定义的值。
       2. 字符数组可以用字符串字面值进行初始化,要注意,字符串字面值的结尾处有一个空字符,这个空字符也会被拷贝到字符数组中。所以在定义字符数组的大小时,要考虑到这个空字符。

        char a1[] = {'C', '+', '+'};               // 列表初始化,没有空字符   
        char a2[] = {'C', '+', '+', ''};        // 列表初始化,含有显式的空字符   
        char a3[] = "C++";                       // 自动添加表示字符串结束的空字符   
        const char a4[3] = {'C', '+', '+'};   // 错误:没有空间存放空字符   
    

       3. 不允许数组间的拷贝初始化和赋值操作
       4. 在很多使用数组名字的地方,编译器会将它转换成指针。当使用数组类型作为 auto变量的初始值时,推断得到的是指针而非数组;而使用 decltype得到的是数组类型。

        int ia[] = {0, 1, 2, 3, 4};     
        auto ia2(ia);        // ia2 是一个整型指针,指向 ia的第一个元素   
        decltype(ia) ia3;  // ia3 是一个整型数组      
    

       5. C++11新标准引入了 begin和 end两个函数,使得内置数组也可以像 STL中的容器那样操作迭代器。注意这两个函数不是成员函数,使用时要用数组作为它们的参数。
       6. 内置数组的下标类型不是无符号类型,可以是负值,但结果地址必须指向原指针所指向的同一数组中的元素。

        int ia[] = {0, 1, 2, 3, 4};     
        int *p = ia[2];  // 指向 ia[2]     
        int k = p[-2];   // 指向 ia[0]      
    

    13.对于适用于 C风格字符串的函数 strlen、strcmp等,传入此函数的指针必须指向以空字符结束的数组,没有空字符,就无法判断字符数组在内存中的结束位置。
    14.现代的 C++程序应尽量使用 vector和迭代器,避免使用内置数组和指针;应该尽量使用 string,避免使用 C风格的基于数组的字符串。因为使用 C风格的编程风格容易引发语法和繁琐细节上的错误。
    15.在使用范围 for语句处理多维数组时,除了最内层的循环外,其他所有循环的控制变量都应该是引用类型。比如对于以下形式

    for (auto row : ia)
        for (auto col : row)
    

    在遍历内循环时,因为 row不是引用类型,所以编译器初始化 row时会自动将这些数组形式的元素转换成指向首元素的指针,这样 row的类型就是 int*,显然内层循环就不合法了。

  • 相关阅读:
    383 Ransom Note 赎金信
    382 Linked List Random Node 链表随机节点
    381 Insert Delete GetRandom O(1)
    380 Insert Delete GetRandom O(1)
    378 Kth Smallest Element in a Sorted Matrix 有序矩阵中第K小的元素
    377 Combination Sum IV 组合之和 IV
    376 Wiggle Subsequence 摆动序列
    SpringBoot(十四):springboot整合shiro-登录认证和权限管理
    SpringBoot(十三):springboot 小技巧
    SpringBoot(十二):springboot如何测试打包部署
  • 原文地址:https://www.cnblogs.com/taqikema/p/8144637.html
Copyright © 2020-2023  润新知