C에 왼쪽이 없을 때 & 오퍼레이터는 어떻게 해야 합니까?
C에서 다음과 같은 코드를 가진 프로그램을 보았습니다.
static void *arr[1] = {&& varOne,&& varTwo,&& varThree};
varOne: printf("One") ;
varTwo: printf("Two") ;
varThree: printf("Three") ;
뭐가 뭔지 헷갈려구요&&
왼쪽에는 아무것도 없기 때문입니다.디폴트로는 늘로 평가됩니까?아니면 이게 특별한 경우인가요?
편집: 질문/코드를 보다 명확하게 하기 위해 몇 가지 정보를 추가했습니다.도와주셔서 감사합니다.이것은 gcc 고유의 확장의 경우입니다.
이것은 "값으로서의 라벨"로 알려진 gcc 확장입니다.gcc 매뉴얼 링크
이 확장자에서는&&
는 라벨에 적용할 수 있는 단항 연산자입니다.결과는 type 값입니다.void *
이 값은 나중에 참조할 수 있습니다.goto
실행이 해당 라벨로 점프하도록 하는 스테이트먼트입니다.또한 이 값에는 포인터 산술이 허용됩니다.
라벨은 같은 함수에 있어야 합니다.또는 코드가 "내포함수"의 gcc 확장자를 사용하는 경우에는 동봉함수에 있어야 합니다.
이 기능을 사용하여 스테이트 머신을 구현하는 샘플프로그램을 다음에 나타냅니다.
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void)
{
void *tab[] = { &&foo, &&bar, &&qux };
// Alternative method
//ptrdiff_t otab[] = { &&foo - &&foo, &&bar - &&foo, &&qux - &&foo };
int i, state = 0;
srand(time(NULL));
for (i = 0; i < 10; ++i)
{
goto *tab[state];
//goto *(&&foo + otab[state]);
foo:
printf("Foo\n");
state = 2;
continue;
bar:
printf("Bar\n");
state = 0;
continue;
qux:
printf("Qux\n");
state = rand() % 3;
continue;
}
}
컴파일 및 실행:
$ gcc -o x x.c && ./x
Foo
Qux
Foo
Qux
Bar
Foo
Qux
Qux
Bar
Foo
GCC 고유의 확장자인데&&
라벨 이름에 적용할 수 있는 연산자로 주소를 지정합니다.void*
가치.
확장의 일환으로goto *ptr;
허가된 장소ptr
타입의 표현입니다.void*
.
여기 gcc 매뉴얼에 기재되어 있습니다.
단항 연산자를 사용하여 현재 함수(또는 포함 함수)에 정의된 라벨의 주소를 얻을 수 있습니다.
&&
. 값에 유형이 있습니다.void *
이 값은 상수이며 해당 유형의 상수가 유효한 경우 사용할 수 있습니다.예를 들어 다음과 같습니다.void *ptr; /* ... */ ptr = &&foo;
이러한 값을 사용하려면 1로 점프할 수 있어야 합니다.이것은 계산된 goto 문장으로 이루어집니다.
goto *exp;
.예를들면,goto *ptr;
임의의 유형의 표현
void *
허용됩니다.
zwol이 댓글에서 지적했듯이 gcc는&&
더 명백하기보다는&
왜냐하면 라벨과 같은 이름을 가진 오브젝트가 동시에 보일 수 있기 때문에&foo
만약이라면 애매할 가능성이 있다&
"라벨 주소"를 의미합니다.라벨명은 독자적인 네임스페이스(C++의 의미가 아님)를 점유하며 특정 컨텍스트에서만 표시할 수 있습니다.즉, 라벨이 붙은 스테이트먼트에 의해 정의되며,goto
스테이트먼트(또는 gcc의 경우 단항 피연산자로서)&&
.
C에서 이런 식으로 작동하는 운영자는 없습니다.문맥에 따라 C의 앰퍼샌드는 여러 가지 의미를 가질 수 있습니다.
주소 연산자
예를 들어, l값 바로 앞에 있습니다.
int j;
int* ptr = &j;
위의 코드에서는 ptr은 j의 주소를 저장하고 이 컨텍스트에서는 임의의 lvalue의 주소를 받습니다.아래 코드는 그렇게 작성되었으면 더 이해가 되었을 것입니다.
static int varOne;
static int varTwo;
static int varThree;
static void *arr[1][8432] = { { &varOne,&varTwo, &varThree } };
논리 AND
논리 AND 연산자는 위의 연산자와 달리 더 단순합니다. 이 연산자는 이진 연산자이며, 이는 왼쪽과 오른쪽 연산자가 필요하다는 것을 의미합니다.이 방법은 좌우 피연산자를 평가하여 true를 반환하고 둘 다 true이면 true를 반환하고 bool이 아닌 경우에는 0보다 큰 값을 반환하는 것입니다.
bool flag = true;
bool flag2 = false;
if (flag && flag2) {
// Not evaluated
}
flag2 = true;
if (flag && flag2) {
// Evaluated
}
비트 AND
C에서 앰퍼샌드를 사용하는 또 다른 방법은 비트 AND를 실행하는 것입니다.논리 AND 연산자와 유사하지만 1개의 앰퍼샌드만 사용하고 비트레벨에서 AND 연산을 수행합니다.
숫자가 있고 아래에 표시된 이진 표현에 매핑된다고 가정하면 AND 연산은 다음과 같이 작동합니다.
0 0 0 0 0 0 1 0
1 0 0 1 0 1 1 0
---------------
0 0 0 0 0 0 1 0
C++랜드에서는 일이 더 복잡해진다.앰퍼샌드는 참조 유형을 나타내듯이 유형 뒤에 배치할 수 있습니다(더 강력하지만 안전한 종류의 포인터라고 생각할 수 있음). 그런 다음 유형 뒤에 두 개의 앰퍼샌드를 배치하면 r-값 참조가 더 복잡해집니다.2) 템플릿 타입 또는 자동 차감 타입 뒤에 앰퍼샌드를 2개 배치했을 때의 범용 참조.
내 생각에 당신의 코드는 어떤 종류의 확장으로 인해 당신의 컴파일러에서만 컴파일 될 것 같습니다.저는 이 https://en.wikipedia.org/wiki/Digraphs_and_trigraphs#C을 생각하고 있었습니다만, 그런 것 같지는 않습니다.
언급URL : https://stackoverflow.com/questions/39357887/what-does-a-operator-do-when-there-is-no-left-side-in-c
'sourcecode' 카테고리의 다른 글
x<1과 x<10 중 어느 쪽이 빠릅니까? (0) | 2022.07.23 |
---|---|
C++ - unistd를 포함합니다.왜 cunistd 안 돼? (0) | 2022.07.23 |
Linux에서 비동기 신호 핸들러는 어떻게 실행됩니까? (0) | 2022.07.23 |
math.h 헤더를 포함했는데도 "undefined reference to sqrt" 오류가 발생하는 이유는 무엇입니까? (0) | 2022.07.23 |
복사된 데이터가 변경될 때 Vuex 상태를 변경하지 않고 Vuex 상태에서 Data로 값을 복사하려면 어떻게 해야 합니까? (0) | 2022.07.17 |