指针的异或运算可用于交换两个变量的值

Posted 恶魔岛

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了指针的异或运算可用于交换两个变量的值相关的知识,希望对你有一定的参考价值。

指针是不能直接进行异或运算的,需要将指针转换成整型int或long,在Linux系统下只能是long,因为指针在win系统占4个字节,在Linux系统占6个字节。

以下为两个指针的异或运算实现指针的交换:

    #include <stdio.h>
    
    int main()
    {
        int *a,*b;
        unsigned long aa,bb;
    
        printf("a:%p\n", a);
        printf("b:%p\n", b);
    
        aa = (unsigned long)a;    //a变量指针转换成整型
        bb = (unsigned long)b;    //b变量指针转换成整型
  
        printf("\n");
    
        aa ^= bb;
        bb ^= aa;    //此时bb=aa
        aa ^= bb;    //此时aa=bb
    
        a = (int *)aa;        //aa变量指针转换成指针类型
        b = (int *)bb;        //bb变量指针转换成指针类型
    
        printf("a:%p\n", a);
        printf("b:%p\n", b);
       
        return 0;
    }

在Linux 64系统中的运行结果为:

    a:0x7ffc70da4cf0
    b:0x4004e0
    
    a:0x4004e0
    b:0x7ffc70da4cf0

因此我们可以看到,交换两个值也不一定只能借助临时变量,异或运算也是一种选择。

以上代码来源于:https://blog.csdn.net/weixin_39666151/article/details/90731384

下面附上对线性表的置逆操作,使用单链表实现:

#include<iostream>
#include<bits/stdc++.h>
#define int long long
using namespace std;
typedef struct
{
    int len;
    int *next;
    //int listsize;//该项为顺序表的大小,本题不要求 
}node;

//置逆函数 
void Inverse(node *list)
{
    for(int i = 0;i < list->len / 2;i++)//第一个元素与最后一个元素交换,第二个元素与倒数第二个元素交换,以此类推,只要进行到表的一半即可,也可以用临时变量来交换数值,这样做需要增加额外的存储空间,^表示异或运算 
    {
        list->next[i] = list->next[i]^list->next[list->len - i - 1];
        list->next[list->len - i - 1] = list->next[i]^list->next[list->len - i - 1];
        list->next[i] = list->next[i]^list->next[list->len - i - 1];
    }

}

void Print(node *list)
{
    for(int i = 0;i < list->len;i++)//遍历 
        cout << list->next[i] << " ";
    cout << endl;
}


signed main()//主函数,顺序表的初始化及销毁直接在主函数中实现了 
{
    int i = 0;
    node *list;//定义一个结构体node指针 
    list = (node *)malloc(sizeof(node));//为该指针动态申请存储空间 
    
    cout << "请输入元素个数:";
    cin >> list->len;//输入顺序表的长度 
    list->next = (int *)malloc(sizeof(int)*list->len);//为固定好长度的顺序表动态申请存储空间 ,强制转换为int型,之后再置逆的过程中可使用异或运算符,指针本身不能使用异或运算 
    
    cout << "请输入元素:";
    for(i = 0;i < list->len;i++)//循环输入元素,用指针数组存储 
        cin >> list->next[i];
    
    cout << "置逆前的表为:";
    Print(list);//自定义函数输出 
    Inverse(list);//置逆操作 
    cout << "置逆后的表为:";
    Print(list);//输出置逆后的 
    
    free(list->next);//释放开辟的空间,不要忘记结构体中的指针 
    free(list);
    
    return 0;
}

下面附上线性表的置逆,用顺序表实现

#include<iostream>
#define int long long
#include<map>
using namespace std;

signed main()
{
    int n;
    int vis[100];
    cin >> n;
    for(int i = 1;i <= n;i++)
        cin >> vis[i];
    int i = 1;
    int j = n;
    while(i < j)
    {
        int temp;
        temp = vis[i];
        vis[i] = vis[j];
        vis[j] = temp;
        i++;
        j--;
    }
    for(int i = 1;i <= n;i++)
        cout << vis[i] << " ";
    cout << endl;    
    return 0;
}

对上述单链表的操作好好参悟参悟

以上是关于指针的异或运算可用于交换两个变量的值的主要内容,如果未能解决你的问题,请参考以下文章

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?

浅谈java两个数的异或交换以及反射和Integer的缓存机制

Java位运算:位异或运算位与运算位或运算位取反运算左位移运算右位移运算无符号右移运算不用额外变量交换两个整数的值(使用位异或运算)

JavaSE7基础 使用位运算异或 进行两个变量的数值交换

java 交换两个数的值(临时变量,加减,异或)

Java位运算:位异或运算位与运算位或运算位取反运算左位移运算右位移运算无符号右移运算不用额外变量交换两个整数的值(使用位异或运算)只出现一次的数字