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 ...
随机推荐
- 离线+生成树+并查集——cf1213G
#include<bits/stdc++.h> using namespace std; #define N 200005 #define ll long long struct Edge ...
- Elasticsearch之index_closed_exception
索引的打开与关闭 关闭索引 POST /index_name/_close 尝试插入数据 PUT /shakespeare/_doc/ { "title":"kibana ...
- python对具有宏excel的操作
一.使用win32com库 安装pip install pypiwin32 import win32com.client #excel xlApp =win32com.client.DispatchE ...
- java做题笔记
java做题笔记 1. 初始化过程是这样的: 1.首先,初始化父类中的静态成员变量和静态代码块,按照在程序中出现的顺序初始化: 2.然后,初始化子类中的静态成员变量和静态代码块,按照在程序中出现的顺序 ...
- 数据可视化(Echart) :柱状图、折线图、饼图等六种基本图表的特点及适用场合
数据可视化(Echart) 柱状图.折线图.饼图等六种基本图表的特点及适用场合 参考网址 效果图 源码 <!DOCTYPE html> <html> <head> ...
- idea无法引用jar包中的class
最近由eclipse换idea的过程中,出现了一个很奇妙的问题! 项目是maven+git+idea管理的,idea某次在使用的过程中,电脑死机重启后,发现无法引用jar包中的class.包括jdk中 ...
- 2.3 Gulp
在前端工程化中最重要的就是流程管理,借用 gulp 可以很方便的基于流的方式定义流程任务,并将任务串联起来,本节中将详细介绍 gulp ,包括: gulp 介绍 gulp 是什么 gulp 能够解决哪 ...
- flink中对于window和watermark的一些理解
package com.chenxiang.flink.demo; import java.io.IOException; import java.net.ServerSocket; import j ...
- Laravel/php 一些调试技巧
1. 模型属性不知道哪里修改? 直接覆盖模型的 setAttribute 方法,监测到某一个属性改动的时候,抛一个异常就可以看到堆栈了 use Illuminate\Database\Eloquent ...
- C# WinForm 第一个项目控件使用心得
1.控件心得 1.1 基础控件 panel 作用:布局 难点:重绘边框改变颜色 重绘panel里如果有fill填充控件 panle的padding要改个值 private void pnlPaintB ...