Apr.30 快乐数
1 | class Solution: |
Apr.29 山脉数组中查找目标值
1 | // 4 ms, 7.2 MB |
Apr.28 数组中数字出现的次数
分组异或。
1 | // 40 ms, 16.1 MB |
Apr.27 搜索旋转排序数组
1 | // 0 ms, 6.4 MB |
Apr.26 合并K个排序链表
1 | // 60 ms, 10.4 MB |
Apr.25 全排列
解法一
1 | // 4 ms, 7.4 MB |
解法二
1 | // 4 ms, 7.2 MB |
1 | class Solution: |
1 | // 4 ms, 7.2 MB |
分组异或。
1 | // 40 ms, 16.1 MB |
1 | // 0 ms, 6.4 MB |
1 | // 60 ms, 10.4 MB |
解法一
1 | // 4 ms, 7.4 MB |
解法二
1 | // 4 ms, 7.2 MB |
在C++0x中介绍了一种新的引用类型:右值引用,它帮助解决了不必要的拷贝问题和允许了完美转发的存在。当赋值的右手边(right-hand side)是一个右值时,左手边(left-hand side)的对象就可以偷走右手边对象的资源,而不是进行一次独立的分配,也就诞生了”移动语义“。
左值:可以出现在 operator= 左侧者。
右值:只能出现在 operator= 右侧者。
1 |
|
C++在用户自定义类型中会产生一些细微的问题,这些问题有关于修改或赋值动作。这种问题就导致上面的定义不正确。
(但是仍然应把临时对象认为是右值。)
当右值出现在 operator= (拷贝赋值,copy assignment)的右侧,我们认为对资源进行偷取/搬移(move)而非拷贝(copy)是合理的。则
用隐式和用户定义转换的组合在类型间转换。
static_cast <new_type> (expression)
返回 new_type
类型的值。
唯有下列转换能用 static_cast
执行,但若转换会转型走常量性或易变性则亦不允许。
若存在从 expression 到 new_type 的隐式转换序列,或者若针对以 expression 到 new_type 类型的对象或引用所进行的直接初始化的重载决议,找到至少一个可行函数,则 static_cast <new_type> (expression)
返回如同以 new_type Temp(expression);
所初始化的一个虚构变量 Temp
,它可能涉及隐式转换,对 new_type 的构造函数的调用,或对用户定义转换运算符的调用。对于非引用的 new_type,static_cast 纯右值表达式的结果对象是其直接初始化的对象。 (C++17 起)
若 new_type 是某类类型 D
的左值或指向它的指针纯右值,而 expression 的类型是到其非虚基类 B
的指针或引用,则 static_cast
进行向下转型(downcast)。若 B
是 D
的有歧义、不可访问或虚的基类(或虚基类的基类),则此向下转型非良构。这种 static_cast
并不进行用以确保该对象的运行时类型确实是 D
的运行时检查,而且仅当这项前提条件由其他方法所保证时才能安全使用,例如在实现静多态时。可以用 dynamic_cast
执行安全的向下转型。
1 | struct B { }; |
(本条自C++11起) 若 new_type 是右值引用类型,则 static_cast
将泛左值、类纯右值或数组纯右值 (C++17 前) 任何左值 (C++17 起) expression 的值转换为与该表达式指代相同对象,或指代其基类子对象(取决于 new_type)的亡值。若目标类型是表达式的不可访问或有歧义基类,则程序非良构。若表达式是位域左值,则它首先被转换成底层类型的纯右值。这种 static_cast
用于在 std::move
中实现移动语义。
若 new_type 是(可为 cv 限定的)void 类型,则 static_cast
在求值 expression 后舍弃其值。
若存在从 new_type 到 expression 类型的标准转换序列,且它不包含左值到右值、数组到指针、函数到指针、空指针、空成员指针、函数指针 (C++17 起)或布尔转换,则 static_cast
能进行该隐式转换的逆转换。
若从 expression 到 new_type 涉及左值到右值、数组到指针或函数到指针转换,则能显式用 static_cast
进行。
有作用域枚举类型(C++11)能转换成整数或浮点类型。
整数或枚举类型值可转换为任何完整枚举类型。
指向某类 D
的成员的指针可以向上转型(upcast)为指向其无歧义、可访问的基类 B
的成员。这种 static_cast
不进行用以确保成员实际存在于所指向对象的运行时类型的检查。
指向(可有 cv 限定)void 的指针类型的纯右值可转换到指向任何对象的指针类型。若原指针值所表示的内存中字节地址不满足目标类型的对齐要求,则结果指针值未指明。否则,若原指针值指向对象 a,且存在与 a 指针可互转换(定义于下文)的目标类型的(忽略 cv 限定)对象 *b,则结果为指向 *b 的指针。否则指针值不改变。任何指针转换到 void 指针,再转换回原(或更为 cv 限定的)类型的指针,都保持其原值。
同所有转型表达式,结果是:
满足以下条件时,两个对象 a 与 b 指针可互转换(pointer-interconvertible):
1 | union U { int a; double b; } u; |
static_cast
亦可用于通过进行到指定类型的函数到指针转换,来消解函数重载的歧义。如
1 | std::for_each(files.begin(), files.end(), |
下面这段代码
1 |
|
理论上,它的运行结果应为
1 | default ctor // foo函数第一行的对象b的构造 |
然而,当我们实际编译并运行它时,运行结果为
1 | default ctor |
发现所有的拷贝构造和临时对象的析构都被优化掉了。这就是NRV优化带来的性能上的好处。
DNS:Domain Name System,域名系统。它是:
它运行在UDP之上,使用53号端口。
它提供的服务:
yahoo.com
)进行解析,已获得该主机的规范主机名(如relay1.west-coast.hotmail.com
)及其IP地址。图源:《TCP/IP详解 卷1:协议》
大致说来,在DNS服务器的层次结构中有3种类型的DNS服务器:
还有一类重要的DNS服务器,严格而言它不属于DNS服务器的层次结构,但它对DNS层次结构至关重要。这一类DNS服务器是本地DNS服务器。每个ISP(如一个居民区的ISP或一个机构的ISP)都有一台本地DNS服务器(也叫默认名字服务器)。当主机与某个ISP连接时,该ISP提供一台主机的IP地址,该主机具有一台或多台其本地DNS服务器的IP地址(通常通过DHCP)。主机的本地DNS服务器通常“临近”本主机:对某机构ISP而言,本地DNS服务器可能就与主机在同一局域网中;对于某居民区ISP来说,本地DNS服务器通常与主机相隔不超过几台路由器。当主机发出DNS请求时,该请求被发往本地DNS服务器,它起着代理的作用,并将该请求转发到DNS服务器层次结构中。
查询分为递归查询与迭代查询。
(具体例子见 《计算机网络:自顶向下方法(原书第7版)》P86-88)
在一个请求链中,当某DNS服务器接收一个DNS回答(如包含某主机名到IP地址的映射)时,它能将映射缓存在本地存储器中。由于主机和主机名与IP地址间的映射不是永久的,所以DNS服务器在一段时间后(通常设置为两天)将丢弃缓存的信息。
本地DNS服务器也能够缓存TLD服务器的IP地址,因而允许本地DNS绕过查询链中的根DNS服务器。事实上,因为缓存,除了少数DNS查询以外,根服务器基本都被绕过了。
共同实现DNS分布式数据库的所有DNS服务器存储了资源记录(Resource Record,RR),RR提供了主机名到IP地址的映射。资源记录是一个包含了以下字段的4元组:
TTL
该记录的生存时间,它决定了资源记录应当从缓存中删除的时间。
Name、Value、Type
(relay1.bar.foo.com, 145.37.93.126, A)
。foo.com
),而Value是个知道如何获得该域中主机IP地址的权威DNS服务器的主机名。这个记录用于沿着查询链来路由DNS查询。如(foo.com, dns.foo.com, NS)
。(foo.com, relay1.bar.foo.com, CNAME)
。(foo.com, mail.bar.foo.com, MX)
。通过使用MX记录,一个公司的邮件服务器和其他服务器(如Web服务器)可以使用相同的别名。为了获得邮件服务器的规范主机名,DNS客户应当请求一条MX记录;而为了获得其他服务器的规范主机名,DNS客户应当请求CNAME记录。《计算机网络:自顶向下方法(原书第7版)》P83-92
Update your browser to view this website correctly. Update my browser now