임시 변 수 를 사용 하지 않 고 두 수의 값 을 교환 합 니 다.

임시 변 수 를 사용 하지 않 고 두 수의 값 을 교환 합 니 다.
 
 
두 수의 값 을 교환 하려 면 일반적인 방법 은 임시 변 수 를 정의 한 다음 에 교환 하 는 것 이다.그렇다면 임시 변 수 를 사용 하지 않 고 두 수의 값 을 교환 할 수 있 습 니까?할 수 있어!C 언어 가 제공 하 는 이 또는 연산 은 이러한 조작 을 실현 할 수 있다.
 
이 또는 연산 자 ^ XOR 연산 자 라 고도 부 릅 니 다. 연산 에 참가 하 는 두 개의 이 진 이 같은 번호 라면 결 과 는 0 (가짜) 입 니 다.이 호 는 1 (진) 이다.즉 0 ^ 0 = 0, 0 ^ 1 = 1, 1 ^ 0 = 1, 1 ^ 1 = 0.
 
예:#include <stdio.h>

int main(int argc, char *argv[])
{
    int a = 2, b = 6;

    a = a ^ b;
    b = b ^ a;
    a = a ^ b;

    printf("a = %d b = %d/n", a, b);

    return 0;
}

결 과 는 다음 과 같다.
a = 6 b = 2
분석:
앞의 두 개의 할당 문 구 는 "a = a ^ b;" 와 "b = b ^ a;" 는 b = b ^ (a ^ b) 에 해당 하고 b ^ a ^ b 는 a ^ b ^ b 와 같다.b ^ b 의 결 과 는 0 입 니 다. 같은 수 와 상 향 상 ^ 이기 때문에 결 과 는 반드시 0 입 니 다.따라서 b 의 값 은 a ^ 0, 즉 a 와 같 고 그 값 은 2 이다.
세 번 째 할당 문 구 를 다시 실행 합 니 다: "a = a ^ b".a 의 값 은 (a ^ b), b 의 값 은 (b ^ a ^ b) 과 같 기 때문에 a = a ^ b ^ b ^ b, 즉 a 의 값 은 a ^ a ^ b ^ b, b 와 같다.
2007.06.02
 
오늘 또 다른 두 가지 방법 을 발견 하여 특별히 보충 하 였 다.
 
방법 1void swap(int *p, int *q)
{
    *p = *p + *q;
    *q = *p - *q;
    *p = *p - *q;
}

방법 2void swap(int *p, int *q)
{
    *p = *p + *q - (*q = *p);
}

원 리 는 산술 연산 자의 결합 순서 가 왼쪽 에서 오른쪽으로 이다.
2007.06.18
 
다른 세 문장 을 하나 로 압축 할 수 있 습 니 다.
  a ^= b ^= a ^= b;
세 변수의 값 을 교환 하려 면 다음 문장 을 사용 할 수 있 습 니 다.c = a + c - (a = b, b = c);
2007.09.11
위의 빨간색 부분의 오 류 를 지적 해 주 셔 서 감사합니다.#include <stdio.h>

int main(int argc, char *argv[])
{
    int a = 1;
    int b = 2;
    int c = 3;

    c = a + c - (a = b, b = c);

    printf("a = %d/n", a);
    printf("b = %d/n", b);
    printf("c = %d/n", c);

    return 0;
}

컴 파일 실행 결 과 는 다음 과 같 습 니 다.
a = 2 b = 3 c = 2
이 를 통 해 알 수 있 듯 이 최초의 목표 중의 c = 1 부분 은 실현 되 지 못 했다.그래서 원인 분석:
더 C 프로 그래 밍 언어 · 세 컨 드 에 디 션 P205 는 연산 자 플러스 와 마이너스 의 결합 순 서 를 왼쪽 에서 오른쪽으로 부가 하 는 'The additive operators + and - group left - to - right' 라 고 소개 했다.P209 는 "A pair of expressions separated by a coma is evaluated left - to - right, and the value of the left expression is discarded. The type and value of the result are the type and value of the right operand" 라 고 소개 했다. 즉, 쉼표 표현 식 의 계산 순 서 는 왼쪽 에서 오른쪽으로, 쉼표 왼쪽 표현 식 의 값 이 버 려 지고,표현 식 결과 의 유형 과 수 치 는 쉼표 오른쪽 표현 식 의 유형 과 수치 입 니 다.
그렇다면 결 과 는 옳 을 텐 데 왜 실 수 를 하 겠 는가?VC 6.0 에서 컴 파일 된 어 셈 블 리 코드 를 다시 보 겠 습 니 다.7: int a = 1;
00401028 mov dword ptr [ebp-4],1
8: int b = 2;
0040102F mov dword ptr [ebp-8],2
9: int c = 3;
00401036 mov dword ptr [ebp-0Ch],3
10:
11: c = a + c - (a = b, b = c);
0040103D mov eax,dword ptr [ebp-8]
00401040 mov dword ptr [ebp-4],eax
00401043 mov ecx,dword ptr [ebp-4]
00401046 add ecx,dword ptr [ebp-0Ch]
00401049 mov edx,dword ptr [ebp-0Ch]
0040104C mov dword ptr [ebp-8],edx
0040104F sub ecx,dword ptr [ebp-8]
00401052 mov dword ptr [ebp-0Ch],ecx

11 번 째 줄 코드 의 실행 과정 은 다음 과 같 습 니 다.
먼저 b 의 값 을 a 에 게 부여 한 다음 에 a 와 c 의 값 을 더 한 다음 에 레지스터 ecx 에 넣 은 다음 에 c 의 값 을 b 에 부여 한 다음 에 ecx 와 b 의 값 을 감소 시 켜 결 과 를 c 에 부여 합 니 다.C 문장 으로 분해 하기:a = b; /* a = 2, b = 2 */
ecx = a + c; /* ecx = 5, a = 2, c = 3 */
b = c; /* b = 3, c = 3 */
c = ecx - b; /* c = 2, ecx = 5, b = 3 */

원래 프로그램 이 실 행 될 때 쉼표 왼쪽 표현 식 의 값 을 계산 해서 버 린 다음 에 다른 연산 을 하면 최초의 오류 도 여기에 틀 렸 다 는 것 을 잘 알 수 있 습 니 다.
자, 위의 식 에 문제 가 있 는 이상 한 문장 으로 세 변수의 값 을 교환 할 수 있 는 다른 정확 한 방법 이 있 습 니까?
 
임시 변 수 를 사용 하지 않 고 N 개의 변 수 를 순서대로 교환 합 니 다.
 
 
N (N > = 2) 개의 변수 가 있 습 니 다. 임시 변 수 를 사용 하지 않 고 어떻게 순서대로 값 을 교환 합 니까?한 문장 으로 만 실현 할 수 있 습 니까?... 와 같다
 
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
| 1 | 2 | 3 | 4 | 5 |
+---+---+---+---+---+
 
그것 을
 
+---+---+---+---+---+
| a | b | c | d | e |
+---+---+---+---+---+
| 2 | 3 | 4 | 5 | 1 |
+---+---+---+---+---+
 
어떻게 실현 합 니까?
 
우선, 우 리 는 다른 변수 나 두 변수의 교환 을 실현 하 는 것 을 고려 하여 나의 이 글 을 참고 할 수 있다.
임시 변 수 를 사용 하지 않 고 두 수의 값 을 교환 합 니 다.C + + 로 함 수 를 쓰 면 다음 과 같 습 니 다.
  int &swap(int &a, int &b)
{
    b = b ^ a;
    a = a ^ b;
    b = b ^ a;

    return b;
}

그리고 코드 를 다음 과 같이 최적화 할 수 있 습 니 다.int &swap(int &a, int &b)
{
    b ^= a;
    a ^= b;
    b ^= a;

    return b;
}

계속 최적화 하고 세 문장 을 한 문장 으로 압축 하면 다음 과 같다.int &swap(int &a, int &b)
{
    b ^= a ^= b ^= a;
    
    return b;
}

다시 최적화 할 수 있 습 니 다. 다음 과 같 습 니 다.int &swap(int &a, int &b)
{
    return (b ^= a ^= b ^= a);
}

현재 5 개의 변수의 값 을 순서대로 교환 합 니 다. 다음 과 같 습 니 다.swap(a, b);        // b

swap(b, c);        // c

swap(c, d);        // d

swap(d, e);        

반환 값 이 있 으 면 체인 으로 쓸 수 있 습 니 다. 다음 과 같 습 니 다.swap(a, b);                                 // b

swap(swap(a, b), c);                        // c

swap(swap(swap(a, b), c), d);               // d

swap(swap(swap(swap(a, b), c), d), e);        

이제 swap 함 수 를 순서대로 해당 함수 체 로 교체 합 니 다. 다음 과 같 습 니 다.e ^= d ^= e ^= swap(swap(swap(a, b), c), d);

e ^= d ^= e ^= d ^= c ^= d ^= swap(swap(a, b), c);

e ^= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= swap(a, b);

e ^= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= b ^= a ^= b ^= a;

자, 마지막 문 구 는 다섯 개의 변 수 를 순서대로 교환 하 는 값 을 실현 합 니 다. 쓰기 프로그램 검증 은 다음 과 같 습 니 다./******************************************************************
* Copyright (c) 2005-2007 CUG-CS
* All rights reserved
*
* :xor.c
* :
*
* :1.0
* :raincatss
* :2007-10-18
* :Windows XP Sp2 + VC6.0
* :http://raincatss.cublog.cn/
******************************************************************/


#include <stdio.h>

#define PRINT(A) do {/
    printf("%d/n", A);/
    } while (0)

int main()
{
    int a = 1;
    int b = 2;
    int c = 3;
    int d = 4;
    int e = 5;

//    b ^= a ^= b ^= a;        // swap(a, b)

//    c ^= b ^= c ^= b;        // swap(b, c)

//    d ^= c ^= d ^= c;        // swap(c, d)

//    e ^= d ^= e ^= d;        // swap(d, e)


    e ^= d ^= e ^= d ^= c ^= d ^= c ^= b ^= c ^= b ^= a ^= b ^= a;

    PRINT(a);
    PRINT(b);
    PRINT(c);
    PRINT(d);
    PRINT(e);

    return 0;
}

실행 결 과 는 다음 과 같 습 니 다.
2 3 4 5 1
테스트 결과 가 정확 하여 예 정 된 목표 에 도달 하 다.
다섯 개의 변수의 순차 적 교환 을 알 게 되면 여러 변수의 순차 적 교환 을 차례대로 유도 할 수 있 습 니 다. 여기 서 저 는 더 이상 쓰 지 않 겠 습 니 다.
물론 본 고 에서 소개 한 방법 을 제외 하고 임시 변 수 를 사용 하지 않 고 여러 변 수 를 교환 하 는 수 치 를 실현 할 수 있 고 독자 가 스스로 탐색 할 수 있다.
 

좋은 웹페이지 즐겨찾기