c实现swap函数陷阱
swap函数陷阱
使用c实现一个交换两个数的函数,代码很简单:
void swap(int *a, int *b)
{
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
只有3行代码,且没有引入中间变量,使用了位运算,效率高!
但一个明显的缺陷是没有检查空指针,于是代码修正为:
void swap(int *a, int *b)
{
if (a == NULL || b == NULL)
return;
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
似乎这样就完美了?
看看以下代码:
static int count = 0;
void permutation(int *a, int from, int to)
{
if (from == to) {
cout << ++count << ":";
for (int i = 0; i <= to; ++i)
cout << a[i] << " ";
cout << endl;
return;
}
for (int i = from; i <= to; ++i) {
swap(&a[from], &a[i]);
permutation(a, from + 1, to);
swap(&a[from], &a[i]);
}
}
以上代码功能很简单,使用递归的方式输出数组的全排列,核心算法肯定是没有问题的。可是运行以上代码,输出大量的0!!
why ?
答案在于swap函数还没有考虑当a,b是同一个指针的情况,当a == b时, *a ^= *b,结果必然为0,因此结果为*a == *b == 0,
因此正确的swap函数应该是这样的:
void swap(int* a, int* b)
{
if (a == NULL || b == NULL || a == b)
return;
*a ^= *b;
*b ^= *a;
*a ^= *b;
}
c实现swap函数陷阱的更多相关文章
- 关于swap函数传值的问题
#include <stdio.h> void swap(int * p3,int * p4); int main() { int a = 9; int b = 8; int * p ...
- 自己写一个swap函数交换任意两个相同类型元素的值 对空指针的使用 字节大小的判断(二)了解原理
验证的代码: #include <stdio.h> int main(){ char c = 'z'; ) + (c << ) + () + 'a'; printf(" ...
- swap函数的四种写法
swap 函数的四种写法 (1)经典型 --- 嫁衣法 void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } ( ...
- c++ swap 函数
转载地址 1,最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符. template <class T> void swap ( T& a, T& b ) { T ...
- [转]谈谈C++中的swap函数
1,最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符. template <class T> void swap ( T& a, T& b ) { T c(a) ...
- [Effective C++ --025]考虑写出一个不抛异常的swap函数
引言 在我的上一篇博客中,讲述了swap函数. 原本swap只是STL的一部分,而后成为异常安全性编程的脊柱,以及用来处理自我赋值可能性. 一.swap函数 标准库的swap函数如下: namespa ...
- [020]转--C++ swap函数
原文来自:http://www.cnblogs.com/xloogson/p/3360847.html 1.C++最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符 template < ...
- 从Swap函数谈加法溢出问题
1. 初始题目 面试题:). 这个题目太经典,也太简单,有很多人都会不假思索结出答案: //Code 1 void Swap(int* a, int* b) { *a = *a + *b; ...
- EC读书笔记系列之13:条款25 考虑写出一个不抛异常的swap函数
记住: ★当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定其不抛出异常 ★若你提供一个member swap,也该提供一个non-member swap来调用前者.对于cla ...
随机推荐
- php高版本安装ecshop错误解决方法
1.Strict Standards: Non-static method cls_image::gd_version() should not be called statically in F:\ ...
- Dart编程实例 - Const 关键字
Dart编程实例 - Const 关键字 void main() { final v1 = 12; const v2 = 13; v2 = 12; } 本文转自:http://codingdict.c ...
- css样式总结体会
css属性值语法:https://developer.mozilla.org/zh-CN/docs/Web/CSS/Value_definition_syntax 1.margin-top属性不起作用 ...
- [NOIP模拟23]题解
中间鸽了好几篇啊QAQ……有时间再补吧…… A.mine sbdp,考场上写的巨麻烦不过还是能A的(虽然MLE了……每一维都少开1就A掉了555).设$dp[i][j][k]$为枚举到第i位,第i位是 ...
- 【spring】1.2、Spring Boot创建项目
Spring Boot创建项目 在1.1中,我们通过"Spring Starter Project"来创建了一个项目,实际上是使用了Pivotal团队提供的全新框架Spring B ...
- LInux多线程编程----线程特定数据的处理函数
1.pthread_key_t和pthread_key_create() 线程中特有的线程存储, Thread Specific Data .线程存储有什么用了?他是什么意思了?大家都知道,在多线程程 ...
- 【hive 日期函数】Hive常用日期函数整理
1.to_date:日期时间转日期函数 select to_date('2015-04-02 13:34:12');输出:2015-04-02122.from_unixtime:转化unix时间戳到当 ...
- spark hive java.lang.NoSuchFieldError: HIVE_STATS_JDBC_TIMEOUT
java.lang.NoSuchFieldError: HIVE_STATS_JDBC_TIMEOUT 这个问题我感觉是hive给spark挖的一个大坑.spark版本是2.4.4,hive是3 这个 ...
- 拾遗:Docker 基本应用
https://wiki.gentoo.org/wiki/Docker 检查内核内核选项 exec /usr/share/docker/contrib/check-config.sh 使用 btrfs ...
- Java多线程sleep和wait的区别,总结得非常好。
我们都知道sleep是让线程休眠,到时间后会继续执行,wait是等待,需要唤醒再继续执行,那么这两种方法在多线程中的表现形态,它们各有什么区别呢? 可以总结为以下几点. 使用上 从使用角度看,slee ...