菜鸟的算法基础

一、交换算法

C语言交换两个数的3种实现方法(附完整示例)

交换两个数是C语言基础操作,以下提供3种核心实现方式,涵盖「通用无风险」「无临时变量」等场景,附原理、代码和优缺点分析。

方法1:临时变量法(最推荐,通用无风险)

核心思路

定义一个临时变量作为"中转站",先保存其中一个数的值,再完成交换,是最基础、通用且无副作用的方法,适用于所有数据类型(int/float/double等)。

代码示例

c 复制代码
#include <stdio.h>

// 交换整数(通用版,可适配其他类型)
void swap(int *a, int *b) {
    int temp; // 临时变量
    temp = *a; // 保存a的值到临时变量
    *a = *b;   // 把b的值赋给a
    *b = temp; // 把临时变量(原a值)赋给b
}

// 测试交换浮点数(仅需修改类型)
void swap_float(float *a, float *b) {
    float temp;
    temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    // 测试交换整数
    int x = 10, y = 20;
    printf("交换前:x=%d, y=%d\n", x, y);
    swap(&x, &y); // 传地址(指针),才能修改原变量
    printf("交换后:x=%d, y=%d\n\n", x, y);

    // 测试交换浮点数
    float m = 3.14, n = 6.28;
    printf("交换前:m=%.2f, n=%.2f\n", m, n);
    swap_float(&m, &n);
    printf("交换后:m=%.2f, n=%.2f\n", m, n);

    return 0;
}

优点&缺点

  • ✅ 优点:逻辑简单、无溢出风险、适配所有数据类型(整数/浮点/字符等);
  • ❌ 缺点:需要额外占用1个临时变量的内存(可忽略,几乎无影响)。

方法2:算术运算法(不用临时变量,仅适用于数值类型)

核心思路

利用「加减运算」抵消值的差异,无需临时变量,但仅适用于整数/浮点型,且两个大数相加可能触发溢出(超出数据类型取值范围)。

代码示例

c 复制代码
#include <stdio.h>

void swap(int *a, int *b) {
    *a = *a + *b; // a = 原a + 原b
    *b = *a - *b; // b = (原a+原b) - 原b = 原a
    *a = *a - *b; // a = (原a+原b) - 原a = 原b
}

int main() {
    int x = 5, y = 8;
    printf("交换前:x=%d, y=%d\n", x, y);
    swap(&x, &y);
    printf("交换后:x=%d, y=%d\n", x, y);
    return 0;
}

优点&缺点

  • ✅ 优点:无需临时变量,代码简洁;
  • ❌ 缺点:
    1. 仅适用于数值类型(无法交换字符/字符串等);
    2. 整数相加可能溢出(如a=2^30,b=2^30,相加后超出int范围);
    3. 若a和b指向同一地址(swap(&x, &x)),结果会变为0(逻辑错误)。

方法3:位运算法(异或,仅适用于整数)

核心思路

利用异或运算(^) 的特性:

  • 一个数异或自身等于0(a^a=0);
  • 一个数异或0等于自身(a^0=a);
  • 异或满足交换律和结合律(a^b^c = a^(b^c))。
    仅适用于整数类型(char/int/long等),无溢出风险。

代码示例

c 复制代码
#include <stdio.h>

void swap(int *a, int *b) {
    if (a == b) return; // 避免同一地址异或后变为0
    *a = *a ^ *b; // 步骤1:a = 原a ^ 原b
    *b = *a ^ *b; // 步骤2:b = (原a^原b) ^ 原b = 原a
    *a = *a ^ *b; // 步骤3:a = (原a^原b) ^ 原a = 原b
}

int main() {
    int x = 100, y = 200;
    printf("交换前:x=%d, y=%d\n", x, y);
    swap(&x, &y);
    printf("交换后:x=%d, y=%d\n", x, y);
    return 0;
}

优点&缺点

  • ✅ 优点:无需临时变量、无溢出风险、仅操作二进制位,效率高;
  • ❌ 缺点:
    1. 仅适用于整数类型(无法交换浮点/字符);
    2. 可读性差(需理解异或特性);
    3. 若a和b指向同一地址,结果会变为0(需加判断规避)。

关键注意事项

  1. 传参方式:上述代码均用「指针传参」,因为C语言默认是"值传递",直接传变量会复制一份值,无法修改原变量;
  2. 选型建议 :
    • 日常开发/通用场景:优先用「临时变量法」(无坑、易维护);
    • 嵌入式/内存极度受限场景:用「位运算法」(仅整数);
    • 避免用「算术运算法」(溢出风险高);
  3. 扩展适配 :若需交换其他类型(如double/char),只需修改临时变量法的类型即可,无需改逻辑。
复制代码
相关推荐
学长毕设8 小时前
基于SpringBoot的实验室资产管理系统
java·spring boot·后端
zzu123zsw9 小时前
从臃肿的模板调用到声明式契约:深入 UniHttp 动态代理与多渠道生命周期扩展
java·spring boot·microsoft·unihttp
UIU1149 小时前
P1233 [ICPC 2001 Taejon R] 木棍加工
数据结构·c++·算法·动态规划
源码集结号10 小时前
云诊所门诊系统源码,基于SpringBoot+Vue.js架构,支持多租户设计与Docker容器化部署
java·spring boot·源码·医院信息系统·门诊系统·诊所系统
论文复现现场10 小时前
WRF、FEA 能用 L40S 加速吗?求解器检查、断点恢复与长期运行
java·数据库·算法·wrf·有限元分析·gpu计算·断点续算
ZhengEnCi10 小时前
用 AI 写代码为什么拼到最后还是拼人:算力瓶颈与领域专家提示词的本质差异
算法·架构
啃瓜子的松鼠10 小时前
泛微OAe9-后端二开异步调用
java
秋天的怀念_David11 小时前
第二十一夜 · 数字黑洞与西西弗斯的惩罚
java·程序人生·算法
外收内放11 小时前
Python基础语法练习题(73)
java·前端·python
Wang's Blog11 小时前
Java 项目实战: 交友项目 - 环信后台发送消息测试
java·交友