Other operators
다른 주요 카테고리에 속하지 않는 연산자들의 모음입니다.
|
이 섹션은 불완전합니다
이유: 이 표와 여러 주제를 다루는 다른 표들을 위해 더 일반적인 목차를 고려해 주세요 |
| 연산자 | 연산자 이름 | 예시 | 설명 |
|---|---|---|---|
| ( ... ) | 함수 호출 | f ( ... ) | 함수 f ()를 0개 이상의 인수로 호출 |
| , | 쉼표 연산자 | a, b | 표현식 a 를 평가하고 반환값을 무시한 후 모든 부수 효과를 완료한 다음, 표현식 b 를 평가하여 이 평가의 타입과 결과를 반환 |
| ( type ) | 타입 변환 | ( type ) a | a 의 타입을 type 으로 변환 |
| ? : | 조건 연산자 | a ? b : c | a 가 논리적으로 참(0으로 평가되지 않음)이면 표현식 b 를 평가하고, 그렇지 않으면 표현식 c 를 평가 |
| sizeof | sizeof 연산자 | sizeof a | a 의 바이트 단위 크기 |
|
_Alignof
(C11부터) |
_Alignof 연산자 | _Alignof ( type ) | type 에 필요한 정렬 요구사항 |
| typeof | typeof 연산자 | typeof ( a ) | a 의 타입 |
목차 |
함수 호출
함수 호출 표현식의 형식은 다음과 같습니다
표현식
(
인수-목록
(선택사항)
)
|
|||||||||
여기서
| expression | - | 함수 포인터 타입의 임의의 표현식( lvalue conversions 이후) |
| argument-list | - | 모든 완전한 객체 타입의 표현식들로 구성된 쉼표로 구분된 목록(쉼표 연산자는 사용할 수 없음). 인수를 받지 않는 함수를 호출할 때는 생략할 수 있습니다. |
함수 호출 표현식의 동작은 호출되는 함수의 프로토타입이 호출 지점에서 범위 내 에 있는지 여부에 따라 달라집니다.
프로토타입이 있는 함수 호출
|
또한,
배열 타입
의 모든 매개변수에 대해
static
키워드가
[
과
]
사이에 사용되는 경우, 인수 표현식은 매개변수의 크기 표현식에 지정된 요소 수 이상을 가진 배열의 요소를 가리키는 포인터를 지정해야 합니다.
|
(C99부터) |
-
- 만약 trailing ellipsis 매개변수가 있는 경우, Default argument promotions 이 나머지 인수들에 대해 수행되며, 이들은 va_list 에서 사용 가능하게 됩니다.
void f(char* p, int x) {} int main(void) { f("abc", 3.14); // array to pointer and float to int conversions }
프로토타입 없는 함수 호출
1)
인수들은
지정되지 않은 순서로 시퀀싱 없이 평가됨
.
2)
기본 인수 승격
이 모든 인수 표현식에 수행됨.
3)
대입
이 각 인수의 값을 해당 함수 매개변수에 복사하기 위해 수행되며, 매개변수 타입과 그 재귀적 요소 또는 멤버(있는 경우)의 모든 타입 한정자는 무시됨.
4)
함수가 실행되고, 반환된 값이 함수 호출 표현식의 값이 됨 (함수가 void를 반환하면 함수 호출 표현식은 void 표현식임)
void f(); // no prototype int main(void) { f(1, 1.0f); // UB unless f is defined to take an int and a double } void f(int a, double c) {} 프로토타입 없는 함수 호출의 동작은 다음 경우에 정의되지 않음:
|
(C23까지) |
참고 사항
함수 호출 대상 함수를 지정하는 expression 및 모든 인자들의 평가는 서로 간에 unsequenced 입니다 (그러나 함수 본문 실행 시작 전에 sequence point가 존재합니다)
(*pf[f1()]) (f2(), f3() + f4()); // f1, f2, f3, f4는 임의의 순서로 호출될 수 있음
함수 호출은 함수 포인터에 대해서만 정의되어 있지만, 함수-포인터 암시적 변환 으로 인해 함수 지정자와도 동작합니다.
int f(void) { return 1; } int (*pf)(void) = f; int main(void) { f(); // f를 포인터로 변환한 후 호출 (&f)(); // 함수 포인터를 생성한 후 호출 pf(); // 함수 호출 (*pf)(); // 함수 지정자를 얻어 포인터로 변환한 후 호출 (****f)(); // 포인터로 변환, 함수 획득을 4회 반복한 후 호출 (****pf)(); // 또한 유효함 }
사용되지 않는 인수를 무시하는 함수들, 예를 들어 printf 와 같은 함수들은 정의되지 않은 동작을 유발하지 않기 위해 반드시 프로토타입이 있는 범위 내에서 호출되어야 합니다(이러한 함수들의 프로토타입은 반드시 후행 생략 부호 매개변수를 사용합니다).
함수 매개변수의 의미론을 현재 표준으로 기술한 방식은 결함이 있습니다. 매개변수가 호출 시 인수로부터 할당된다고 명시하고 있기 때문인데, 이는 const 한정 매개변수나 멤버 타입을 부정확하게 거부하며, 많은 플랫폼에서 함수 매개변수에 대해 구현 불가능한 volatile의 의미론을 부적절하게 적용합니다. C11 이후의 결함 보고서 DR427 에서는 이러한 의미론을 할당에서 초기화로 변경하는 것을 제안했으나, 결함이 아니라는 이유로 종결되었습니다.
|
expression 이 완전히 식별자로만 구성되고 해당 식별자가 선언되지 않은 함수 호출 표현식은 다음과 같이 식별자가 선언된 것처럼 동작합니다. extern int identifier(); // returns int and has no prototype 따라서 다음 완전한 프로그램은 유효한 C89입니다: main() { int n = atoi("123"); // implicitly declares atoi as int atoi() } |
(C99까지) |
콤마 연산자
쉼표 연산자 표현식의 형식은 다음과 같습니다
lhs
,
rhs
|
|||||||||
여기서
| lhs | - | 임의의 표현식 |
| rhs | - | 다른 콤마 연산자를 제외한 임의의 표현식 (다시 말해, 콤마 연산자의 결합 방향 은 좌측에서 우측으로) |
먼저, 왼쪽 피연산자인 lhs 가 평가되고 그 결과 값은 버려집니다.
그런 다음, 시퀀스 포인트 가 발생하여 lhs 의 모든 부수 효과가 완료됩니다.
그런 다음, 오른쪽 피연산자인 rhs 가 평가되고 그 결과가 콤마 연산자에 의해 비-좌측값 으로 반환됩니다.
참고 사항
lhs 의 타입은 void 일 수 있습니다(즉, void 를 반환하는 함수 호출이거나, cast 표현식이 void 로 변환된 경우일 수 있습니다)
콤마 연산자는 C++에서는 lvalue일 수 있지만, C에서는 절대 그렇지 않습니다
쉼표 연산자는 구조체를 반환할 수 있습니다 (구조체를 반환하는 다른 표현식으로는 복합 리터럴, 함수 호출, 대입 연산, 조건 연산자가 있습니다)
다음 상황에서는 쉼표가 다른 의미를 가지기 때문에 쉼표 연산자가 표현식의 최상위 수준에 나타날 수 없습니다:
- 함수 호출의 인수 목록
- 초기화 표현식 또는 initializer list
- generic selection
콤마 연산자를 이러한 맥락에서 사용해야 하는 경우, 반드시 괄호로 묶어야 합니다:
// int n = 2,3; // 오류: 쉼표가 다음 선언자의 시작으로 간주됨 // int a[2] = {1,2,3}; // 오류: 요소 수보다 초기화자가 더 많음 int n = (2,3), a[2] = {(1,2),3}; // 정상 f(a, (t=3, t+2), c); // 정상, 먼저 t에 3을 저장한 다음 세 개의 인수로 f를 호출함
최상위 쉼표 연산자는 배열 경계에서도 허용되지 않습니다
// int a[2,3]; // 오류 int a[(2,3)]; // OK, 크기 3의 VLA 배열 (VLA인 이유: (2,3)이 상수 표현식이 아니기 때문)
콤마 연산자는 최상위 수준인지 여부와 관계없이 상수 표현식 에서 허용되지 않습니다
// static int n = (1,2); // 오류: 상수 표현식에서 쉼표 연산자를 호출할 수 없음
캐스트 연산자
조건 연산자
조건부 연산자 표현식의 형식은 다음과 같습니다
조건
?
참-표현식
:
거짓-표현식
|
|||||||||
여기서
| condition | - | 스칼라 타입의 표현식 |
| expression-true | - | condition이 0과 비교하여 같지 않을 경우 평가될 표현식 |
| expression-false | - | condition이 0과 비교하여 같을 경우 평가될 표현식 |
다음 표현식들만 expression-true 와 expression-false 로 허용됩니다
- 임의의 산술 타입 을 가진 두 표현식
- 동일한 구조체 또는 공용체 타입을 가진 두 표현식
- void 타입의 두 표현식
- cvr-qualifier를 무시했을 때 호환 가능한 타입을 가리키는 포인터 타입의 두 표현식
|
(C23부터) |
- 한 식은 포인터이고 다른 식은 널 포인터 상수(예: NULL ) 또는 nullptr_t 값 (C23 이후)
- 한 식은 객체에 대한 포인터이고 다른 식은 void에 대한 포인터(한정자 있을 수 있음)인 경우
| (C23부터) |
#define ICE(x) (sizeof(*(1 ? ((void*)((x) * 0l)) : (int*)1))) // x가 정수 상수 표현식이면 매크로는 다음으로 확장됩니다 sizeof(*(1 ? NULL : (int *) 1)) // (void *)((x)*0l)) -> NULL // 포인트 (4)에 따라 이것은 더 나아가 다음으로 변환됩니다 sizeof(int) // x가 정수 상수 표현식이 아니면 매크로는 다음으로 확장됩니다 // 포인트 (6)에 따라 (sizeof(*(void *)(x)) // 불완전한 타입으로 인한 오류
참고 사항
조건 연산자는 절대 lvalue 표현식 이 아니지만, 구조체/공용체 타입의 객체를 반환할 수 있습니다. 구조체를 반환할 수 있는 다른 표현식으로는 대입 , 콤마 , 함수 호출 , 그리고 복합 리터럴 이 있습니다.
C++에서는 lvalue 표현식일 수 있습니다.
자세한 내용은 이 연산자와 대입 연산자의 상대적 우선순위에 대해 연산자 우선순위 를 참조하십시오.
조건부 연산자는 오른쪽에서 왼쪽으로의 결합성을 가지며, 이를 통해 연쇄 사용이 가능합니다
#include <assert.h> enum vehicle { bus, airplane, train, car, horse, feet }; enum vehicle choose(char arg) { return arg == 'B' ? bus : arg == 'A' ? airplane : arg == 'T' ? train : arg == 'C' ? car : arg == 'H' ? horse : feet ; } int main(void) { assert(choose('H') == horse && choose('F') == feet); }
sizeof
연산자
참조 sizeof 연산자
_Alignof
연산자
참조 _Alignof 연산자
typeof
연산자
참조 typeof 연산자
참고문헌
- C23 표준 (ISO/IEC 9899:2024):
-
- 6.5.2.2 함수 호출 (p: TBD)
-
- 6.5.3.4 sizeof 및 _Alignof 연산자 (p: TBD)
-
- 6.5.4 캐스트 연산자 (p: TBD)
-
- 6.5.15 조건 연산자 (p: TBD)
-
- 6.5.17 쉼표 연산자 (p: TBD)
-
- 6.7.3.5 Typeof 지정자 (p: 115-118)
- C17 표준 (ISO/IEC 9899:2018):
-
- 6.5.2.2 함수 호출 (p: 58-59)
-
- 6.5.3.4 sizeof 및 _Alignof 연산자 (p: 64-65)
-
- 6.5.4 캐스트 연산자 (p: 65-66)
-
- 6.5.15 조건 연산자 (p: 71-72)
-
- 6.5.17 쉼표 연산자 (p: 75)
- C11 표준 (ISO/IEC 9899:2011):
-
- 6.5.2.2 함수 호출 (p: 81-82)
-
- 6.5.3.4 sizeof 및 _Alignof 연산자 (p: 90-91)
-
- 6.5.4 캐스트 연산자 (p: 91)
-
- 6.5.15 조건 연산자 (p: 100)
-
- 6.5.17 쉼표 연산자 (p: 105)
- C99 표준 (ISO/IEC 9899:1999):
-
- 6.5.2.2 함수 호출 (p: 71-72)
-
- 6.5.3.4 sizeof 연산자 (p: 80-81)
-
- 6.5.4 캐스트 연산자 (p: 81)
-
- 6.5.15 조건 연산자 (p: 90-91)
-
- 6.5.17 콤마 연산자 (p: 94)
- C89/C90 표준 (ISO/IEC 9899:1990):
-
- 3.3.2.2 함수 호출
-
- 3.3.3.4 sizeof 연산자
-
- 3.3.4 캐스트 연산자
-
- 3.3.15 조건 연산자
-
- 3.3.17 쉼표 연산자
참고 항목
| 일반 연산자 | ||||||
|---|---|---|---|---|---|---|
| 대입 |
증가
감소 |
산술 | 논리 | 비교 |
멤버
접근 |
기타 |
|
a
=
b
|
++
a
|
+
a
|
!
a
|
a
==
b
|
a
[
b
]
|
a
(
...
)
|
|
C++ 문서
for
Other operators
|