利用位运算和指针实现的交换两个数的程序

位运算是C语言的一大特色,利用异或运算可以实现交换两个数,原理是一个整数与另外一个数进行两次异或运算仍然是其本身,基本原理用式子表达如下:

(1) A ^ A = 0;

(2) A = A ^B;

(3) B = A ^B;(相当于B = A ^ B ^ B ,即 B = A)

(4) A= A ^ B;(相当于A = A ^B ^A ,即A = B)

利用位运算不仅提高了代码的执行速度,而且此处还减少了对辅助变量的需求,因此提高了程序的效率。

一个具体的程序如下:

  1. #include<stdio.h>  
  2. void swap(int *a, int *b)  
  3. {  
  4.     *a = (*a)  ^  (*b);  
  5.     *b = (*a)  ^  (*b);  
  6.     *a = (*a)  ^  (*b);  
  7. }  
  8. int main(void)  
  9. {  
  10.     int a, b;  
  11.     printf("please input two integers for example 3 4/n");  
  12.     scanf("%d %d",&a,&b);  
  13.     printf("Before swap a = %d, b = %d/n",a,b);  
  14.     swap(&a,&b);  
  15.     printf("After swap a = %d, b = %d/n",a,b);  
  16. }  
不得不说赞两句 硬盘上的二进制数据 用这个方法有效地交换数据 不需要第三方变量 实在是不错
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
### 回答1: 可以使用字符串来表示超长正整数,然后按照加法的规则逐位相加,注意进位即可。具体实现可以参考以下伪代码: 1. 读入个超长正整数 num1 和 num2 2. 将 num1 和 num2 转换为字符串形式,分别保存在 str1 和 str2 中 3. 如果 str1 的长度小于 str2 的长度,则交换 str1 和 str2,使得 str1 的长度不小于 str2 4. 定义一个空字符串 result,用于保存相加的结果 5. 定义指针 i 和 j,分别指向 str1 和 str2 的末尾 6. 定义一个变量 carry,表示进位,初始值为 0 7. 从末位开始,依次将 str1 和 str2 对应位置的数字相加,再加上进位 carry,得到一个新的数字 sum 8. 如果 sum 大于等于 10,则需要进位,将 carry 设为 1,否则 carry 设为 0 9. 将 sum 对 10 取余,得到当前位的数字,将其转换为字符并添加到 result 的开头 10. 将 i 和 j 分别减 1,继续处理下一位,直到 i 和 j 都小于 0 11. 如果最后 carry 不为 0,则需要在 result 的开头再添加一个字符 '1' 12. 输出 result 注意,以上伪代码只是一种实现思路,具体实现方式可能会有所不同,需要根据具体情况进行调整。 ### 回答2: 超长正整数加法运算需要考虑到个问题,一是数据的存储,二是运算的逻辑。 对于数据的存储,可以考虑使用字符串来表示超长正整数,每个字符代表一位数字,然后通过对字符串进行逐位遍历来实现加法运算。可以通过从字符串末尾开始遍历,依次将个数相同位置的数字相加并进位,最后将结果逆序输出得到最终结果。 对于加法运算的逻辑,需要考虑到进位的情况。例如,对于个数的个位数相加,如果结果大于等于10,则需要进位到十位数,同时将个位数的余数加到下一位数的计算中去。因此,在计算过程中必须记录下进位数,并在下一位计算时加上进位数。 示例代码如下: ``` #include <stdio.h> #include <string.h> #define MAX_LEN 1000 void long_add(char* num1, char* num2, char* result) { int len1 = strlen(num1); int len2 = strlen(num2); int i = 0, j = 0, k = 0, carry = 0; // 从末尾开始相加 for (i = len1 - 1, j = len2 - 1, k = 0; i >= 0 || j >= 0; i--, j--, k++) { int x = i >= 0 ? num1[i] - '0' : 0; int y = j >= 0 ? num2[j] - '0' : 0; int sum = x + y + carry; result[k] = sum % 10 + '0'; carry = sum / 10; } // 如果最后一位有进位,需要在结果中加入进位 if (carry == 1) { result[k] = '1'; k++; } // 反转字符串得到最终结果 for (i = 0; i < k / 2; i++) { char temp = result[i]; result[i] = result[k - i - 1]; result[k - i - 1] = temp; } result[k] = '\0'; // 字符串末尾加上\0 } int main() { char num1[MAX_LEN], num2[MAX_LEN], result[MAX_LEN]; scanf("%s %s", num1, num2); long_add(num1, num2, result); printf("%s\n", result); return 0; } ``` 该程序中通过声明`num1`,`num2`,`result`三个字符串数组来存储个超长正整数和它们的和,其中`MAX_LEN`表示字符串数组的最大长度。在主函数中,首先通过`scanf`语句读入个超长正整数,然后调用`long_add`函数来计算它们的和并存储到`result`数组中,最后通过`printf`语句输出结果。`long_add`函数中通过循环依次遍历个输入的字符串,将对应位上的数字相加并加上进位数,然后将结果存储到`result`数组中。计算完成后,再通过一个循环将`result`数组中的字符按照反序逐个输出,得到最终的加法结果。 需要注意的是,在`long_add`函数中需要判断最后一位加法是否有进位,并在结果最后加上进位数字。并且,需要将`result`数组末尾加上`\0`,以保证它是一个合法的字符串。 ### 回答3: 在编写程序实现个超长正整数的加法运算之前,需要先明确超长正整数的存储问题。由于超长正整数可能达到甚至超过计算机的最大数值范围,因此需要使用字符串或数组来存储。 一般来说,将超长正整数转换为字符串或字符数组,并判断每一位数值的大小,最后进行运算即可。在程序中,可以借助循环结构来遍历每一位数值,并将结果保存在一个新的字符串或数组中。 具体步骤如下: 1. 将个超长正整数按照相同的长度对齐,不足位数的用0进行补齐。 2. 从个数的最后一位开始,依次对每一位数值进行相加,并保存进一个结果数组中。 3. 遍历结果数组,将每一位数值进位,直至所有位数值都在0~9以内。注意最高位可能需要进位,此时需要新开一个数组存储。 4. 将结果数组转换为字符串或字符数组。 下面给出一个最简单的示例代码,仅供参考: ``` #include <iostream> #include <cstring> using namespace std; int main() { string a, b; cin >> a >> b; int len_a = a.length(); int len_b = b.length(); int max_len = max(len_a, len_b); int numa[max_len+1] = {0}; int numb[max_len+1] = {0}; int numc[max_len+2] = {0}; for(int i = 0; i < len_a; i++) { numa[i] = a[len_a-1-i] - '0'; } for(int i = 0; i < len_b; i++) { numb[i] = b[len_b-1-i] - '0'; } for(int i = 0; i < max_len; i++) { numc[i] += numa[i] + numb[i]; numc[i+1] += numc[i] / 10; numc[i] %= 10; } int len_c = max_len; if(numc[len_c] > 0) { len_c++; } for(int i = len_c-1; i >= 0; i--) { cout << numc[i]; } cout << endl; return 0; } ``` 需要注意的是,以上代码并没有考虑超长正整数溢出的问题,也没有考虑数相加超出了数值范围的情况,因此在实际应用中还需要进一步完善。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值