Namespaces
Variants

Assignment operators

From cppreference.net

대입 및 복합 대입 연산자는 오른쪽의 값을 사용하여 왼쪽의 변수를 수정하는 이항 연산자입니다.

연산자 연산자 이름 예시 설명 동등 표현
= 기본 할당 a = b a b 와 같아짐 해당 없음
+ = 덧셈 할당 a + = b a a b 의 합과 같아짐 a = a + b
- = 뺄셈 할당 a - = b a a 에서 b 를 뺀 값과 같아짐 a = a - b
* = 곱셈 할당 a * = b a a b 의 곱과 같아짐 a = a * b
/ = 나눗셈 할당 a / = b a a b 로 나눈 값과 같아짐 a = a / b
% = 모듈로 할당 a % = b a a b 로 나눈 나머지와 같아짐 a = a % b
& = 비트 AND 할당 a & = b a a b 의 비트 AND와 같아짐 a = a & b
| = 비트 OR 할당 a | = b a a b 의 비트 OR와 같아짐 a = a | b
^ = 비트 XOR 할당 a ^ = b a a b 의 비트 XOR와 같아짐 a = a ^ b
<<= 비트 왼쪽 시프트 할당 a <<= b a a b 만큼 왼쪽으로 시프트한 값과 같아짐 a = a << b
>>= 비트 오른쪽 시프트 할당 a >>= b a a b 만큼 오른쪽으로 시프트한 값과 같아짐 a = a >> b

목차

단순 할당

단순 대입 연산자 표현식의 형식은 다음과 같습니다.

lhs = rhs

여기서

lhs - 수정 가능한 lvalue 표현식 (모든 완전한 객체 타입)
rhs - 모든 타입의 표현식 암시적으로 변환 가능 하거나 lhs 호환되는 타입

대입은 암시적 변환 을 통해 rhs 의 값을 lhs 의 타입으로 변환한 후, lhs 로 지정된 객체의 값을 rhs 의 변환된 값으로 대체합니다.

대입은 또한 lhs 에 저장된 값과 동일한 값을 반환합니다 (따라서 a = b = c 와 같은 표현이 가능합니다). 대입 연산자의 값 범주 는 비-좌측값입니다 (따라서 ( a = b ) = c 와 같은 표현은 유효하지 않습니다).

rhs lhs 는 다음 중 하나를 충족해야 합니다:

  • lhs rhs 모두 산술 타입 을 가지는 경우, 이때 lhs volatile 한정자를 가질 수 있음 또는 atomic (C11부터)
  • lhs rhs 모두 포인터 타입이며 호환되는 (한정자는 무시) 타입을 가리키거나, 한쪽 포인터가 void 포인터이며 변환 이 가리키는 타입에 한정자를 추가하지 않는 경우. lhs volatile 또는 restrict (C99부터) 한정자를 가질 수 있음 또는 atomic (C11부터) .
  • lhs 가 (한정자가 있을 수 있는 또는 atomic (C11부터) ) 포인터이고 rhs NULL 과 같은 null 포인터 상수인 경우 또는 nullptr_t 값인 경우 (C23부터)
  • lhs 는 (한정자가 있을 수 있는 또는 atomic (C11부터) ) _Bool 타입을 가지며, rhs 는 포인터 또는 nullptr_t (C23부터)
(C99부터)
  • lhs 가 (한정되었거나 atomic일 수 있는) nullptr_t 타입을 가지고 있고 rhs nullptr_t 타입을 가지는 경우
(C23부터)

참고 사항

만약 rhs lhs 가 메모리에서 겹치는 경우(예: 동일한 union의 멤버인 경우), 겹침이 정확하고 타입이 호환 가능한 경우를 제외하고는 동작이 정의되지 않습니다.

배열은 할당 가능하지 않지만, 구조체로 감싸진 배열은 동일한(또는 호환되는) 구조체 타입의 다른 객체에 할당 가능합니다.

lhs 를 갱신하는 부수 효과는 sequenced after 값 계산 이후에 발생하지만, lhs rhs 자체의 부수 효과는 그렇지 않으며, 피연산자들의 평가는 상대적으로 비순서화되어 있습니다 (따라서 i = ++ i ;와 같은 표현식은 정의되지 않습니다)

대입은 부동 소수점 표현식에서 추가 범위와 정밀도를 제거합니다(참조 FLT_EVAL_METHOD ).

C++에서 할당 연산자는 좌측값 표현식이지만, C에서는 그렇지 않습니다.

#include <stdio.h>
int main(void)
{
    // 정수
    int i = 1, j = 2, k = 3; // 초기화, 대입이 아님
    i = j = k;   // i와 j의 값은 이제 3
//  (i = j) = k; // 오류: lvalue 필요
    printf("%d %d %d\n", i, j, k);
    // 포인터
    const char c = 'A'; // 초기화; 대입이 아님
    const char *p = &c;  // 초기화; 대입이 아님
    const char **cpp = &p; // 초기화; 대입이 아님
//  cpp = &p;   // 오류: char**는 const char**로 변환 불가
    *cpp = &c;  // OK, char*는 const char*로 변환 가능
    printf("%c \n", **cpp);
    cpp = 0;    // OK, 널 포인터 상수는 어떤 포인터로든 변환 가능
    // 배열
    int arr1[2] = {1,2}, arr2[2] = {3, 4};
//  arr1 = arr2; // 오류: 배열에 대입할 수 없음
    printf("arr1[0]=%d arr1[1]=%d arr2[0]=%d arr2[1]=%d\n",
            arr1[0],   arr1[1],   arr2[0],   arr2[1]);
    struct { int arr[2]; } sam1 = { {5, 6} }, sam2 = { {7, 8} };
    sam1 = sam2; // OK: 구조체로 감싼 배열은 대입 가능
    printf("%d %d \n", sam1.arr[0], sam1.arr[1]);
}

출력:

3 3 3
A
arr1[0]=1 arr1[1]=2 arr2[0]=3 arr2[1]=4
7 8

복합 할당

복합 할당 연산자 표현식의 형식은 다음과 같습니다

lhs op rhs

여기서

op - 다음 중 하나 * = , / = % = , + = - = , <<= , >>= , & = , ^ = , | =
lhs , rhs - 산술 타입 을 가지는 표현식들 (단, lhs 는 한정되거나 atomic일 수 있음). 단, op + = 또는 - = 인 경우, +와 - 연산자와 동일한 제한 조건으로 포인터 타입도 허용됨

표현식 lhs @= rhs lhs = lhs @ ( rhs ) 와 정확히 동일하며, 단지 lhs 가 한 번만 평가된다는 점만 다릅니다.

만약 lhs atomic 타입을 가지고 있다면, 이 연산은 memory_order_seq_cst 메모리 순서를 가진 단일 atomic 읽기-수정-쓰기 연산으로 동작합니다.

정수 atomic 타입의 경우, 복합 할당 @ = 는 다음과 동일합니다:

T1* addr = &lhs;
T2 val = rhs;
T1 old = *addr;
T1 new;
do { new = old @ val } while (!atomic_compare_exchange_strong(addr, &old, new);
(C11부터)
#include <stdio.h>
int main(void)
{
    int x = 10; 
    int hundred = 100; 
    int ten = 10; 
    int fifty = 50; 
    printf("%d %d %d %d\n", x, hundred, ten, fifty);
    hundred *= x; 
    ten     /= x; 
    fifty   %= x; 
    printf("%d %d %d %d\n", x, hundred, ten, fifty);
    return 0;
}

출력:

10 100 10 50
10 1000 1 0

참고문헌

  • C17 표준 (ISO/IEC 9899:2018):
  • 6.5.16 대입 연산자 (p: 72-73)
  • C11 표준 (ISO/IEC 9899:2011):
  • 6.5.16 대입 연산자 (p: 101-104)
  • C99 표준 (ISO/IEC 9899:1999):
  • 6.5.16 대입 연산자 (p: 91-93)
  • C89/C90 표준 (ISO/IEC 9899:1990):
  • 3.3.16 Assignment operators

참고 항목

연산자 우선순위

일반 연산자
대입 증가
감소
산술 논리 비교 멤버
접근
기타

a = b
a + = b
a - = b
a * = b
a / = b
a % = b
a & = b
a | = b
a ^ = b
a <<= b
a >>= b

++ a
-- a
a ++
a --

+ a
- a
a + b
a - b
a * b
a / b
a % b
~a
a & b
a | b
a ^ b
a << b
a >> b

! a
a && b
a || b

a == b
a ! = b
a < b
a > b
a <= b
a >= b

a [ b ]
* a
& a
a - > b
a. b

a ( ... )
a, b
( type ) a
a ? b : c
sizeof


_Alignof
(C11부터)
(C23 이전)

alignof
(C23부터)

참고 항목

C++ 문서 에 대한 대입 연산자