... má jen minimum datových typů ...
Pokud se týče základních datových typů, tak bych naopak řekl, že jako snad jediný jazyk (kromě assembleru) poskytuje kompletní množinu různě dlouhých integerů se znaménkem nebo bez (a floaty a pointery). Sice se integer typy divně jmenují (char, short, long, long long) takže si je lidi někdy pro lepší přehlednost přejmenovávají na něco jako u16, nebo s32... ale těch pár jiných jazyků, které, jsem potkal, mě většinou tlačilo nějak do kouta stylem "tumáš nějaký integer a neotravuj s detailismem". Na to navazují bit-banging operace AND, OR, XOR, NOT.
Žádné rozmazlování garbage collectorem - máte lokální proměnné na stacku a globální tuším na heapu, a na případnou dynamickou alokaci z heapu máte v případě zájmu explicitní malloc() a free().
Jazyk je to závorkovatý, takže se nemusíte bát, že se Vám program rozbije změnou odsazení řádku.
Zároveň není tak ukecaný jako někteří jeho vrstevnící, kteří uzavírají blok mezi slůvka BEGIN a END :-)
Ten jazyk má přímý přístup k systémovým standardním knihovnám a syscallům. Vyšší jazyky toto C-level API musí nějak "balit" pro své potřeby, mohou být pozadu / nabízet jenom podmnožinu, nabalit další vrstvu abstrakce která může věci zjednodušovat a ve složitějších případech překáží apod.
Jsou situace / zadání, kde je zcela legitimní a vhodné, použít něco jiného než právě C :-)
Je to osobní volba. Mě v hadích letech vždycky zajímalo, jak věci fungují "pod kapotou", a když jsem po setkání s Basicem a Pascalem potkal vlastním přičiněním nakonec i Céčko, byla to pro mě veliká úleva. Že nemusím prosté věci řešit divnými oklikami, zároveň ale nemusím zabředat do detailů instrukční sady procesoru.