표현식

표현식 (Expressions)

표현식은 연산자와 그 피연산자들의 나열로, 하나의 계산을 나타내요. 2 + 2를 평가하면 결과 4가 나오고, printf("%d", 4)를 평가하면 문자 '4'가 표준 출력으로 나가는 부수 효과가 생기며, 객체나 함수를 가리키는 역할도 해요.

출처: cppreference

본문

일반 (General)

  • 값 범주(lvalue, 비-lvalue 객체, 함수 지정자)는 표현식을 그 값의 종류로 분류해요.
  • 인자와 부분 표현식의 평가 순서는 중간 결과가 얻어지는 순서를 규정해요.

연산자

공통 연산자
대입 증가·감소 산술 논리 비교 멤버 접근 기타
`a=ba+=ba-=ba*=ba/=ba%=ba&=ba =ba^=ba<<=ba>>=b` ++a--aa++a-- `+a-aa+ba-ba*ba/ba%b~aa&ba ba^ba<>b` `!aa&&ba

변환 (Conversions)

  • 피연산자의 타입이 연산자 기대와 맞지 않을 때 암시적 변환이 일어나요.
  • 캐스트로 값을 한 타입에서 다른 타입으로 명시적으로 바꿀 수 있어요.

그 외

  • 상수 표현식은 컴파일 시간에 평가될 수 있고, 컴파일 시간 문맥(C99부터는 비-VLA 배열 크기, 정적 초기화자 등)에서 쓰여요.
  • (C11부터) 제네릭 선택은 인자의 타입에 따라 서로 다른 표현식을 실행할 수 있어요.
  • (C99부터) 부동소수점 산술은 math_errhandling에 규정된 대로 예외를 발생시키고 오류를 보고할 수 있어요.
  • (C99부터) 표준 #pragma FENV_ACCESS, FP_CONTRACT, CX_LIMITED_RANGE부동소수점 평가 정밀도, 반올림 방향이 부동소수점 산술이 실행되는 방식을 제어해요.

기본 표현식 (Primary expressions)

어떤 연산자의 피연산자는 다른 표현식일 수도 있고, 기본 표현식일 수도 있어요. 예를 들어 1 + 2 * 3에서 + 연산자의 피연산자는 부분 표현식 2 * 3과 기본 표현식 1이에요.

기본 표현식은 다음 중 하나예요.

  1. 상수와 리터럴 (예: 2, "Hello, world")
  2. 적절히 선언된 식별자 (예: n, printf)
  3. (C11부터) 제네릭 선택

괄호로 감싼 어떤 표현식도 기본 표현식으로 분류돼요. 이 덕분에 괄호가 어떤 연산자보다 우선순위가 높다는 게 보장돼요.

상수와 리터럴

C 프로그램의 소스 코드에 특정 타입의 상수 값을 박아 넣을 때 쓰는 전문 표현식이 있는데, lvalue 표현식용은 리터럴, 비-lvalue 표현식용은 상수라고 불러요.

  • 정수 상수는 정수 타입의 십진수·팔진수·십육진수 숫자예요.
  • 문자 상수는 타입 int의 개별 문자로, 문자 타입으로 변환하기에 적합해요. (C11부터는 char16_t, char32_t, 또는 wchar_t, C23부터는 char8_t 타입도 있어요.)
  • 부동 상수float, double, 또는 long double 타입의 값이에요.
  • (C23부터) 미리 정의된 상수 true/falsebool 타입의 값이에요.
  • (C23부터) 미리 정의된 상수 nullptrnullptr_t 타입의 값이에요.
  • 문자열 리터럴은 널 종료 문자열을 나타내는 char[](C11부터 char16_t[], char32_t[], C23부터 char8_t[], 그리고 wchar_t[]) 타입의 문자 시퀀스예요.
  • (C99부터) 복합 리터럴은 프로그램 코드에 직접 박아 넣은 struct·union·배열 타입의 값이에요.

평가되지 않은 표현식

sizeof 연산자의 피연산자는 평가되지 않는 표현식이에요(C99부터 VLA인 경우는 제외). 그래서 size_t n = sizeof(printf("%d", 4));는 콘솔 출력을 수행하지 않아요.

(C11부터) _Alignof(C23까지) / alignof(C23부터) 연산자의 피연산자, 제네릭 선택의 제어 표현식, 그리고 _Alignof(C23까지) / alignof(C23부터)의 피연산자인 VLA의 크기 표현식도 평가되지 않는 표현식이에요.

더 알아보기

  • 값 범주 문서와 평가 순서 문서를 함께 보면 표현식의 골격이 잡혀요.
  • 연산자 우선순위와 대체 표기도 이어서 확인하면 좋아요.
  • cppreference의 표현식 원문에서 C++ 표현식과 비교해 볼 수 있어요.