CPP Primer第五版笔记整理(1) 至第三章vector部分

先过一过基础
1.main函数的返回类型必须为int

2.在大多数系统中,main的返回值被用来指示状态,0表示成功,非0值的含义由系统定义,通常用来指出错误类型

3.#include指令必须在所有函数外,且必须和文件名在同一行

4.注释界定符不能嵌套

5.char 8 long 16 long long 32
其中long long 是C++11的新定义的

6.尽量不要混用无符号和有符号的类型
7. 0开头为8进制,0x为16
8. 列表初始化的好处:
当使用内置类型的变量进行列表初始化时,如果存在信息丢失风险编译器将会报错,比如 long double ld=3.1415926;
int a{ld};将会报错

9.定义变量若没初始化则会被默认初始化,由其具体类型决定,如果是内置的类型,那么由其定义的位置决定,定义于任何函数体外的内置变量会被初始化为0,函数体内部的内置类型不会被初始化,会出错,而类的变量则由类确定初始化方式,绝大多数类都hi吃无需显示初始化定义对象,如string可以不指定初值,而有些类需要。因此对于内置类型尽量都初始化

10.为了支持分离式编译(将程序分为多个文件),需要在各个文件之间共享代码,需要用extern关键字来声明:例如 extern int i;此时代表声明 i而非定义i,如果此时在声明后面加入了初始值,那么此时就抵消了extern的作用了,而且在函数体内部是不允许为其提供初始值的
而且注意当有多个文件的全局变量都有同样的变量名,再用extern会报错,因为编译器并不知道你声明的是哪一个,因此这种情况要尽可能避免

11.如果要使用某一个变量,那么这个变量只能被定义一次,但可以被多次声明
12.C++是一种静态类型的语言,在编译阶段检查类型

13.所有标识符仅有字母,数字和下划线,其中数字不能开头

14.命名规范:{
1.标识符应尽量体现实际意义
2.变量用小字母开头,用户定义的类用大写开头
3.多单词尽量第一个用小写开头后面用大写开头
}

指针这边由于内容比较多,我直接新开了一篇整理

15.常量表达式:在编译过程时就能得到的表达式。

而在一般情况下,我们要去判断一个表达式是否为常量表达式太过繁琐,因此在C++11的新标准种,出现了一种新的类型,constexpr变量(const expression) ,声明为该类型的变量会被自动检测是否为常量表达式,而且还有constexpr函数,具体后面会提到,而且constexpr和const变量一样都需要初始化。

由于constexpr变量的值是能在编译时得到的,因此其类型必须有所限制,否则编译器看不懂,比如算数类型,引用,指针,但是指针的初始值必须是0或者nullptr,或者是存储在某个固定地址的对象(比如某个全局变量,注意局部变量没有固定地址,具体后续会提到)

注意的是这里constexpr和const有部分不一样

const int *p=nullptr;
constexpr int *q=nullptr;

上一句表示的是p是指向常量的指针,q是常量指针

16.C++11新出了一种类型说明符 auto,可以根据表达式自动推出变量类型,因此,auto也必须有初值
但有时候auto也不一定能和初始值的类型完全一样(比如当引用被当作初始值的时候,auto的类型是它绑定的元素的类型而不是引用)
而且auto一般会忽略顶层const,要想使其不忽略,需要再前面加一个const

const int ci=10;
const auto t=ci;

不过值得一提的是 auto的引用是可以保留顶层const

17.与auto类似的,C++11还有一个类型说明符:decltype(),它可以推断某个表达式的类型:比如:

decltype(f()) sum=x;

sum的类型就是f()的类型
与auto有区别的是decltype不会吞掉引用和顶层const

但即便如此,如果真的想吞掉引用怎么办呢,答案是在后面加1个0即可

decltype(r+0) b;

而且还有一些要注意的地方,如果加上括号或者有解引用操作,那么得到的结果就是引用 比如

 int i=42,*p=&i,&r=i;
 decltype(*p) x;
 decltype((i)) y;

x和y都是引用类型

18.头文件不要包含using 声明,否则容易产生冲突

19.string 默认初始化是没有任何字符的
几种容易忘的用法:
getline(is,s);读一行,is表示istream
这里的string对象的==或!=与java的有点不同,这里直接比较的是所有字符,对大小写敏感,而java里的String比较的是地址
而且对于>和<号,比较的是字典序,即先比较长度再从头到尾比较单一字符的大小

20.string里的size函数实际上返回的不是int或者unsigned int,实际上返回的是string::size_type类型,首先它是一个无符号类型,而且足以存放任意string对象的大小。要注意的是,用这个类型的时候,也就是用x.size()去作为表达式的一部分的时候,尽量要用无符号类型做,否则可能会有意外情况,比如

string s="abcde";
    int n=-10;
    cout<<(s.size()<n);

得到的结果是1,这是因为n转化为了无符号型的值

要注意的是虽然string可以支持相加操作,也支持和字面值相加,但字面值和字面值之间并不支持相加,也就是说在相加时要保证加号两边至少有一个string类型,而且与java不同,这里的字面值必须是字符或者字符串。而且字符串字面值的类型并非string。

21.要遍历string对象的每个字符,虽然可以直接直接for循环遍历,用下标访问,但C++11提供了一种新方法,更加简洁:

string str("hello");
for(auto c:str){
cout<<c<<endl;
}

而要改变字符,只需要加用引用即可

注意的是在C++ 11以前如果vector嵌套定义的话,那么两个>>需要用空格隔开,但C++11不用

vector<vector<int>> c;

这个语句在C++11之前会报错,但11不会
23.在C++11的新标准里,可以为数据成员提供一个类内初始值,在创建一个对象的时候,没有被初始化的数据成员将被默认初始化
24.vector的默认初始化也为空,在C++11中提供了一种新的初始化方式:列表初始化,即用花括号,然后里面的元素都用逗号隔开,如

vector<string> v1{"i","love","c++"};

一般情况下,有很多初始化方式,而且都可以,有几种情况比较特殊,一个是拷贝初始化只能提供一个初始值,二是如果提供的是类内初始值,那么必须用花括号形式的初始化,三是如果提供的是初始元素值的列表,那么要用花括号而不能用圆括号,如

vector<string> v1{"i","love","c++"};  //正确
vector<string> v1("i","love","c++");  //错误

25.vector的比较也是和字典序一样,下标和size也和string类似,但注意别用下标来添加vector元素

26.迭代器:iterator,一般是用来访问容器里面的元素的,与指针类似,也提供了对对象的间接访问,使用方法: begin成员函数和end成员函数,begin返回容器的指向第一个元素的迭代器, end返回指向最后元素的下一个元素的迭代器,也称为尾后迭代器,特殊情况是当容器为空的时候begin和end是同一个迭代器,都是尾后迭代器,一般的话都用auto,比较方便。

27.迭代器支持的运算:和指针十分类似,比如

*iter  ;//返回迭代器iter所指向元素的引用
iter->mem; //等价于(*item).mem
++item;//指向容器的下一个元素

一般使用时要检查容器是否为空,只需要判断begin和end是否相同即可,迭代器的类型一般有iterator或者const_iterator两种,后者和底层const类似,不能对其指向对象进行修改

28.begin和end的返回类型由对象是否是常量决定,如果是就返回const的,否则就是普通的。一般如果只读不写尽量用const的,C++11新标准提供了两个新函数,cbegin和cend,就可以返回const的。

29.要注意的是像vector这样能动态增加空间的容器,对其增加元素的时候会使得迭代器失效,因此,在用迭代器遍历或者用范围for循环遍历的时候不要给vector新加元素

30.数组是不能拷贝和赋值的

31.数组和指针的一些复杂的声明:
一般从内向外,从右向左看
比如

int (*Parray)[10]=&arr;

从括号看它是一个指针,从右看它是指向一个大小为10的int数组;
32.数组下标其实是size_t类型的,它是一种机器相关的无符号类型,它被设计的足够大可以能表示内存中任意对象的大小,其在cstddef头文件里定义的。

33.C++11中为数组定义了和容器类似的begin和end,用法是这样而不是成员函数

begin(ia);

34.可以用string和字符数组相加或者用字符数组赋给string对象,不过反过来不可以,可以用string里的c_str()成员函数,返回类型是const char *

35.不能用vector初始化数组不过可以用数组初始化vector,只需要指明要拷贝区域的首元素和尾元素地址即可

vector<int> ivec(begin(int_arr),end(int_arr));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值