#每日一题:浅谈交换两个数的几种方法#

1. Question & Analysis

  1. Question: 输入两个数,把它们交换后并输出;
  2. Analysis: 我目前接触到的题目,有点点难度的就是不允许定义中间临时变量完成两个数进行交换;他们考这些题目的时候一般操作数都是整型数字,我这里想尝试一下浮点数,看能不能准确输出想要的结果!

2.Code Module

  1. 直接在主函数中创建临时变量完成交换:

    #include <stdio.h>
    int main(int agrc, const char* agrv[]) {
        double a, b;
        scanf("a=%lf,b=%lf", &a, &b);
     
        double tmp = a;
        a = b;
        b = tmp;
     
        printf("a=%lf,b=%lf\n", a, b);
     
        return 0;
    }
    
  2. 通过指针操作完成交换:

    #include <stdio.h>
     
    void exchange(double* i, double* j) {
        double k = *i;
        *i = *j;
        *j = k;
    }
     
    int main() {
        double a, b;
        scanf("a=%lf,b=%lf", &a, &b);
        exchange(&a, &b);
        printf("a = %lf, b = %lf\n", a, b);
        return 0;
    }
    
  3. 通过位操作符"^",不创建临时变量:

    #include <stdio.h>
    int main(int agrc, const char* agrv[]) {
        double a, b;
        scanf("a=%lf,b=%lf", &a, &b);
     
        a = a ^ b; // 报错!操作数必须为整型;
        b = a ^ b; // 同上;
        a = a ^ b; // 同上;
     
        printf("a=%lf,b=%lf\n", a, b);
     
        return 0;
    }
    

3. Summary

这里提醒一点2.3中位操作符的操作数必须为整型。 说一下我的测试发现,以上2.1&2.2的输入和输出如下:

  • 输入:a = 3.1415925, b = 0.6180335
  • 输出:a = 0.618034, b = 3.141592

由此可以看出,printf("%lf\n", goal_num); 输出浮点数的时候,默认保留六位小数,且默认遵循"向偶舍入"。

另外,我想,关于交换两个操作数,肯定还有其他比较漂亮的方法,我这里就是抛砖引玉,记录一下,哈哈哈 smile 期待大家能够一起讨论分享。(在此再次感谢上个帖子为我解惑的大佬们,你们的评论真的很有价值!),所以说,逛贴子最有意思的还是看评论区,收获很大。 smile

c++·c
150 views
Comments
登录后评论
Sign In
·

有个小小的疑问,在编辑窗口编辑帖子的时候 "由此可以看出,printf("%lf\n", goal_num);" 为啥我想输入"\n", '\'会被转义掉,然后就隐藏起来了,所以实际需要多加一个"\"来解决被转移的问题。现在评论区也是这样。我能手动@HD Superman 吗?哈哈哈 smile

·

没什么其他方法了,你几乎已经列举完了,C语言的语法就只有这么多,怎么操作也离不开变量和指针还有函数,那个题目的意思应该就是想让你使用指针在函数间传值

还有第三种方法实际上并没有很好,看似不需要创建临时变量,实际上代码可读性并没有很好,性能也一般,普适性也差,在编译器开启优化的前提下,方法一创建的临时变量能直接被优化掉,直接使用寄存器交换变量,在一些场景下性能优于方法二和方法三

一种比较hack的方法是,直接交换要输出的变量位置就好了printf(xx,a,b)->printf(xx,b,a),什么交换变量都是不存在的

不过C++标准库中有个很好的方法(只能在C++中使用),std::swap,利用移动语义避免了临时变量的构造开销(对基本类型来说没什么差别),使用起来比较优雅,如果你以后学C++的话可以看看

还有就是Python交换变量的写法,相当漂亮,x,y = y,x

·

这里我可以提供两个错误的写法:

void swap_XOR(int* a, int* b) {
   *a = *a ^ *b;
   *b = *a ^ *b;
   *a = *a ^ *b;
}
void swap_add(int* a, int* b) {
   *a = *a + *b;
   *b = *a - *b;
   *a = *a - *b;
}

当指针a和指针b指向同一个内存时,无论它们共同指向地址是什么数值,最后都将被赋予0

·

兄弟,你这scanf用得太可怕了,我之前还都没有发现,格式字符串不要和printf的搞混了