持续更新中…
1. 字符大小写转换
大写转小写:
char LowChar = (UpperChar | 0X20);
小写转大写:
char UpperChar = (LowChar & -33);
2. 两个整数之和的一半
(x + y) / 2 = (x & y) + ((x ^ y) >> 1)
其中, x x x和 y y y都是整数。
此外,如果是计算一段距离的中点的话,不建议使用和的一半:
int mid = (start + end) / 2; // 这种方法不好,因为有可能x+y的值超过范围了,导致整数溢出
int mid = start + (end - start) / 2; // 这种方法就比较好,不会发生整数的溢出
3. 多线程间数据共享
如果多个线程共享同一个数据,且至少有一个线程是通过非直接方式来获取此数据的值(比如通过指针指向此数据的地址),则这个数据应该定义成volatile的,因为编译器有可能经过优化后,会将数据缓存到寄存器中,导致线程可能会获取到不正确的数据。
4. Windows下使用CreateThread()和_beginthreadex()的区别
根据《Win32多线程程序设计》中的介绍,当创建的子程序中包含某些C runtime 函数时,不应该使用CreateThread()
。
如果主线程以外的任意新建的线程中包含以下操作,则应该使用多线程版本的C runtime library,并使用_beginthreadex()
和_endthreadex()
:
- 在C程序中使用
malloc()
和free()
,或者在C++程序中使用new()
和delete()
; - 调用
stdio.h
或io.h
中声明的任何函数,包括fopen()
、open()
、getchar()
、write()
、printf()
等等。所有这些函数都用到共享的数据结构以及errno
。对于格式化操作,如果不想使用C runtime library的函数,你可以使用wsprintf()
来替代printf()
(wsprintf()是Win内核自己实现的,不依赖于C runtime library,其与printf()大同小异,唯一区别是在浮点数的处理上不同); - 使用浮点变量或者浮点运算函数;
- 调用任何一个使用了静态缓冲区的runtime函数,如
asctime()
、strtok
或rand()
。
如果新建的线程里面没有以上列出来的事项,则可以用单线程版本的runtime library和CreateThread()。
此外,如果要在MFC程序中产生一个线程,而该线程将调用MFC函数或使用MFC的任何数据,那么必须使用AfxBeginThread()
或CWinThread::CreateThread()
来产生线程。
5. 使用共享内存来实现进程间通信注意事项
进程间通信的一种方式是使用共享内存,不管是使用SendMessage()
通过COPYDATASTRUCT
结构体来实现还是通过创建FileMap(文件映射)
的方式来实现,注意,被共享的变量中一定不能含有指针,只能是数值。进程间共享内存只能共享数值,而不能共享地址。比如,如果想把A进程中string对象共享给B进程,则因为string中的真正的字符串是存储在A进程的heap中的,是通过指针来引用的。然而不同进程中,内存环境不一样,所以地址0xabcde
在A进程中可能指到string中的字符串内容,但是此地址在B进程中所指的内容根本与string中的字符串没半毛钱关系,两个进程的地址是独立的。
注意,如果一个类中含有虚函数,则此类的对象也不能被共享,因为此类中含有虚函数表,也是指针。
6. C++ 中函数限定符出现在声明和定义处的整理
1. noexcept:
必须出现在函数的所有声明和定义处;
2. inline:
只需要出现在函数定义处,且此函数只能定义在头文件中,不应该定义在源文件中;
3. explicit:
只能出现在成员函数声明处;
4. static:
只能出现在函数声明处;
5. 函数默认实参:
只能出现在函数声明处;
6. final:
只能出现在函数声明处;
7. override:
只能出现在函数声明处;
7. n 个bit位能表示带符号整数的范围
其范围为 [-2n-1, 2n-1 - 1]。比如4个bit位能表示的整数范围为 [-8, 7]。
8. 判断某个数为奇数或者偶数的快速方法
由于偶数的比特位的最后一位肯定是0,而奇数的最后一位肯定是1,因此使用位运算的方式最快:
int x = 9;
if ((x & 1u ) == 0)
std::cout << "偶数\n";
else
std::cout << "奇数\n";
此外,如果将一个整数除以2的倍数或乘以2的倍数,则可以直接用移位的方式。
9. -fno-elide-constructors作用:
用于G++编译器,用于取消编译器对构造函数的优化,详情百度。
10. 在区间[i, j]之间递增或递减(间隔为t),且无限循环:
int t = 5; // 递增或递减间隔
int i = 1, j = 21; // 区间为[1, 21],闭区间
int x = 0; // 记录的值,开始为0,则从i开始进行递增或递减
while (true)
x = (x - i + t) % (j - i + t) + i; // 递增算法
while (true)
x = (x - 2 * i + j) % (j - i + t) + i; // 递减算法