一些编程或者算法小技巧或小知识点

持续更新中…




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.hio.h中声明的任何函数,包括fopen()open()getchar()write()printf()等等。所有这些函数都用到共享的数据结构以及errno。对于格式化操作,如果不想使用C runtime library的函数,你可以使用wsprintf()来替代printf()(wsprintf()是Win内核自己实现的,不依赖于C runtime library,其与printf()大同小异,唯一区别是在浮点数的处理上不同);
  • 使用浮点变量或者浮点运算函数;
  • 调用任何一个使用了静态缓冲区的runtime函数,如asctime()strtokrand()

如果新建的线程里面没有以上列出来的事项,则可以用单线程版本的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; // 递减算法

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值