虹软笔试题

Yale_Yange 2013-05-24 09:18:21
不用三方参数,实现i和j之间的值的交换(方法越多,加分越多)
int i=6;
int j=5;
...


我仅仅只能想到两种:
i=i^j;
j=i^j;
i=i^j;

i=i+j;
j=i-j;
i=i-j;

有没有更多的方法,拓展下思路
...全文
1163 33 打赏 收藏 转发到动态 举报
写回复
用AI写文章
33 条回复
切换为时间正序
请发表友善的回复…
发表回复
Yale_Yange 2013-05-25
  • 打赏
  • 举报
回复
引用 30 楼 zhao4zhong1 的回复:
#include <stdio.h>
#define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0)
char   *p1="1" ,*p2="2" ;
char    c1=1   , c2=2   ;
short   s1=1   , s2=2   ;
int     i1=1   , i2=2   ;
__int64 I1=1i64, I2=2i64;
float   f1=1.0f, f2=2.0f;
double  d1=1.0 , d2=2.0 ;
void main() {
    SWAP((int)p1,(int)p2);                printf("char *     %5s,   %5s\n",p1,p2);
    SWAP(c1,c2);                          printf("char       %5d,   %5d\n",c1,c2);
    SWAP(s1,s2);                          printf("short      %5d,   %5d\n",s1,s2);
    SWAP(i1,i2);                          printf("int        %5d,   %5d\n",i1,i2);
    SWAP(I1,I2);                          printf("__int64 %5I64d,%5I64d\n",I1,I2);
    SWAP(*(int     *)&f1,*(int     *)&f2);printf("float      %5g,   %5g\n",f1,f2);
    SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double    %5lg,  %5lg\n",d1,d2);

    SWAP(c1,c1);
    printf("%d\n",c1);
}
//char *         2,       1
//char           2,       1
//short          2,       1
//int            2,       1
//__int64     2,    1
//float          2,       1
//double        2,      1
//2
学习了
  • 打赏
  • 举报
回复
引用 30 楼 zhao4zhong1 的回复:
#include <stdio.h>
#define SWAP(a,b) do ((&(a))!=(&(b)))?((a)^=(b)^=(a)^=(b)):((a)=(a)); while (0)
char   *p1="1" ,*p2="2" ;
char    c1=1   , c2=2   ;
short   s1=1   , s2=2   ;
int     i1=1   , i2=2   ;
__int64 I1=1i64, I2=2i64;
float   f1=1.0f, f2=2.0f;
double  d1=1.0 , d2=2.0 ;
void main() {
    SWAP((int)p1,(int)p2);                printf("char *     %5s,   %5s\n",p1,p2);
    SWAP(c1,c2);                          printf("char       %5d,   %5d\n",c1,c2);
    SWAP(s1,s2);                          printf("short      %5d,   %5d\n",s1,s2);
    SWAP(i1,i2);                          printf("int        %5d,   %5d\n",i1,i2);
    SWAP(I1,I2);                          printf("__int64 %5I64d,%5I64d\n",I1,I2);
    SWAP(*(int     *)&f1,*(int     *)&f2);printf("float      %5g,   %5g\n",f1,f2);
    SWAP(*(__int64 *)&d1,*(__int64 *)&d2);printf("double    %5lg,  %5lg\n",d1,d2);

    SWAP(c1,c1);
    printf("%d\n",c1);
}
//char *         2,       1
//char           2,       1
//short          2,       1
//int            2,       1
//__int64     2,    1
//float          2,       1
//double        2,      1
//2
老赵V5.收了,学习。
失散糖 2013-05-24
  • 打赏
  • 举报
回复
push i push j pop i pop j
mujiok2003 2013-05-24
  • 打赏
  • 举报
回复
现在这写“技巧”没有必要了,不安全。 异或的做法应该安全,但是可读性性依然很差。 内嵌汇编的做法,牺牲了可移植性。

int a, b;
std::swap(a,b);
Yale_Yange 2013-05-24
  • 打赏
  • 举报
回复
引用 20 楼 palm008 的回复:
void swap1(int &a,int &b)
{
    a=a+b;
    b=a-b;
    a=a-b;
    return ;
}
void swap2(int &a,int &b)
{
    a=a^b;
    b=a^b;
    a=a^b;
    return ;
}

void swap3(int &a,int &b)
{
    __asm
    {
        mov eax,dword ptr[a];
        mov ecx,dword ptr[eax];

        mov ebx,dword ptr[b];
        mov edx,dword ptr[ebx];

        mov dword ptr[eax],edx;
        mov dword ptr[ebx],ecx;
    }
}

void swap4(int &a,int &b)
{
    __asm
    {       
        mov eax,dword ptr[a];
        push eax;
        mov eax,dword ptr[eax];
        mov ebx,dword ptr[b];
        mov ecx,dword ptr[ebx];
        xchg eax,dword ptr[ebx];
        pop eax;
        xchg ecx,dword ptr[eax];     
    }
}
本来想点引用的,点错了,不好意思 另外,感觉好厉害,虽然学过汇编,但是没想到还可以用__asm内联,这还真是第一次见,多谢!
nice_cxf 2013-05-24
  • 打赏
  • 举报
回复
加减法就算有溢出,在主流编译器编译也没问题,结果是正确的 乘法的话,溢出就基本出错了
palm008 2013-05-24
  • 打赏
  • 举报
回复
以上代码vs2008运行正确,我目前能想到的就这么多,还望高人补充
palm008 2013-05-24
  • 打赏
  • 举报
回复
void swap1(int &a,int &b)
{
    a=a+b;
    b=a-b;
    a=a-b;
    return ;
}
void swap2(int &a,int &b)
{
    a=a^b;
    b=a^b;
    a=a^b;
    return ;
}

void swap3(int &a,int &b)
{
    __asm
    {
        mov eax,dword ptr[a];
        mov ecx,dword ptr[eax];

        mov ebx,dword ptr[b];
        mov edx,dword ptr[ebx];

        mov dword ptr[eax],edx;
        mov dword ptr[ebx],ecx;
    }
}

void swap4(int &a,int &b)
{
    __asm
    {       
        mov eax,dword ptr[a];
        push eax;
        mov eax,dword ptr[eax];
        mov ebx,dword ptr[b];
        mov ecx,dword ptr[ebx];
        xchg eax,dword ptr[ebx];
        pop eax;
        xchg ecx,dword ptr[eax];     
    }
}
  • 打赏
  • 举报
回复
引用 18 楼 pengjialaosan 的回复:
[quote=引用 12 楼 pengjialaosan 的回复:] 加减在过程中有溢出风险,如果不考虑溢出的话,乘除应该也可以吧? i = i * j; j = i / j; i = i / j; 考虑到整除的问题,下面的方法就不行了: i = i / j; j = i * j; i = j / i; 但加减法除了楼主提出的: i=i+j; j=i-j; i=i-j; 这样也可以: i = i - j; j = i + j; i = j - i; 但是,无论加减法,乘除法还有异或法有多快,我在写程序的时候都会用临时变量。
晕,刚刚发现加减法还可以这样: i = j - i; j = j - i; i = i + j; 想想还是Python爽: i,j = j,i[/quote] Python,perl,ruby这类语言就不说了,对这类问题这类语言在行
彭家老三 2013-05-24
  • 打赏
  • 举报
回复
引用 12 楼 pengjialaosan 的回复:
加减在过程中有溢出风险,如果不考虑溢出的话,乘除应该也可以吧? i = i * j; j = i / j; i = i / j; 考虑到整除的问题,下面的方法就不行了: i = i / j; j = i * j; i = j / i; 但加减法除了楼主提出的: i=i+j; j=i-j; i=i-j; 这样也可以: i = i - j; j = i + j; i = j - i; 但是,无论加减法,乘除法还有异或法有多快,我在写程序的时候都会用临时变量。
晕,刚刚发现加减法还可以这样: i = j - i; j = j - i; i = i + j; 想想还是Python爽: i,j = j,i
Yale_Yange 2013-05-24
  • 打赏
  • 举报
回复
引用 16 楼 zjq9931 的回复:
来个加减法变种,主要用减法 这样似乎可以防止溢出。

#include<stdio.h>
int main()
{
	int i=6;
	int j=5;
	
	if(i>j)
	{
		i=i-j;
		j=i+j;
		i=j-i;
	}
	else
	{
		j=j-i;
		i=j+i;
		j=i-j;
	}

	printf("%d\t%d\r\n", i, j);
	return 0;
}
嗯,对,考虑得好全面
  • 打赏
  • 举报
回复
来个加减法变种,主要用减法 这样似乎可以防止溢出。

#include<stdio.h>
int main()
{
	int i=6;
	int j=5;
	
	if(i>j)
	{
		i=i-j;
		j=i+j;
		i=j-i;
	}
	else
	{
		j=j-i;
		i=j+i;
		j=i-j;
	}

	printf("%d\t%d\r\n", i, j);
	return 0;
}
lin5161678 2013-05-24
  • 打赏
  • 举报
回复
引用 13 楼 Grey110 的回复:
[quote=引用 11 楼 lin5161678 的回复:] [quote=引用 9 楼 Grey110 的回复:] 嗯,我也是,不过刚刚琢磨琢磨着,又琢磨出了一种办法,分享下: a=a*b; b=a/b; a=a/b; 嘿嘿,虽然和那个减法的差不太多
你忘记考虑 不能整除的情况了 余数也得算进去的[/quote] 不会啊,除非两个整数中有一个是0的情况除外,不然只要第一步是相乘,那么应该不会有不整除的情况出现吧[/quote]嗯 是啊 第一步 乘 我疏忽了 第一步除才会出现我说的问题
Yale_Yange 2013-05-24
  • 打赏
  • 举报
回复
引用 12 楼 pengjialaosan 的回复:
加减在过程中有溢出风险,如果不考虑溢出的话,乘除应该也可以吧? i = i * j; j = i / j; i = i / j; 考虑到整除的问题,下面的方法就不行了: i = i / j; j = i * j; i = j / i; 但加减法除了楼主提出的: i=i+j; j=i-j; i=i-j; 这样也可以: i = i - j; j = i + j; i = j - i; 但是,无论加减法,乘除法还有异或法有多快,我在写程序的时候都会用临时变量。
嗯,对,所以考虑整除的时候,第一步必须是进行乘法 另外,加减那个也得考虑溢出问题
Yale_Yange 2013-05-24
  • 打赏
  • 举报
回复
引用 11 楼 lin5161678 的回复:
[quote=引用 9 楼 Grey110 的回复:] 嗯,我也是,不过刚刚琢磨琢磨着,又琢磨出了一种办法,分享下: a=a*b; b=a/b; a=a/b; 嘿嘿,虽然和那个减法的差不太多
你忘记考虑 不能整除的情况了 余数也得算进去的[/quote] 不会啊,除非两个整数中有一个是0的情况除外,不然只要第一步是相乘,那么应该不会有不整除的情况出现吧
彭家老三 2013-05-24
  • 打赏
  • 举报
回复
加减在过程中有溢出风险,如果不考虑溢出的话,乘除应该也可以吧? i = i * j; j = i / j; i = i / j; 考虑到整除的问题,下面的方法就不行了: i = i / j; j = i * j; i = j / i; 但加减法除了楼主提出的: i=i+j; j=i-j; i=i-j; 这样也可以: i = i - j; j = i + j; i = j - i; 但是,无论加减法,乘除法还有异或法有多快,我在写程序的时候都会用临时变量。
lin5161678 2013-05-24
  • 打赏
  • 举报
回复
引用 9 楼 Grey110 的回复:
嗯,我也是,不过刚刚琢磨琢磨着,又琢磨出了一种办法,分享下: a=a*b; b=a/b; a=a/b; 嘿嘿,虽然和那个减法的差不太多
你忘记考虑 不能整除的情况了 余数也得算进去的
lin5161678 2013-05-24
  • 打赏
  • 举报
回复
引用 3 楼 turingo 的回复:
b=a^b^(a=b);
这个不可靠 C99明确说了是未定义行为
Yale_Yange 2013-05-24
  • 打赏
  • 举报
回复
引用 8 楼 CKnightx 的回复:
[quote=引用 3 楼 turingo 的回复:] __asm{ xchg val1,val2 } b=a^b^(a=b);
+1
引用 6 楼 Grey110 的回复:
[quote=引用 4 楼 CKnightx 的回复:] 没有说不能加中间变量。。也没有说要性能。 第三方参数,是第三方库吧?
不是,是第三方参数[/quote] 那没有办法了,我也只见过这两种方法。 内联 asm的方法,今天也是第一次见[/quote] 嗯,我也是,不过刚刚琢磨琢磨着,又琢磨出了一种办法,分享下: a=a*b; b=a/b; a=a/b; 嘿嘿,虽然和那个减法的差不太多
  • 打赏
  • 举报
回复
引用 3 楼 turingo 的回复:
__asm{ xchg val1,val2 } b=a^b^(a=b);
+1
引用 6 楼 Grey110 的回复:
[quote=引用 4 楼 CKnightx 的回复:] 没有说不能加中间变量。。也没有说要性能。 第三方参数,是第三方库吧?
不是,是第三方参数[/quote] 那没有办法了,我也只见过这两种方法。 内联 asm的方法,今天也是第一次见
加载更多回复(13)

64,680

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧