随笔分类 -  C/C++编程

摘要:该文介绍了如何使用指针中一些未使用的位来隐藏一些数据。 When we write C code, pointers are everywhere. We can make a little extra use of pointers and sneak in some extra informat 阅读全文
posted @ 2015-06-15 11:11 Mr.Rico 阅读(584) 评论(0) 推荐(0) 编辑
摘要:在Linux中关于IP和无符号整数之间的转换有两个比较好的函数: int inet_aton(const char *cp, struct in_addr *inp); char *inet_ntoa(struct in_addr in); 通过函数名就可以知道函数作用了.这里需要注... 阅读全文
posted @ 2012-10-17 23:31 Mr.Rico 阅读(941) 评论(0) 推荐(0) 编辑
摘要:现代C++程序设计比较推崇使用模板STL。STL是C++中一个非常重要的改革。在C++03之后,STL表现非常不错,STL中提供了一些常见的算法。这些算法可以直接使用,而不需要自己再去写,效率。 简单总结一下STL一些比较好的算法。 一. 非变易算法 1. for_each:遍历容器元素进行操作 该... 阅读全文
posted @ 2012-10-11 23:13 Mr.Rico 阅读(880) 评论(0) 推荐(0) 编辑
摘要:1. strspn与strcspn 2. strtok与strpbrk 3. strstr, strchr与strrchr 4. 字符串与数值之间的转换:atoi,atol,atof,strtod,strtol,strtoul 5. frexp和ldexp 1. strspn与strcspn (1)... 阅读全文
posted @ 2012-10-11 23:05 Mr.Rico 阅读(1167) 评论(1) 推荐(0) 编辑
摘要:C语言中的时间相关的函数 是C标准函数库中获取时间与日期、对时间与日期数据操作及格式化的头文件。宏: NULL null是一个null指针常量的值 CLOCKS_PER_SEC 每秒的时钟数变量:typedefsize_t类型定义typedefclock_t类型定义structtm结构体struct... 阅读全文
posted @ 2012-10-11 23:03 Mr.Rico 阅读(296) 评论(0) 推荐(0) 编辑
摘要:C语言在 头文件定义了一些宏,当函数参数未知时去获取函数的参数。包括一个va_list类型和三个函数(宏)va_start, va_arg和va_end .变量和定义va_list类型通过stdarg宏定义来访问一个函数的参数表,参数列表的末尾会用省略号省略声明:void va_start(va_l... 阅读全文
posted @ 2012-10-11 23:01 Mr.Rico 阅读(294) 评论(0) 推荐(0) 编辑
摘要:在STL中,迭代器主要分为5大类:Input Iterator, Output Iterator, Forward Iterator, Bidirectional Iterator和RandomAccess Iterator。关系如下:其中每一个左边的迭代器都实现了右边迭代器的方法。左边迭代器是对右边迭代器的进一步强化。In this graph, each iterator category implements the functionalities of all categories to its right:(1) Input and output iterators are the 阅读全文
posted @ 2012-10-10 22:13 Mr.Rico 阅读(816) 评论(0) 推荐(0) 编辑
摘要:C语言中重要函数的简要分析及实例1. strspn与strcspn2. strtok与strpbrk3. strstr, strchr与strrchr4. 字符串与数值之间的转换:atoi,atol,atof,strtod,strtol,strtoul5. frexp和ldexp1. strspn与strcspn(1)函数strspn:size_t strspn ( const char * str1, const char * str2 );功 能: 在串中查找指定字符集的子集的第一次出现,如果str1中的所有字符都在str2中出现过,那么返回str1的长度。如果第一个字符就不在str2中, 阅读全文
posted @ 2012-08-27 15:42 Mr.Rico 阅读(478) 评论(0) 推荐(0) 编辑
摘要:多态性与将实现多态的函数的访问限定符没有任何关系,private 函数仍然可以实现多态,它的指针仍然位于vtbl中,只不过此时该函数的多态一般只能在基类的内部由其他非虚函数调用该函数的时候反映出来(而无法直接在类外部调用该函数来实现多态),访问限定符仅仅限制外部对类的成员的访问权限,它并没有破坏以下规则: 通过基类指针或引用调用成员函数时,如果该函数时非虚的,那么将采用静态绑定,即编译时绑定;如果该函数是虚拟的,则采用动态绑定,即运行时绑定。如下面的例子:#include#includeusingnamespacestd;classBase{private:virtualstringclass 阅读全文
posted @ 2012-08-26 11:13 Mr.Rico 阅读(633) 评论(0) 推荐(0) 编辑
摘要:1. C语言中的 sizeof 问题(1)类型转换的问题#include#defineNUM(sizeof(arr)/sizeof(arr[0]))intarr[]={1,2,3,4,5,6,7};intmain(){inti;for(i=-1;iintmain(){inti;i=10;printf("i:%d\n",i);printf("sizeof(i++)is:%d\n",sizeof(i++));printf("i:%d\n",i);return0;}结果是i : 10sizeof(i++) is: 4i : 10为什么第三个 阅读全文
posted @ 2012-08-25 21:13 Mr.Rico 阅读(398) 评论(0) 推荐(0) 编辑
摘要:1. 一般说来,volatile用在如下的几个地方:(1)、中断服务程序中修改的供其它程序检测的变量需要加volatile;(2)、多任务环境下各任务间共享的标志应该加volatile;(3)、存储器映射的硬件寄存器通常也要加volatile说明,因为每次对它的读写都可能由不同意义;另外,以上这几种情况经常还要同时考虑数据的完整性(相互关联的几个标志读了一半被打断了重写),在1中可以通过关中断来实现,2中可以禁止任务调度,3中则只能依靠硬件的良好设计了。2. 判断char是有符号还是无符号C语言中的char是有符号还是无符号有时候这个问题和平台或者编译器有关,gcc和 Ms cl 都默认是si 阅读全文
posted @ 2012-08-25 21:07 Mr.Rico 阅读(279) 评论(0) 推荐(0) 编辑
摘要:散列Hash函数是一种特殊的映射函数, 散列表Hash Table由散列函数所产生的一种数据结构. 这是一种非常重要的数据结构. 首先, 先了解散列表在数据结构方面的基础: 散列表是用于存储动态集的一种非常有效的数据结构。通过散列函数h(key)的计算结果,直接得到key关键字表示的元素的存储地址。散列技术中,可能会有两个不同的key1和key2,通过h(key)计算得到的地址是一样的,这就发生了冲突。散列技术中散列函数h(key)和解决冲突的技术是最关键的问题。 散列函数要求(1)能快速的计算;(2) 计算结果分布要均匀。 散列函数有如下几种常用的:(1) 除留余数法;(2) 平方取中法;. 阅读全文
posted @ 2012-08-25 20:37 Mr.Rico 阅读(5555) 评论(0) 推荐(1) 编辑
摘要:1. C库中的伪随机函数rand的实现 《The GNU C Library》里说的,大概如下: 公式: Y=(a*X+c)mod m 其中,a,c,m都是常数 一种取值是: a = 0x5DEECE66D = 25214903917 c = 0xb = 11 m = 2^48 用上面的公式可以这样写: __int64rand(){static__int64r=0;const__int64a=25214903917;const__int64c=11;const__int64m=1<<48;r=(r*a+c)%m;returnr;}2. ASNI 随机数生成的理解ANSI中和随机数生 阅读全文
posted @ 2012-08-25 20:29 Mr.Rico 阅读(2311) 评论(0) 推荐(0) 编辑
摘要:getword函数这儿所说的getword函数,是指从一段字符串中提取出其中的单词。其实这儿主要是分析利用一些标点符号和一些空白字符进行分割而成的单词,还没有达到编译器所使用的对字符串的分析。编译器是根据语言的文法对语言的源代码进行分析。一般需要利用编译原理中的文法分析来得到具体的token。而这儿的比较简单。对于C和C++有不同的实现方式。在C语言中有一个函数,strtok可以帮助实现这个。这个函数主要是根据给定的分隔符来对字符串进行分割。实现代码如下:/**10.C语言中利用strtok对字符串根据特定的字符进行划分*/#include#include#includeintgetwords 阅读全文
posted @ 2012-08-25 12:48 Mr.Rico 阅读(2159) 评论(0) 推荐(0) 编辑
摘要:有些成员变量的数据类型比较特别,它们的初始化方式也和普通数据类型的成员变量有所不同。这些特殊的类型的成员变量包括: a. 常量型成员变量(const) b. 引用型成员变量 (&) c. 静态成员变量 (static) d. 整型静态常量成员变量 static const int e. 非整型静态常量成员变量 static const double 1. 常量型成员初始化:只能在构造函数的初始化列表中进行直接初始化。 如: classTest{public:constintMY_MASK;Test():MY_MASK(0xff){}};如果不是在初始化列表中对 const 常量进行初始 阅读全文
posted @ 2012-08-25 12:40 Mr.Rico 阅读(1775) 评论(0) 推荐(0) 编辑
摘要:STL中并没有把heap作为一种容器组件,heap的实现亦需要更低一层的容器组件(诸如list,array,vector)作为其底层机制。Heap是一个类属算法,包含在algorithm头文件中。 在STL中为堆heap的创建和操作提供了4种算法:make_heap,pop_heap,push_heap和sort_heap。1. push_heap: 假定区间[first,last-1)已经包含了一个堆,把区间[first,last)调整为一个堆(从而 把last-1位置上的元素压入堆。 函数原型:voidpush_heap(first,last);voidpush_heap(first,la 阅读全文
posted @ 2012-08-25 08:06 Mr.Rico 阅读(853) 评论(0) 推荐(0) 编辑
摘要:这是摘自《More Effective C++ 2007》条款27:要求或禁止在堆中产生对象要求在堆中建立对象 让我们先从必须在堆中建立对象开始说起。为了执行这种限制,你必须找到一种方法禁止以调用"new"以外的其它手段建立对象。这很容易做到。非堆对象(non-heap object)在定义它的地方被自动构造,在生存时间结束时自动被释放,所以只要禁止使用隐式的构造函数和析构函数,就可以实现这种限制。把这些调用变得不合法的一种最直接的方法是把构造函数和析构函数声明为 private。这样做副作用太大。没有理由让这两个函数都是 private。最好让析构函数成为 private 阅读全文
posted @ 2012-08-19 14:21 Mr.Rico 阅读(778) 评论(0) 推荐(0) 编辑
摘要:这是摘自《More Effective C++ 2007》 条款24:理解虚函数,多重继承,虚基类和RTTI所需的代价 当调用一个虚拟函数时,被执行的代码必须与调用函数的对象的动态类型相一致;指向对象的指针或引用的类型是不重要的。编译器如何能够高效地提供这种行为呢?大多数编译器是使用 virtual table 和 virtual table pointers。virtual table 和 virtual table pointers 通常被分别地称为 vtbl 和 vptr。 一个 vtbl 通常是一个函数指针数组。(一些编译器使用链表来代替数组,但是基本方法是一样的)在程序中的每个类只要 阅读全文
posted @ 2012-08-19 13:45 Mr.Rico 阅读(961) 评论(0) 推荐(0) 编辑
摘要:函数模板与类模板是两大类主要的C++泛型编程的使用方法。类模板可以进行模板偏特化和全特化,而函数模板只能进行全特化。但是类不同的是,函数还有一个重要的特性就是重载,如果将函数模板与函数重载的问题放在一块的时候,问题就变得比较麻烦了。 看下面的一个例子:includeusingnamespacestd;templatevoidf(T){coutvoidf(T*){coutvoidf(int*){cout(int*)"voidf(int*){cout(int*)"(int*)即调用的是第3个函数。这儿容易让人疑惑的是,为什么不是第4个函数:templatevoid f(int* 阅读全文
posted @ 2012-08-17 22:49 Mr.Rico 阅读(1035) 评论(0) 推荐(0) 编辑
摘要:如果想要删除vector中值为val的元素,最容易想到的方法就是对vector进行遍历,然后遇到值为val时就将其删除。比较好的是vector容器有erase操作。但是这儿需要注意,与list中的erase不同,list的erase操作之后,之前获得的迭代器还是有效的,而在vector中因为vector是顺序存储,所以,一旦删除一个元素,之前获得的迭代器就会失效了,vector.begin()和vector.end()是变化的。注意到,erase的返回值是一个迭代器,而这个迭代器就是指向删除之前元素后的第一个元素。注意到这一点我们可以采用下面的方法实现:voidremove_v(vector& 阅读全文
posted @ 2012-08-17 14:51 Mr.Rico 阅读(11579) 评论(0) 推荐(0) 编辑