모든 C 컴파일러 구현에는 표준이 있으므로 숨겨진 기능이 없어야합니다. 그럼에도 불구하고, 나는 모든 C 개발자들이 항상 사용하는 숨겨진 / 비법을 가지고 있다고 확신합니다.
답변
함수 포인터. 함수 포인터 테이블을 사용하여 빠른 간접 스레드 코드 인터프리터 (FORTH) 또는 바이트 코드 디스패처를 구현하거나 OO와 유사한 가상 메소드를 시뮬레이션 할 수 있습니다.
그런 다음 qsort (), bsearch (), strpbrk (), strcspn ()과 같은 표준 라이브러리에 숨겨진 gem이 있습니다.
C의 잘못된 기능은 부호있는 산술 오버플로가 정의되지 않은 동작 (UB)이라는 것입니다. 따라서 부호있는 정수 인 x + y와 같은 표현식이 나타날 때마다 오버플로가 발생하여 UB가 발생할 수 있습니다.
답변
GCC 컴파일러의 더 많은 트릭이지만 컴파일러에 분기 표시 힌트를 제공 할 수 있습니다 (Linux 커널에서 일반적 임)
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)
참조 : http://kerneltrap.org/node/4705
내가 이것에 대해 좋아하는 것은 또한 일부 기능에 표현력을 추가한다는 것입니다.
void foo(int arg)
{
if (unlikely(arg == 0)) {
do_this();
return;
}
do_that();
...
}
답변
int8_t
int16_t
int32_t
uint8_t
uint16_t
uint32_t
이들은 표준에서 선택적인 항목이지만 사람들이 끊임없이 재정의하고 있기 때문에 숨겨진 기능이어야합니다. 내가 작업 한 코드베이스 (현재는 여전히)에는 여러 식별자가있는 여러 재정의가 있습니다. 대부분의 경우 전 처리기 매크로를 사용합니다.
#define INT16 short
#define INT32 long
등등. 머리카락을 뽑고 싶어요. 괴물 표준 정수 타입 정의를 사용하십시오!
답변
쉼표 연산자는 널리 사용되지 않습니다. 확실히 남용 될 수 있지만 매우 유용 할 수도 있습니다. 이 사용이 가장 일반적입니다.
for (int i=0; i<10; i++, doSomethingElse())
{
/* whatever */
}
그러나이 연산자는 어디에서나 사용할 수 있습니다. 관찰 :
int j = (printf("Assigning variable j\n"), getValueFromSomewhere());
각 명령문은 평가되지만 표현식의 값은 마지막으로 평가 된 명령문의 값입니다.
답변
구조를 0으로 초기화
struct mystruct a = {0};
이것은 모든 구조 요소를 0으로 만듭니다.
답변
다중 문자 상수 :
int x = 'ABCD';
이 세트 x
에 0x41424344
(또는 0x44434241
, 아키텍처에 따라 다름).
편집 : 이 기술은 특히 int를 직렬화하는 경우 이식성이 없습니다. 그러나 자체 문서화 열거 형을 만드는 것이 매우 유용 할 수 있습니다. 예 :
enum state {
stopped = 'STOP',
running = 'RUN!',
waiting = 'WAIT',
};
따라서 원시 메모리 덤프를보고 열거 형 값을 조회하지 않고도 값을 결정해야하는 경우 훨씬 간단 해집니다.
답변
나는 비트 필드를 사용한 적이 없지만 초저 레벨의 물건에는 멋지게 들립니다.
struct cat {
unsigned int legs:3; // 3 bits for legs (0-4 fit in 3 bits)
unsigned int lives:4; // 4 bits for lives (0-9 fit in 4 bits)
// ...
};
cat make_cat()
{
cat kitty;
kitty.legs = 4;
kitty.lives = 9;
return kitty;
}
즉 sizeof(cat)
, 이만큼 작을 수 있습니다 sizeof(char)
.