Programing

C99에서 가장 유용한 새 기능은 무엇입니까?

crosscheck 2020. 10. 13. 07:26
반응형

C99에서 가장 유용한 새 기능은 무엇입니까?


C99 는 10 년 이상 사용되었지만 지원이 느리게 진행되어 대부분의 개발자가 C89를 고수했습니다. 지금도 C 코드에서 C99 기능을 발견하면 가끔 약간 놀랐습니다.

이제 대부분의 주요 컴파일러가 C99를 지원하므로 (MSVC는 주목할만한 예외이며 일부 임베디드 컴파일러도 뒤처짐) C로 작업하는 개발자는 C99 기능을 사용할 수 있는지 알아야합니다. 일부 기능은 이전에 표준화 된 적이없는 일반적인 기능 ( snprintf예 :)이거나 C ++ (유연한 변수 선언 배치 또는 한 줄 //주석) 에서 익숙 하지만 일부 새로운 기능은 C99에서 처음 도입되었으며 많은 프로그래머에게 익숙하지 않습니다.

C99에서 가장 유용한 새 기능은 무엇입니까?

참고로 C99 표준 (초안으로 표시되지만 내가 아는 한 업데이트 된 표준과 동일 함), 새로운 기능 목록GCC C99 구현 상태가 있습니다.

답변 당 하나의 기능을 사용하십시오. 여러 답변을 남겨주세요. 새로운 기능을 보여주는 짧은 코드 예제가 권장됩니다.


나는 타이핑에 너무 익숙해

for (int i = 0; i < n; ++i) { ... }

C ++에서는 C99가 아닌 컴파일러를 사용하는 것이 고통 스럽습니다.

int i;
for (i = 0; i < n; ++i ) { ... }

stdint.h정의되는 int8_t, uint8_t등 없음은 더 정수가 얼마나 폭에 대한 비 휴대용 가정을 할 필요.

uint32_t truth = 0xDECAFBAD;

새로운 초기화 메커니즘이 매우 중요하다고 생각합니다.

struct { int x, y; } a[10] = { [3] = { .y = 12, .x = 1 } };

OK-설득력있는 예는 아니지만 표기법은 정확합니다. 배열의 특정 요소와 구조의 특정 멤버를 초기화 할 수 있습니다.

아마도 더 나은 예는 이것이 될 것입니다-비록 그다지 매력적이지 않다는 것을 인정합니다.

enum { Iron = 26, Aluminium = 13, Beryllium = 4, ... };

const char *element_names[] =
{
    [Iron]      = "Iron",
    [Aluminium] = "Aluminium",
    [Beryllium] = "Beryllium",
    ...
};

가변 길이 배열 :

int x;
scanf("%d", &x);
int a[x];
for (int i = 0; i < x; ++i)
    a[i] = i * i;
for (int i = 0; i < x; ++i)
    printf("%d\n", a[i]);

로 시작하는 한 줄 주석 지원 //.


블록의 시작이 아닌 다른 위치에서 변수를 선언 할 수 있습니다.


가변 매크로. 인수의 무제한으로 상용구 코드를 더 쉽게 생성 할 수 있습니다.


snprintf() -진지하게, 안전한 형식의 문자열을 할 수 있다는 것은 많은 가치가 있습니다.


복합 리터럴. 멤버 별 구조 설정은 '89;)

불필요한 변수를 선언하지 않고 자동 저장 기간이있는 개체에 대한 포인터를 가져 오는 데 사용할 수도 있습니다.

foo(&(int){ 4 });

의욕

int tmp = 4;
foo(&tmp);

유연한 어레이 멤버.

6.7.2.1 구조 및 공용체 지정자

특별한 경우로 이름이 지정된 멤버가 둘 이상있는 구조의 마지막 요소에 불완전한 배열 유형이있을 수 있습니다. 이를 유연한 배열 구성원 이라고합니다 . 두 가지 예외를 제외하고 유연한 배열 구성원은 무시됩니다. 우선, 구조체의 크기는 unspeci 인터넷 ED 길이의 어레이로 배열 FL 융통성이 부재를 대체 달리 동일한 구조의 마지막 요소의 오프셋) 둘째, 동일하게한다 .(또는->) 연산자에는 유연한 배열 멤버가있는 구조 (에 대한 포인터) 인 왼쪽 피연산자가 있고 해당 멤버의 오른쪽 피연산자 이름을 지정하면 해당 멤버가없는 가장 긴 배열 (동일한 요소 유형)로 대체 된 것처럼 작동합니다. 접근중인 객체보다 구조를 더 크게 만듭니다. 배열의 오프셋은 교체 배열의 오프셋과 다르더라도 유연한 배열 구성원의 오프셋을 유지해야합니다. 이 배열에 요소가 없으면 하나의 요소가있는 것처럼 동작하지만 해당 요소에 액세스하거나 그 요소를 지나서 포인터를 생성하려는 시도가 있으면 동작이 정의되지 않습니다.

예:

typedef struct {
  int len;
  char buf[];
} buffer;

int bufsize = 100;
buffer *b = malloc(sizeof(buffer) + sizeof(int[bufsize]));

부울 유형입니다.

이제 다음과 같이 할 수 있습니다.

bool v = 5;

printf("v=%u\n", v);

인쇄됩니다

1

inline기능 지원 .


이미 언급 한 복합 리터럴이지만 여기에 내 매력적인 예가 있습니다.

struct A *a = malloc(sizeof(*a));
*a = (struct A){0};  /* full zero-initialization   */
/* or */
*a = (struct A){.bufsiz=1024, .fd=2};   /* rest are zero-initialized.  */

It's a clear way to initialize data even if it's on the heap. There is no way to forget to zero-initialize something.


The restrict keyword. Especially when you crunch numbers...


Unicode escape sequence support:

printf("It's all \u03B5\u03BB\u03BB\u03B7\u03BD\u03B9\u03BA\u03AC to me.\n");

Or even, literal Unicode characters:

printf("日本語\n");

(note: may not work depending on your locale; portable support for different encodings will take more work than this)


Hexadecimal floating point constants (0x1.8p0f) and conversion specifiers (%a, %A). If you deal with low-level numerical details frequently, these are an enormous improvement over decimal literals and conversions.

They save you from worries about rounding when specifying constants for an algorithm, and are immensely useful for debugging low-level floating-point code.


Personally, I like the acknowledgment of IEC 60559:1989 (Binary floating-point arithmetic for microprocessor systems) and much better floating-point support.

In a similar vein, setting and querying the floating-point rounding mode, checking for Nan/Infinity/subnormal numbers, etc., is great to have.

참고URL : https://stackoverflow.com/questions/2047065/what-are-the-most-useful-new-features-in-c99

반응형