Pertanyaan Apa fitur baru yang paling berguna di C99? [Tutup]


C99 telah ada selama lebih dari 10 tahun, tetapi dukungan untuk itu telah lambat datang, sehingga sebagian besar pengembang terjebak dengan C89. Bahkan hari ini, saya terkadang agak terkejut ketika saya menemukan fitur C99 dalam kode C.

Sekarang sebagian besar compiler utama mendukung C99 (MSVC menjadi pengecualian penting, dan beberapa kompiler tertanam juga tertinggal), saya merasa bahwa pengembang yang bekerja dengan C mungkin harus tahu tentang fitur C99 apa yang tersedia untuk mereka. Beberapa fitur hanya fitur umum yang tidak pernah distandarisasi sebelumnya (snprintf, misalnya), atau familiar dari C ++ (penempatan deklarasi variabel fleksibel, atau single-line // komentar), tetapi beberapa fitur baru pertama kali diperkenalkan di C99 dan tidak dikenal oleh banyak programmer.

Apa yang Anda temukan fitur baru yang paling berguna di C99?

Sebagai referensi, standar C99 (diberi label sebagai konsep, tetapi identik dengan standar yang diperbarui, sejauh yang saya tahu), daftar fitur baru, dan Status penerapan GCC C99.

Satu fitur per jawaban, silakan; jangan ragu untuk meninggalkan banyak jawaban. Contoh kode singkat menunjukkan fitur baru didorong.


74


asal


Jawaban:


Saya sangat terbiasa mengetik

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

di C + + bahwa sangat sulit untuk menggunakan compiler non-C99 di mana saya dipaksa untuk mengatakan

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

72



stdint.h, yang mendefinisikan int8_t, uint8_t, dll. Tidak perlu lagi membuat asumsi non-portabel tentang seberapa lebar bilangan bulat Anda.

uint32_t truth = 0xDECAFBAD;

66



Saya pikir bahwa mekanisme penginisialisasi yang baru sangat penting.

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

OK - bukan contoh yang menarik, tetapi notasinya akurat. Anda dapat menginisialisasi elemen tertentu dari suatu array, dan anggota tertentu dari suatu struktur.

Mungkin contoh yang lebih baik adalah ini - meskipun saya akui itu tidak sangat menarik:

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

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

63



Dukungan untuk komentar satu baris yang dimulai dengan //.


50



Array panjang variabel:

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]);

48



Mampu mendeklarasikan variabel di lokasi selain awal blok.


40



Makro variatif. Membuat lebih mudah untuk menghasilkan kode boilerplate dengan jumlah argumen tidak terbatas.


34



snprintf() - Serius, sangat berharga untuk dapat melakukan string berformat aman.


31



Anggota array yang fleksibel.

6.7.2.1 Struktur dan spesifikasi penyatuan

Sebagai kasus khusus, elemen terakhir dari struktur dengan lebih dari satu anggota yang disebutkan dapat   memiliki jenis larik yang tidak lengkap; ini disebut a Anggota array yang fleksibel. Dengan dua pengecualian, anggota array yang fleksibel diabaikan. Pertama, ukuran strukturnya   sama dengan offset elemen terakhir dari struktur yang identik yang menggantikan anggota larik fleksibel dengan larik panjang yang tidak spesifik) Kedua, ketika . (atau ->) operator memiliki operan kiri yang (penunjuk ke) struktur dengan anggota larik fleksibel dan nama operan kanan anggota itu, berperilaku seolah-olah anggota yang diganti dengan larik terpanjang (dengan jenis elemen yang sama) yang tidak akan membuat struktur lebih besar dari objek yang sedang diakses; offset dari array akan tetap dari anggota array yang fleksibel, bahkan jika ini akan berbeda dari array pengganti. Jika array ini tidak memiliki elemen, ia berperilaku seolah-olah ia memiliki satu elemen tetapi perilaku tersebut tidak ditentukan jika ada usaha yang dilakukan untuk mengakses elemen tersebut atau untuk menghasilkan penunjuk satu masa lalu.   saya t.

Contoh:

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

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

28