임시 변 수 를 사용 하지 않 고 두 수의 값 을 교환 합 니 다.
두 수의 값 을 교환 하려 면 일반적인 방법 은 임시 변 수 를 정의 한 다음 에 교환 하 는 것 이다.그렇다면 임시 변 수 를 사용 하지 않 고 두 수의 값 을 교환 할 수 있 습 니까?할 수 있어!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
오늘 또 다른 두 가지 방법 을 발견 하여 특별히 보충 하 였 다.
방법 1
void swap(int *p, int *q)
{
*p = *p + *q;
*q = *p - *q;
*p = *p - *q;
}
방법 2
void 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
테스트 결과 가 정확 하여 예 정 된 목표 에 도달 하 다.
다섯 개의 변수의 순차 적 교환 을 알 게 되면 여러 변수의 순차 적 교환 을 차례대로 유도 할 수 있 습 니 다. 여기 서 저 는 더 이상 쓰 지 않 겠 습 니 다.
물론 본 고 에서 소개 한 방법 을 제외 하고 임시 변 수 를 사용 하지 않 고 여러 변 수 를 교환 하 는 수 치 를 실현 할 수 있 고 독자 가 스스로 탐색 할 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Docker를 사용한 React 및 .NET Core 6.0 샘플 프로젝트 - 1부이 기사에서는 Entity Framework Core Code First 접근 방식을 사용하는 ASP.NET Core 6.0 WEP API의 CRUD(만들기, 읽기, 업데이트 및 삭제) 작업에 대해 설명합니다. 웹 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.