programing

if(expr) 대신 if(!(expr) 사용

yoursource 2022. 10. 22. 13:30
반응형

if(expr) 대신 if(!(expr) 사용

Texas Instruments에서 SensorTag에 대해 제공한 코드 예를 읽다가 다음과 같은 조각이 발견되었습니다.

void SensorTagIO_processCharChangeEvt(uint8_t paramID) { 
    ...

    if (!!(ioValue & IO_DATA_LED1)) {
        PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_ON);
    } else {
        PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_OFF);
    }

    if (!!(ioValue & IO_DATA_LED2)) {
        PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_ON);
    } else {
        PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_OFF);
    }

    if (!!((ioValue & IO_DATA_BUZZER))) {
        Clock_start(buzzClockHandle);
    }
    ...
}

선언문은 (같은 파일에) 이렇게 되어 있습니다.

#define IO_DATA_LED1   0x01
static uint8_t ioValue;

if (!!(ioValue & IO_DATA_LED1))에 서다if (ioValue & IO_DATA_LED1)무슨 일입니까?

비적용(적용하지 않음(적용)!는 두 번을 0 1로 하는 것을 으로 합니다 연산자의 목적은 값을 0 또는1로 정규화하는 것입니다. 표현은 가 없습니다.if-statement 제 in 、 in in in in in in in in 。.작은 if-statement는 0 입니다.!!춤은 전혀 쓸모가 없다.

일부 코딩 스타일 가이드는 이러한 종류의 춤을 의무화할 수 있으며, 이것이 당신이 게시한 TI 코드가 그렇게 하는 이유일 수 있습니다.하지만 나는 그렇게 하는 것을 본 적이 없다.

.!!x , 「」!(!x)은이면 1, 이면 1을 의미해요.x이 아닌 이 아닌 포인터)입니다 않으면 010이 됩니다.0으로 하다은 와와다다 it에 해당합니다.x != 0 C99와 (_Bool)x단, C99보다 이전 컴파일러 또는 개발자가 C99를 구현하지 않기로 선택한 컴파일러(MOS 6502를 대상으로 하는 cc65 등)에서는 사용할 수 있습니다.

조건 전체는 다음과 같습니다.

if (ioValue & IO_DATA_LED1) {
    /* what to do if the IO_DATA_LED1 bit is true */
} else {
    /* what to do if the IO_DATA_LED1 bit is false */
}

C에서는 "이 두 값의 비트 단위 AND가 0이 아니면 블록을 실행한다"는 의미입니다.

, 의 ANDAND)를 할 수 .&에 있습니다.ifAND의 )&&를 사용하는 것과 =(주석)이 아닌 (==많은 컴파일러가 진단 프로그램을 제공하고 있습니다.GCC 경고 옵션에서는 다음과 같은 진단에 대해 설명합니다.

-Wlogical-op: 에 대해 식에서 논리 연산자의 의심스러운 사용에 대해 경고합니다.여기에는 비트 단위 연산자가 예상되는 컨텍스트에서 논리 연산자를 사용하는 것도 포함됩니다.

-Wparentheses: 값이 등된 경우 true 이 、 : 、 true 、 : : 、 : : : : : 。

as as as as as as as as as as (a & B) != 0,(_Bool)(a & B) , 「」!!(a & B)컴파일러 및 다른 개발자에게 비트 연산자의 사용이 의도적이었다는 것을 알립니다.

JavaScript 관련 답변도 참조하십시오.

로 변환하는 boolif문을 지정하면 경고가 발생할 수 있습니다.를 통해 실행!!하지 않다.다른 컴파일러에서도 같은 경고가 발생할 수 있습니다.

따라서 해당 경고가 활성화되고 모든 경고를 오류로 처리하기로 결정한 상태에서 코드가 컴파일되었다고 가정하면!!"네, 이 정수를 1의 값으로 해 주세요.bool".

비트에 대한 컴파일러 경고를 소거합니다.&가장 가능성이 높으며, 이는 다음에서 읽기 쉽도록 에넘을 추가하는 리팩터링의 결과일 수도 있습니다.

PIN_setOutputValue(int,int,bool); //function definition
PIN_setOutputValue(hGpioPin, Board_LED1,!!(ioValue & IO_DATA_LED1));
PIN_setOutputValue(hGpioPin, Board_LED2,!!(ioValue & IO_DATA_LED2));
//note: the !! is necessary here in case sizeof ioValue > sizeof bool
//otherwise it may only catch the 1st 8 LED statuses as @M.M points out

대상:

enum led_enum {
  Board_LED_OFF = false,
  Board_LED_ON = true
};
PIN_setOutputValue(int,int,bool); //function definition
//...
PIN_setOutputValue(hGpioPin, Board_LED1,!!(ioValue & IO_DATA_LED1)?Board_LED_ON:Board_LED_OFF);
PIN_setOutputValue(hGpioPin, Board_LED2,!!(ioValue & IO_DATA_LED2)?Board_LED_ON:Board_LED_OFF);

그것이 80자 제한을 초과했기 때문에, 그 후, 그것은 다음과 같이 리팩터링 되었다.

if (!!(ioValue & IO_DATA_LED1)) {
    PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_ON);
} else {
    PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_OFF);
}

if (!!(ioValue & IO_DATA_LED2)) {
    PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_ON);
} else {
    PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_OFF);
}

개인적으로는 읽기 쉽도록 초기 버전을 선호합니다만, 이 버전은 코드 행이 메트릭으로 사용되는 경우 일반적입니다(각 상태에 대해 변수를 선언하지 않고 각 상태를 개별적으로 설정한 후 이를 사용하는 것이 놀랍습니다).

이 "베스트 프랙티스" 코드의 다음 버전은 다음과 같습니다.

bool boardled1State;
bool boardled2State;
//...

boardled1State = !!(ioValue & IO_DATA_LED1);
boardled2State = !!(ioValue & IO_DATA_LED2);
//...

if (boardled1State) {
    PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_ON);
} else {
    PIN_setOutputValue(hGpioPin, Board_LED1, Board_LED_OFF);
}

if (boardled2State) {
    PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_ON);
} else {
    PIN_setOutputValue(hGpioPin, Board_LED2, Board_LED_OFF);
}
//... and so on

이 모든 것은 다음과 같이 이루어질 수 있습니다.

for (int i=0;i<numleds;i++)
        PIN_setOutputValue(hGpioPin, i ,!!(ioValue & (1<<i)));

OP는 오래된 코딩 관용어를 찾고 있습니다.이것은 어느 정도 의미가 있는 BITD(Back-in-The-Day)입니다.

  1. 주요 용도!!표현식을 변환하는 C 구현을 처리하는 것입니다.if(expr)로로 합니다.int0의

의 경우에 어떤 이 일어나는지 해 봅시다.expr is is is is is로 됩니다.int0에 합니다.(0에 합니다.) 0에 대해 테스트합니다.(C89부터 0에 대해 직접 테스트해야 하므로 부적합)

int i;
long li;
double d;

// no problems
if (i & 5) ...
if (d > 4.0) ...

// problems
if (li & 0x10000) ...  (Hint: int is 16-bit)
if (d)                 (d might have a value outside `int` range.

// fix
if (!!(li & 0x10000))
if (!!d)

C89 준거자 및 에서는 C89 C89를 합니다.!!을 사용하다어떤 오래된 습관은 사라지기까지 오랜 시간이 걸린다.

  1. 초기 C++에서는,booltype을 했습니다. 그래서 신뢰성을 테스트하기 위해 필요한 코드는!!

    class uint256;  // Very wide integer
    uint256 x;
    
    // problem  as (int)x may return just the lower bits of x
    if (x) 
    
    // fix
    if (!!x) 
    
  2. C++가 하지 않을 때는 어떻게 C).(bool) defined, operator defined, operator defined, operator operator operator operator operator operator되(int)사하?????2번으로 나누다몇년 동안 C와 C의 코드 는 C++를 사용하여로 유지되었습니다.!!같은 구조와 관련이 있다if (!!x).


「」를 사용합니다.!!현재는 동작하고 있습니다만, 더 이상 발생하지 않는 문제를 큰 빈도로 해결할 수 있기 때문에, 확실히 인기가 없어지고 있습니다.

언급URL : https://stackoverflow.com/questions/35523023/using-if-expr-instead-of-if-expr

반응형