《深入浅出MFC》2/e
体版之授权,直接等3/e 出版后再动作。没想到一拖经年,我的3/e 写作计划 并没有如期完成,致使大陆读者反而没有《深入浅出MFC》2/e 简体版可看。 《深入浅出MFC》3/e 没有如期完成的原因是,MFC 本体架构并没有什么大改 变。《深入浅出MFC》2/e 书中所论之工具及程序代码虽采用VC5+MFC42,仍 适用于目前的VC6+MFC421(唯,工具之画面或功能可能有些微变化)。 由于《深入浅出MFC》2/e 就会吸收很快。 请问,想要从DOS 跨足到Windows 程序设计有哪些书值得推荐呢? hschin.bbs@bbs.cs.nthu.edu.tw:建议你看侯俊杰的深入浅出MFC,里面除了对窗口程序 的架构作基础性的说明,让你了解一些基础概论,也说了不少窗口程序设计的课题,是 非常不错的一本书。 xiii News / BBS 论坛(CompBook and/or programming) 请问VISUAL 您好,我是屏科大的学生,想要用MFC 写一个可以新增、修改、删除资料等动作的 程序,日前老师借了我您的书深入浅出MFC 第二版,我读了很快乐,对于Visual C++ 的 IDE 环境更为了解,对于MFC 整个架构,有了比较明朗的感觉。 大陆Mike Dong尊敬的侯俊杰先生:我叫董旬。我对C/C++ 非常有兴趣。畅读了您写的书《深入浅出 WINDOWS 0 码力 | 1009 页 | 11.08 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 02 现代 C++ 入门:RAII 内存管理
编译器默认生成的构造函数:初始化列表(妙用,处理函数的复杂类型参 数) • 还有,函数的参数,如果是很复杂的类型 ,你不想把类型名重复写一遍,也可以利 用 {} 初始化列表来简化: • zeno 的节点定义函数 defNodeClass 中就大量用到了这种简 化。 有自定义构造函数时仍想用默认构造函数: = default • 一旦我们定义了自己的构造函数,编译器就不会再生成默认的无参构造函数。 主要业务的 C++ ,才发展出了这些思 想,并将拷贝 / 移动 / 指针 / 可变性 / 多线程等概念作为语言基本元素存在。这些在我们的 业务里面是非常重要的,所以不可替代。 • (试图升华文章中心主旨) 扩展阅读关键字 • 限于篇幅,此处放出一些扩展知识供学有余力的同学研究: 1. P-IMPL 模式 2. 虚函数与纯虚函数 3. 拷贝如何作为虚函数 4. std::unique_ptr::release()0 码力 | 96 页 | 16.28 MB | 1 年前3现代C++ 教程:高速上手C++11/14/17/20
<< std::endl; return 0; } 当然,并非所有的类型都能提供原子操作,这是因为原子操作的可行性取决于具体的 CPU 架构, 69 7.5 原子操作与内存模型 第 7 章并行与并发 以及所实例化的类型结构是否能够满足该 CPU 架构对内存对齐条件的要求,因而我们总是可以通过 std::atomic::is_lock_free 来检查该原子类型是否需支持原子操作,例如: 而言,表现为顺序执行的程序,它并没有由于引入多 线程而得到任何效率上的收益。对此有什么办法能够适当的加速呢?答案便是削弱原子操作的在进程间 的同步条件。 从原理上看,每个线程可以对应为一个集群节点,而线程间的通信也几乎等价于集群节点间的通信。 削弱进程间的同步条件,通常我们会考虑四种不同的一致性模型: 1. 线性一致性:又称强一致性或原子一致性。它要求任何一次读操作都能读到某个数据的最近一次写 的数据, 和 b 产生依赖,而 x 和 y 在此例子中表现为没有关系(但实际情况中我们需要更详细的信息才能确定 x 与 y 确实无关) 4. 最终一致性:是最弱的一致性要求,它只保障某个操作在未来的某个时间节点上会被观察到,但并 未要求被观察到的时间。因此我们甚至可以对此条件稍作加强,例如规定某个操作被观察到的时间 总是有界的。当然这已经不在我们的讨论范围之内了。 x.store(3) x.store(4) 0 码力 | 83 页 | 2.42 MB | 1 年前3C++高性能并行编程与优化 - 课件 - 07 深入浅出访存优化
CPU 读取一个地址时: • 缓存会查找和该地址匹配的条目。如果找到,则给 CPU 返 回缓存中的数据。如果找不到,则向主内存发送请求,等读 取到该地址的数据,就创建一个新条目。 • 在 x86 架构中每个条目的存储 64 字节的数据,这个条目 又称之为缓存行( cacheline )。 • 当访问 0x0048~0x0050 这 4 个字节时,实际会导致 0x0040~0x0080 的 就可以在一个循环体内实现两次迭代的效果! 从而快了 2 倍。 动画演示 a a’ a’’ 局部数组,一步抵 16 步 • 一次性读取到局部数组 ta 里,在局部迭代 16 次。 • 注意到局部数组是 64 大小,这包含了中心的 32 个元 素,还包含因为 jacobi 特性需要周围两个元素,导致 迭代 16 次就需要往边缘扩张的 16 个元素。 • 因为局部数组的大小远远小于一级缓存,这样迭代时 读写的带宽就是一级缓存的速度,几乎没有影响。 可以分配对齐 到任意 a 字节的内存。他在这个头文件里。是 x86 特有的,并且需要通 过 _mm_free 来释放。 • 还有一个跨平台版本(比如用于 arm 架构) 的 aligned_alloc(align, n) ,他也可以分配对 齐到任意 a 字节的内存,通过 free 释放。 • 利用他们可以实现分配对齐到页面( 4KB ) 的内存。 小彭老师的 0 码力 | 147 页 | 18.88 MB | 1 年前3Hello 算法 1.0.0 C++版
quadraticRecur(n - 1); } 图 2‑18 递归函数产生的平方阶空间复杂度 4. 指数阶 ?(2?) 指数阶常见于二叉树。观察图 2‑19 ,层数为 ? 的“满二叉树”的节点数量为 2? − 1 ,占用 ?(2?) 空间: // === File: space_complexity.cpp === /* 指数阶(建立满二叉树) */ TreeNode *buildTree(int 逻辑结构:线性与非线性 逻辑结构揭示了数据元素之间的逻辑关系。在数组和链表中,数据按照一定顺序排列,体现了数据之间的线 性关系;而在树中,数据从顶部向下按层次排列,表现出“祖先”与“后代”之间的派生关系;图则由节点 和边构成,反映了复杂的网络关系。 如图 3‑1 所示,逻辑结构可分为“线性”和“非线性”两大类。线性结构比较直观,指数据在逻辑关系上呈 线性排列;非线性结构则相反,呈非线性排列。 ‧ 线性 list」是一种线性数据结构,其中的每个元素都是一个节点对象,各个节点通过“引用”相连接。 引用记录了下一个节点的内存地址,通过它可以从当前节点访问到下一个节点。 链表的设计使得各个节点可以分散存储在内存各处,它们的内存地址无须连续。 第 4 章 数组与链表 hello‑algo.com 73 图 4‑5 链表定义与存储方式 观察图 4‑5 ,链表的组成单位是「节点 node」对象。每个节点都包含两项数据:节点的“值”和指向下一节0 码力 | 378 页 | 17.59 MB | 1 年前3Hello 算法 1.1.0 C++ 版
quadraticRecur(n - 1); } 图 2‑18 递归函数产生的平方阶空间复杂度 4. 指数阶 ?(2?) 指数阶常见于二叉树。观察图 2‑19 ,层数为 ? 的“满二叉树”的节点数量为 2? − 1 ,占用 ?(2?) 空间: // === File: space_complexity.cpp === /* 指数阶(建立满二叉树) */ TreeNode *buildTree(int 逻辑结构:线性与非线性 逻辑结构揭示了数据元素之间的逻辑关系。在数组和链表中,数据按照一定顺序排列,体现了数据之间的线 性关系;而在树中,数据从顶部向下按层次排列,表现出“祖先”与“后代”之间的派生关系;图则由节点 和边构成,反映了复杂的网络关系。 如图 3‑1 所示,逻辑结构可分为“线性”和“非线性”两大类。线性结构比较直观,指数据在逻辑关系上呈 线性排列;非线性结构则相反,呈非线性排列。 ‧ 线性 list)是一种线性数据结构,其中的每个元素都是一个节点对象,各个节点通过“引用”相连接。 引用记录了下一个节点的内存地址,通过它可以从当前节点访问到下一个节点。 链表的设计使得各个节点可以分散存储在内存各处,它们的内存地址无须连续。 第 4 章 数组与链表 hello‑algo.com 73 图 4‑5 链表定义与存储方式 观察图 4‑5 ,链表的组成单位是节点(node)对象。每个节点都包含两项数据:节点的“值”和指向下一节0 码力 | 379 页 | 18.47 MB | 1 年前3Hello 算法 1.0.0b4 C++版
return quadraticRecur(n - 1); } Figure 2‑12. 递归函数产生的平方阶空间复杂度 指数阶 ?(2?) 指数阶常见于二叉树。高度为 ? 的「满二叉树」的节点数量为 2? − 1 ,占用 ?(2?) 空间。 // === File: space_complexity.cpp === /* 指数阶(建立满二叉树) */ TreeNode *buildTree(int 逻辑结构:线性与非线性 「逻辑结构」揭示了数据元素之间的逻辑关系。在数组和链表中,数据按照顺序依次排列,体现了数据之间的 线性关系;而在树中,数据从顶部向下按层次排列,表现出祖先与后代之间的派生关系;图则由节点和边构 成,反映了复杂的网络关系。 逻辑结构通常分为“线性”和“非线性”两类。线性结构比较直观,指数据在逻辑关系上呈线性排列;非线 性结构则相反,呈非线性排列。 ‧ 线性数据结构:数组、链表、栈、队列、哈希表。 「链表 Linked List」是一种线性数据结构,其每个元素都是一个节点对象,各个节点之间通过指针连接,从 当前节点通过指针可以访问到下一个节点。由于指针记录了下个节点的内存地址,因此无需保证内存地址的 连续性,从而可以将各个节点分散存储在内存各处。 链表「节点 Node」包含两项数据,一是节点「值 Value」,二是指向下一节点的「指针 Pointer」,或称「引 用 Reference」。0 码力 | 343 页 | 27.39 MB | 1 年前3Hello 算法 1.0.0b5 C++版
quadraticRecur(n - 1); } 图 2‑18 递归函数产生的平方阶空间复杂度 4. 指数阶 ?(2?) 指数阶常见于二叉树。观察图 2‑19 ,高度为 ? 的“满二叉树”的节点数量为 2? − 1 ,占用 ?(2?) 空间: // === File: space_complexity.cpp === /* 指数阶(建立满二叉树) */ TreeNode *buildTree(int 逻辑结构:线性与非线性 逻辑结构揭示了数据元素之间的逻辑关系。在数组和链表中,数据按照顺序依次排列,体现了数据之间的线 性关系;而在树中,数据从顶部向下按层次排列,表现出祖先与后代之间的派生关系;图则由节点和边构成, 反映了复杂的网络关系。 如图 3‑1 所示,逻辑结构可被分为“线性”和“非线性”两大类。线性结构比较直观,指数据在逻辑关系上 呈线性排列;非线性结构则相反,呈非线性排列。 ‧ 线 素都是一个节点对象,各个节点通过“引用”相连接。 引用记录了下一个节点的内存地址,通过它可以从当前节点访问到下一个节点。 第 4 章 数组与链表 hello‑algo.com 70 链表的设计使得各个节点可以被分散存储在内存各处,它们的内存地址是无须连续的。 图 4‑5 链表定义与存储方式 观察图 4‑5 ,链表的组成单位是「节点 node」对象。每个节点都包含两项数据:节点的“值”和指向下一节0 码力 | 377 页 | 30.69 MB | 1 年前3Hello 算法 1.2.0 简体中文 C++ 版
quadraticRecur(n - 1); } 图 2‑18 递归函数产生的平方阶空间复杂度 4. 指数阶 ?(2?) 指数阶常见于二叉树。观察图 2‑19 ,层数为 ? 的“满二叉树”的节点数量为 2? − 1 ,占用 ?(2?) 空间: // === File: space_complexity.cpp === /* 指数阶(建立满二叉树) */ TreeNode *buildTree(int 逻辑结构:线性与非线性 逻辑结构揭示了数据元素之间的逻辑关系。在数组和链表中,数据按照一定顺序排列,体现了数据之间的线 性关系;而在树中,数据从顶部向下按层次排列,表现出“祖先”与“后代”之间的派生关系;图则由节点 和边构成,反映了复杂的网络关系。 如图 3‑1 所示,逻辑结构可分为“线性”和“非线性”两大类。线性结构比较直观,指数据在逻辑关系上呈 线性排列;非线性结构则相反,呈非线性排列。 ‧ 线性 素都是一个节点对象,各个节点通过“引用”相连接。 引用记录了下一个节点的内存地址,通过它可以从当前节点访问到下一个节点。 链表的设计使得各个节点可以分散存储在内存各处,它们的内存地址无须连续。 第 4 章 数组与链表 www.hello‑algo.com 73 图 4‑5 链表定义与存储方式 观察图 4‑5 ,链表的组成单位是节点(node)对象。每个节点都包含两项数据:节点的“值”和指向下一节0 码力 | 379 页 | 18.48 MB | 10 月前3C++高性能并行编程与优化 - 课件 - 17 由浅入深学习 map 容器
里面第一部分,也就是初始化语句: it = map.begin() 代表从最左节点开始出发。 • 第二部分,也就是判断是否退出的条件: it != map.end() 判断是否抵达最右节点的下一个 。 • 第三部分,也就是每次循环后执行的更新语句: ++it 会让迭代器往下一个节点移动。 • 所以人话就是:从根节点出发,不断向下一个移动,直到没有节点可遍历了。 • 而 for 里面的循环体,会对每个不同的 it 然后从程序员的黑盒视角看来,就是对于所有 map 中的 K-V 对执行了一遍循环体。 迭代器 operator++ 的移动方向 • 迭代器的 ++ 是中根遍历,先左子节点,然后根节点,最后右子节点。 • 为什么是中根遍历?因为刚刚说了二叉排序树的规则是:左子节点<父节点<右子节点。 • 这刚好是中根遍历的顺序,左中右。所以迭代器的 ++ 方向刚好是 K 越来越大的方向。 • 结论:遍历时,总是会按 K 从小到大的顺序。 1 待插入的数 4 5 8 7 set 查找为什么高效 • 刚刚的构建方法是平衡二叉树。而实际 set 中采用的是更为高效的红黑树。 • 区别就是每个节点上多挂了一个 bool 类型的 flag 变量,表示这个节点是红是黑。 • 总之这样三下五除二下来他的插入效率比平衡二叉树高出一个常数,但复杂度还是 O(logn) 。 • 红黑树的具体异同我会放到最后再细讲,一下子讲太深都睡着了,反正只有插入和删除的0 码力 | 90 页 | 8.76 MB | 1 年前3
共 21 条
- 1
- 2
- 3