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函数陷阱的更多相关文章

  1. 关于swap函数传值的问题

    #include <stdio.h> void swap(int * p3,int * p4); int main() {  int a = 9;  int b = 8;  int * p ...

  2. 自己写一个swap函数交换任意两个相同类型元素的值 对空指针的使用 字节大小的判断(二)了解原理

    验证的代码: #include <stdio.h> int main(){ char c = 'z'; ) + (c << ) + () + 'a'; printf(" ...

  3. swap函数的四种写法

    swap 函数的四种写法 (1)经典型 --- 嫁衣法 void swap(int *a, int *b) { int temp; temp = *a; *a = *b; *b = temp; } ( ...

  4. c++ swap 函数

    转载地址 1,最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符. template <class T> void swap ( T& a, T& b ) { T ...

  5. [转]谈谈C++中的swap函数

    1,最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符. template <class T> void swap ( T& a, T& b ) { T c(a) ...

  6. [Effective C++ --025]考虑写出一个不抛异常的swap函数

    引言 在我的上一篇博客中,讲述了swap函数. 原本swap只是STL的一部分,而后成为异常安全性编程的脊柱,以及用来处理自我赋值可能性. 一.swap函数 标准库的swap函数如下: namespa ...

  7. [020]转--C++ swap函数

    原文来自:http://www.cnblogs.com/xloogson/p/3360847.html 1.C++最通用的模板交换函数模式:创建临时对象,调用对象的赋值操作符 template < ...

  8. 从Swap函数谈加法溢出问题

    1.      初始题目 面试题:). 这个题目太经典,也太简单,有很多人都会不假思索结出答案: //Code 1 void Swap(int* a, int* b) { *a = *a + *b; ...

  9. EC读书笔记系列之13:条款25 考虑写出一个不抛异常的swap函数

    记住: ★当std::swap对你的类型效率不高时,提供一个swap成员函数,并确定其不抛出异常 ★若你提供一个member swap,也该提供一个non-member swap来调用前者.对于cla ...

随机推荐

  1. php高版本安装ecshop错误解决方法

    1.Strict Standards: Non-static method cls_image::gd_version() should not be called statically in F:\ ...

  2. Dart编程实例 - Const 关键字

    Dart编程实例 - Const 关键字 void main() { final v1 = 12; const v2 = 13; v2 = 12; } 本文转自:http://codingdict.c ...

  3. css样式总结体会

    css属性值语法:https://developer.mozilla.org/zh-CN/docs/Web/CSS/Value_definition_syntax 1.margin-top属性不起作用 ...

  4. [NOIP模拟23]题解

    中间鸽了好几篇啊QAQ……有时间再补吧…… A.mine sbdp,考场上写的巨麻烦不过还是能A的(虽然MLE了……每一维都少开1就A掉了555).设$dp[i][j][k]$为枚举到第i位,第i位是 ...

  5. 【spring】1.2、Spring Boot创建项目

    Spring Boot创建项目 在1.1中,我们通过"Spring Starter Project"来创建了一个项目,实际上是使用了Pivotal团队提供的全新框架Spring B ...

  6. LInux多线程编程----线程特定数据的处理函数

    1.pthread_key_t和pthread_key_create() 线程中特有的线程存储, Thread Specific Data .线程存储有什么用了?他是什么意思了?大家都知道,在多线程程 ...

  7. 【hive 日期函数】Hive常用日期函数整理

    1.to_date:日期时间转日期函数 select to_date('2015-04-02 13:34:12');输出:2015-04-02122.from_unixtime:转化unix时间戳到当 ...

  8. spark hive java.lang.NoSuchFieldError: HIVE_STATS_JDBC_TIMEOUT

    java.lang.NoSuchFieldError: HIVE_STATS_JDBC_TIMEOUT 这个问题我感觉是hive给spark挖的一个大坑.spark版本是2.4.4,hive是3 这个 ...

  9. 拾遗:Docker 基本应用

    https://wiki.gentoo.org/wiki/Docker 检查内核内核选项 exec /usr/share/docker/contrib/check-config.sh 使用 btrfs ...

  10. Java多线程sleep和wait的区别,总结得非常好。

    我们都知道sleep是让线程休眠,到时间后会继续执行,wait是等待,需要唤醒再继续执行,那么这两种方法在多线程中的表现形态,它们各有什么区别呢? 可以总结为以下几点. 使用上 从使用角度看,slee ...