C++Primer笔记-----day03
==============================================================
day03
==============================================================
1.在表达式求值之前,小整数类型的运算对象会被提升成较大的整数类型。
eg: bool b = true;
    bool b2 = -b; //  b2是true!   原因是当b参与运算时,被提升为int类型,即被提升为整数1,求负后为-1,所以b2为真。由此可见,bool类型不应该参与运算。
2.新标准下,m%(-n)=m%n   (-m)%n = -(m%n)
3.关于位运算。如果运算对象是小整型,则它的值会被自动提升成较大的整数类型。
位运算的运算对象可以是带符号的,也可以是无符号的。左移操作会改变符号位,关于符号位如何处理依赖于机器,没有明确规定,所以强烈建议仅将位运算用于处理无符号类型。
4.sizeof运算符计算的是【类型的大小】!与元素个数或者其他什么无关!其所得值是一个size_t类型的常量表达式。用法有两种形式:
sizeof(type);  //  返回此类型所占的字节数
sizeof(expr);   //  返回表达式结果类型的大小。注意:sizeof并不实际计算表达式的值,所以即使此表达式是一个无效的指针也没有什么影响。
在32位机器上sizeof一个指针,得到4,64位机器得到8.
注意,sizeof一个数组得到整个数组所占空间的大小。要计算数组中元素的个数,用:sizeof(a)/sizeof(*a)
还应注意sizeof一个vector或者string,得到的是该类型固定部分的大小,与它里面有多少个元素无关。
在我的机器上。sizeof(vector<int>) = 16; // 32位机器
sizeof(vector<char>) = 16; // 还是16  .  由此得出,vector类型的大小,与vector类的具体实现有关。
///////////////////////////////////////////////////////////////////////////////////////////////
5.类型转换。
(1)大多数用到数组的表达式,数组自动转换成指向数组首元素的指针。
需要注意的是,当数组被用作decltype关键字的参数,或者取地址符(&)、sizeof、typeid等运算符的运算对象时,上述转换不会发生。
(2)const_cast类型转换,只能用来改变运算对象的底层const,我们一般称其为“去常量性”。
eg: const char *pc;
    char *p = const_cast<char*>(pc);  // 正确:但通过p写值是未定义的行为。
注意:const_cast只能改变常量属性,不能用来改变表达式的类型。
eg: const char *cp;
    const_cast<string>(cp); // 错误
    static_cast<string>(cp); // 正确
const_cast在重载函数的情景中最有用。
eg: const string &foo(const string &s1,const string &s2){...}
这个函数的参数和返回类型都是const string的引用。我们可以对两个非常量的string实参调用这个函数,但结果
仍然是const string的引用。因此我们需要重载一个foo()函数,当它的实参不是常量时,返回一个普通引用,可以
使用const_cast做到这一点。
    string &foo(string &s1,string &s2)
{
	auto &r = foo(const_cast<const string&>(s1),const_cast<const string&>(s2));
	return const_cast<string&>(r);
}
这个版本,先将它的实参强制转化为const引用,然后调用了foo()的const版本,这个const版本的foo()返回
对const string的引用,我们再用const_cast将其转换回一个普通的string&。
(3)reintepret_cast类型转换非常危险。它可以将一个指针转换成一个int。
eg:
int *ip;
char *pc = reintepret_cast<char*>(ip); // pc所指的真实对象是一个int,如果把pc当成普通字符指针使用,会导致异常的运行时行为。
string str(pc); // 会导致异常行为
////////////////////////////////////////////////////////////////////////////////////////////////
6.一个函数只能返回一个值,有时函数需要返回多个值,这时,可以多传入一个引用参数,这样就可以通过引用隐式地返回一个值。
比如,我们想定义一个函数,返回string对象中某个指定字符第一次出现的位置,同时我们也希望得到该字符出现的总次数。
这时,我们可以给函数传入一个额外的引用参数,让其保存字符出现的次数:
eg: string::size_type find_char(const string &s, char c, string::size_type &occurs)
{
	occurs = 0;
	auto ret = s.size();
	for (decltype(ret) i = 0; i != s.size(); ++i) {
		if (s[i] == c) {
			if (ret == s.size())
				ret = i;
			++occurs;
		}
	}
	return ret;           // 出现次数通过occurs隐式地返回
}
非常注意的一点是!参数列表的const string &s中的const不可以丢掉。如果丢掉,就不可以用find_char("abcd",'b',ctr)来调用,因为"abcd"本质上是const char*,无法转换为string&,将导致编译出错。
7.当用实参初始化形参的时候,形参会忽略掉顶层const
eg: void fcn(const int i){}  //  顶层const被忽略
    void fcn(int i){}   //  错误,重复定义了fcn(int)
8.关于数组作为参数传递的问题:
eg: void print(const int a[10]) // 这里的维度表示我们期望数组含有多少元素,实际不一定。
这是因为,使用数组时会自动转换为首元素地址。
再看这个题:
void print(const int ia[10])     //   语法正确,  但与我们的初衷相违背
{
    for(size_t i = 0;i != 10;+=i)
	cout<<ia[i]<<endl;
}
这里的[10]并不能表示我们要传递一个大小为10的数组,传入const int ia[10],const int ia[100]都是可以的。
如果我们想传入一个大小为10的数组,应该使用数组的引用 void print(const int (&ia)[10]).
9.关于默认实参。string screen(int ht = 24, int wid = 80, char bg = ' ');
需要注意的是,一旦某个形参被赋予了默认值,那么它后面的所有形参都必须有默认值。
string window;
window = screen(); // 等价于 screen(24,80,' ')
window = screen(66,256); // 等价于 screen(66,256,' ')
10.数组不能被拷贝,所以函数不能返回一个数组,但可以返回数组指针或引用。
函数形式为: Type (*funcName(parameterList))[dimension]
eg: int (*func(int i))[10]; //声明了一个函数,返回值为一个指向大小为10的int型数组的指针。
可以这样理解:   
func(int i)表示调用func函数时需要一个int类型的实参
(*func(int i))表示我们可以对函数调用的结果执行解引用操作
(*func(int i))[10] 表示解引用后得到的是一个大小是10的数组
int (*func(int i))[10] 表示数组中的元素是int型。
还有其他写法:
auto func(int i) -> int(*)[10];
decltype(一个数组) *arrPtr(int i);
Typedef int arrT[10]; 
或者 using arrT = int[10];
arrT *func(int i);
11.函数重载调用的匹配规则,考虑如下:
有两个函数:
f(int,int);
f(double,double)
调用它们f(42,2.56) ,最终编译器会因为这个调用具有二义性而拒绝调用请求。
C++Primer笔记-----day03的更多相关文章
- OpenCV图像处理学习笔记-Day03
		
OpenCV图像处理学习笔记-Day03 目录 OpenCV图像处理学习笔记-Day03 第31课:Canny边缘检测原理 第32课:Canny函数及使用 第33课:图像金字塔-理论基础 第34课:p ...
 - C++ Primer笔记
		
C++ Primer笔记 ch2 变量和基本类型 声明 extern int i; extern int i = 3.14;//定义 左值引用(绑定零一变量初始值,别名) 不能定义引用的引用:引用必须 ...
 - C++ Primer 笔记(1)基础中的战斗机 输入输出 对输入不定数据处理
		
今天打算再重新好好的看一遍C++ Primer这本很经典的书籍,笔记开始: 1.每个C++程序都包含一个或者多个函数,其中必须有一个main,操作系统通过调用main入手运行程序: 2.函数包括:返回 ...
 - C++ Primer 笔记 第一章
		
C++ Primer 学习笔记 第一章 快速入门 1.1 main函数 系统通过调用main函数来执行程序,并通过main函数的返回值确定程序是否成功执行完毕.通常返回0值表明程序成功执行完毕: ma ...
 - C++primer笔记之顺序容器
		
最近又重新拾起C++primer,发现每一次看都会有不同的体验,但每一次看后因为不常用,忘记得很快,所以记笔记是很关键的一环,咋一看是浪费时间,实际上是节省了很多时间.下面就把这一节的内容做一个简单的 ...
 - c++ primer 笔记  (一)
		
昨天开始看的<C++ Primer>,确实不错.希望这周抓紧看完,每天做下笔记,以便以后复习. main函数返回一个值给操作系统 操作系统通过main函数返回的值来确定程序是否成功执行 ...
 - C++ Primer笔记(1)——连续读取数据、类型对应的尺寸、类型转换、字符串分行写法
		
这次要看看C++ Primer,这本基本上就是必读书籍了.下面的内容就是一些之前没有学过的知识的笔记. 读取数量不定的输入数据 虽然很简单,但是还是记一下: #include <iostream ...
 - C++Primer笔记(3)
		
标准库类型string表示可变长的字符序列,使用前先包含string头文件.(哈哈,终于可以逃脱C语言中的str函数系列了.)因为是标准库的一部分,所以string被定义在命名空间std中.所以你懂该 ...
 - C++ Primer 笔记 第三章
		
C++ Primer 第三章 标准库类型 3.1using声明 例: using namespace atd; using std::cin; 3.2string类型 初始化方式 string s1 ...
 
随机推荐
- linux自学(四)之开始centos学习,网络配置
			
上一篇:linux自学(三)之开启虚拟机 安装好镜像之后,重启之后需要登录,我这里直接是root账号直接登录的,注意:输入密码的时候不显示. 之后输入ifconfig最常用的命令来查看网卡信息,出现c ...
 - 使用 MSBuild 响应文件 (rsp) 来指定 dotnet build 命令行编译时的大量参数
			
在为开源项目 easiwin/MSTestEnhancer 进行持续集成编译时,需要在编译命令中传入较多的参数.这对于新接手此项目的人来说,成本还是高了一点儿.本文将介绍 MSBuild 响应文件 ( ...
 - Windows 10 自带那么多图标,去哪里找呢?
			
无意间发现我的 D 盘根目录中大部分的文件夹都是系统专用文件夹,有自己的独特图标,偶有一两个开发用的文件夹是默认图标.于是想把它们改成独特样式,而且是 Windows 10 那些新图标样式! 这是我的 ...
 - GraphQL和RESTful的区别
			
GraphQL和RESTful的区别 http://graphql.cn/learn/ https://www.cnblogs.com/Wolfmanlq/p/9094418.html http:// ...
 - UICollectionView官方使用示例代码研究
			
注:这里是iOS6新特征汇总贴链接 iOS6新特征:参考资料和示例汇总 这个链接可以学习到UICollectionView的相关介绍:iOS6新特征:UICollectionView介绍 由于UICo ...
 - MySQL 百万级分页优化(Mysql千万级快速分页)
			
以下分享一点我的经验 一般刚开始学SQL的时候,会这样写 : SELECT * FROM table ORDER BY id LIMIT 1000, 10; 但在数据达到百万级的时候,这样写会慢死 : ...
 - 如何定位占用cpu过高的线程
			
如何定位占用cpu过高的线程 近来发现平台应用响应越来越慢,通过top命令发现,cpu占用率越来越高 1. 首先根据top命令,发现占用cpu最高的进程PID:3075. 通过ps aux | gre ...
 - (转)[Android实例] 关于使用ContentObserver监听不到删除短信会话的解决方案
			
最近做通讯录的项目,需要实时监听短信的删除,就用到了观察者ContentObserver,怪异的事情就此发生,当我删除一条短信的时候,可以监听到,但是,当我删除整条短信的时候,就无法监听到,查了很多资 ...
 - 编译Lichee(FridenlyARM NanoPi-M1)碰到的问题及解决办法
			
1. 提示libz.so.1找不到 需要在ubuntu上安装下面两个包: sudo apt-get install lib32ncurses5 ia32-libs 2. 提示xt_hl.o没有make ...
 - Unit02: 参数值注入 、 基于注解的组件扫描
			
Unit02: 参数值注入 . 基于注解的组件扫描 (4)IOC (Inversion Of Controll 控制反转) 什么是IOC? 对象之间的依赖关系由容器来建立. 什么是DI? (Depen ...