C (programlama dili)

AT&T Bell laboratuvarlarında, Ken Thompson ve Dennis Ritchie tarafından UNIX İşletim Sistemi'ni geliştirebilmek amacıyla B dilinden türetilmiş yapısal bir programlama dilidir. Geliştirilme tarihi 1972 olmasına rağmen yaygınlaşması Brian Kernighan ve Dennis M. Ritchie tarafından yayımlanan "C Programlama Dili" kitabından sonra hızlanmıştır. Günümüzde neredeyse tüm işletim sistemlerinin (Microsoft Windows, GNU/Linux, BSD, Minix) yapımında %95'lere varan oranda kullanılmış, hâlen daha sistem, sürücü yazılımı, işletim sistemi modülleri ve hız gereken her yerde kullanılan oldukça yaygın ve sınırları belirsiz oldukça keskin bir dildir. Keskinliği, programcıya sonsuz özgürlüğün yanında çok büyük hatalar yapabilme olanağı sağlamasıdır. Programlamanın gelişim süreciyle beraber programlamanın karmaşıklaşması, gereksinimlerin artması ile uygulama programlarında nesne yönelimliliğin ortaya çıkmasından sonra C programcıları büyük ölçüde nesne yönelimliliği destekleyen C++ diline geçmişlerdir.

C'nin ilk gelişme safhaları 1969 ile 1974 arasında AT&T Bell Laboratuvarları'nda gerçekleşti. Ritchie'ye göre, en yaratıcı devre 1972 idi. Dilin pek çok özelliği "B" adlı bir dilden türediği için, yeni dile "C" adı verildi. B dili yorumlanan bir dildi ve veri tipi desteği yoktu. Yeni donanımların farklı veri tiplerini desteklemesi ve yorumlanan dillerin çalışma zamanında görece yavaş olması sebebi ile C dili tip desteği eklenmiş ve derlenen B olarak geliştirildi.

"B" adının kökeni konusunda ise söylentiler değişik: Ken Thompson B'nin BCPL programlama dilinden türediğini söylemektedir ancak Thompson eşi Bonnie'nin onuruna adını Bon koyduğu bir programlama dili de geliştirmiştir.

1973'e kadar C yeterince güçlü bir hale gelmiş ve ilk başta PDP-11/20 assembly dili ile yazılan UNIX'in çekirdeğinin büyük kısmı C ile yeniden yazılmıştır. Böylece UNIX, çekirdeği bir assembly dili ile yazılmayan ilk işletim sistemlerinden biri olmuştur.

1978'de Ritchie ve Brian Kernighan The C Programming Language (C Programlama Dili) kitabının ilk baskısını yayımladılar. C programcıları tarafından "K&R" olarak bilinen bu kitap yıllar boyunca C dilinin gayriresmî standardı olarak kullanıldı. C'nin bu sürümü bugün "K&R C" olarak adlandırılır. Bu kitabın ikinci baskısı ise aşağıda anlatılan ANSI C standardını içerir.

K&R C genellikle tüm C derleyicilerinin desteklemek zorunda olduğu dilin en temel kısmı olarak kabul edilir. Uzun yıllar boyunca, ANSI C'nin kabul edilişinden sonra bile, yüksek taşınabilirlik ( portability) istendiğinde, K&R C, C programcıları tarafından "ortak payda" olarak kabul edilmiştir. Çünkü bazı derleyiciler henüz ANSI C'yi desteklemek üzere güncellenmemişlerdi ve zaten iyi yazılmış bir K&R C programı aynı zamanda ANSI C'yi de destekliyordu.

1970'lerin sonunda C, en çok kullanılan mikrobilgisayar dili olarak BASIC'in önüne geçmeye başladı. 1980'lerde ise, IBM PC ile kullanılmak üzere benimsenmesiyle birlikte popülaritesi iyice artmaya başladı. Aynı zamanda, Bell Laboratuvarları'nda Bjarne Stroustrup ve iş arkadaşları C'ye nesneye yönelim eklemek üzere çalışmaya başlamışlardı. C bugün UNIX dünyasında en çok kullanılan dil olarak kalırken, Stroustrup'un geliştirip C++ adını verdiği dil Microsoft Windows işletim sisteminde en önemli dil oldu.

1983'te Amerikan Ulusal Standartlar Enstitüsü (ANSI) bir C standardı oluşturmak için bir kurul oluşturdu. Uzun ve yorucu bir çalışmadan sonra, bu kurul standardı 1989'da tamamladı ve standart ANSI X3.159-1989 "Programming Language C (C Programlama Dili)" olarak yayımlandı. Dilin bu versiyonu genellikle ANSI C olarak adlandırılır. 1990'da bu standart, küçük değişikliklerle Uluslararası Standartlar Örgütü (ISO) tarafından da benimsenip ISO/IEC 9899:1990 olarak yayımlandı.

ANSI C'yi oluşturmanın amaçlarıdan biri K&R C'yi içeren ve dile sonradan katılan "gayriresmî" özellikleri de dile katan bir standart oluşturmaktı. Kurul fonksiyon prototiplerini ve daha yetenekli bir önişlemciyi de standarda ekledi.

Bugün artık ANSI C neredeyse tüm derleyiciler tarafından desteklenmektedir. Günümüzde yazılmakta olan C programlarının çoğunluğu ANSI C standardına uygun olarak yazılmaktadır. Yalnızca standart C kullanılarak yazılmış bir program, standarda uyumlu her derleyici ile doğru bir biçimde derlenip çalıştırılabilir. Ancak standart olmayan kütüphaneler kullanılarak yazılmış programlar belli bir platform ya da derleyici gerektirebilirler.

ANSI standartlaştırma işleminden sonra C dili uzun bir süre oldukça sabit kaldı ancak C++ gelişmeyi sürdürdü. Buna bağlı olarak, 1990'ların sonunda ISO standardı güncellendi ve 1999'da ISO 9899:1999 olarak yayımlandı. 2000 yılının Mart'ında ise, "C99" olarak bilinen bu standart ANSI tarafından da benimsendi.

Merhaba, dünya örneği ilk olarak The C Programming Language kitabının birinci baskısında kullanıldı ve birçok programlama kitabında kullanılan tanıtıcı örnek haline geldi. Bu örnek terminal ekranına "merhaba, dünya" yazar.

1. satır : Bir önişlemci komutudur ve daha program derlenmeden önce devreye girerek istenilen değişiklikleri kaynak dosya üzerinde gerçekleştirir. Bu programda stdio.h (standart input-output) başlık dosyasını programa dahil eder. Bu başlık dosyasında standart giriş-çıkış fonksiyonlarının prototipleri mevcuttur. Burada programdaki komutun amacı printf fonskiyonunu programa dahil etmektir.

2. satır : Bu satırda programda işe main fonksiyonun tanımlanmasıyla başlanmıştır. main fonksiyonun C dilinde özel bir amacı vardır. Programın çalışma zamanında başladığı yer main fonksiyonudur.

4. satır : Bu satırda "merhaba, dünya" yazısını (karakter dizisini) ekrana bastırmak için printf fonksiyonu çağrılır ki bu fonksiyonu 1. satırdaki stdio.h başlık dosyası ile programa dahil etmiştik.

Statik bellek tahsisi: nesne için alan, derleme zamanında ikili dosyada sağlanır; bu nesnelerin, onları içeren ikili belleğe yüklendiği sürece bir kapsamı(extent) (veya ömrü "lifetime") vardır.

Otomatik bellek tahsisi: geçici nesneler yığında(stack) saklanabilir ve bu alan otomatik olarak serbest bırakılır ve bildirildikleri bloktan çıkıldıktan sonra yeniden kullanılabilir.

Dinamik bellek ayırma: çalışma zamanında, yığın adı verilen bir bellek bölgesinden mallocgibi kitaplık işlevleri kullanılarak isteğe bağlı boyutta bellek blokları istenebilir; bu bloklar, kütüphane işlevi realloc veya free çağrılarak yeniden kullanım için serbest bırakılıncaya kadar devam eder.

Bu üç yaklaşım, farklı durumlarda uygundur ve çeşitli ödünleşimlere sahiptir. Örneğin, statik bellek tahsisi (allocation), çok az tahsis ek yüküne sahiptir. Otomatik tahsis biraz daha fazla ek yük içerebilir, ve dinamik bellek ayırma (tahsisi), hem allocation hem de deallocation için potansiyel olarak büyük bir ek yüke sahip olabilir. Statik nesnelerin kalıcı doğası, işlev (fonksiyon) çağrıları arasında durum bilgilerini korumak için kullanışlıdır. Otomatik ayırmanın kullanımı kolaydır, ancak yığın alanı genellikle statik bellek veya yığın alanından çok daha sınırlı ve geçicidir, ve dinamik bellek tahsisi, boyutu yalnızca çalışma zamanında bilinen nesnelerin uygun şekilde tahsis edilmesini sağlar. Çoğu C programı, üçünü de kapsamlı bir şekilde kullanır.

Aksi belirtilmedikçe, statik nesneler program başlangıcında sıfır veya boş gösterici değerleri içerir. Otomatik ve dinamik olarak tahsis edilen nesneler, yalnızca bir başlangıç değeri açıkça belirtilmişse başlatılır; aksi halde başlangıçta belirsiz değerlere sahiptirler (tipik olarak, depolamada hangi bit deseni bulunursa bulunsun, bu tür için geçerli bir değeri bile temsil etmeyebilir). Program başlatılmamış bir değere erişmeye çalışırsa, sonuçlar tanımsızdır. Birçok modern derleyici bu sorunu tespit etmeye ve uyarmaya çalışır, ancak hem yanlış pozitifler hem de yanlış negatifler oluşabilir.

Yığın bellek tahsisi, mümkün olduğunca yeniden kullanılmak üzere herhangi bir programdaki gerçek kullanımıyla senkronize edilmelidir. Örneğin, bir yığın bellek tahsisine yönelik tek işaretçi kapsam dışına çıkarsa veya açıkça tahsis edilmeden önce değerinin üzerine yazılırsa, bu bellek daha sonra yeniden kullanım için kurtarılamaz ve esasen program tarafından kaybedilir, bu bir bellek sızıntısı olarak bilinen bir olgudur. Tersine, belleğin serbest bırakılması mümkündür, ancak daha sonra başvurulmakta ve bu da öngörülemeyen sonuçlara yol açmaktadır. Tipik olarak, hata belirtileri programın hataya neden olan kodla ilgisi olmayan bir bölümünde belirir ve bu da hatanın teşhis edilmesini zorlaştırır. Bu tür sorunlar, otomatik çöp toplama ile dillerde iyileştirilir.

C programlama dili, birincil uzantı yöntemi (primary method of extension) olarak kütüphaneleri kullanır. C'de bir kitaplık, tek bir "arşiv" dosyasında bulunan bir dizi işlevdir. Her kütüphane tipik olarak, bir program tarafından kullanılabilecek kütüphane içinde bulunan işlevlerin prototiplerini ve bu işlevlerle kullanılan özel veri türlerinin ve makro sembollerinin bildirimlerini içeren bir başlık dosyasına sahiptir. Bir programın kütüphaneyi kullanabilmesi için, kütüphanenin başlık dosyasını içermesi ve kütüphanenin, çoğu durumda derleyici bayrakları gerektiren programla bağlantılı olması gerekir (örneğin, -lm,"matematik kitaplığını bağla" için kısayol) .

En yaygın C kütüphanesi, ISO ve ANSI C standartları tarafından belirtilen ve her C uygulamasıyla birlikte gelen C standart kütüphanesidir (gömülü sistemler gibi sınırlı ortamları hedefleyen uygulamalar, standart kütüphanenin yalnızca bir alt kümesini sağlayabilir). Bu kütüphane, akış giriş ve çıkışını, bellek ayırmayı, matematiği, karakter dizilerini ve zaman değerlerini destekler. Birkaç ayrı standart başlık (örneğin, stdio.h), bu ve diğer standart kütüphane olanakları için arabirimleri belirtir.

Diğer bir yaygın C kütüphanesi işlevi kümesi, özellikle Unix ve Unix benzeri sistemler için hedeflenen uygulamalar tarafından kullanılanlardır, özellikle çekirdeğe bir arabirim sağlayan işlevlerdir. Bu işlevler, POSIX ve Single UNIX Spesifikasyonu gibi çeşitli standartlarda detaylandırılmıştır.

Birçok program C ile yazıldığından, çok çeşitli başka kütüphaneler de mevcuttur. kütüphaneler genellikle C ile yazılır çünkü C derleyicileri verimli nesne kodu üretir; programcılar daha sonra rutinlerin Java, Perl ve Python gibi daha yüksek seviyeli dillerden kullanılabilmesi için kütüphaneye arayüzler oluşturur.

Dosya girişi ve çıkışı(G/Ç), C dilinin bir parçası değildir, bunun yerine kitaplıklar (C standart kitaplığı gibi) ve bunlarla ilişkili başlık dosyaları (örneğin stdio.h) tarafından işlenir. Dosya işleme, genellikle akışlar aracılığıyla çalışan yüksek seviyeli girdi ve çıktılar aracılığıyla gerçekleştirilir. Bu açıdan bir stream, cihazlardan bağımsız bir veri akışı iken, bir dosya somut bir cihazdır. Üst düzey giriş ve çıkış, bir akışın bir dosyayla ilişkilendirilmesi yoluyla yapılır. C standart kitaplığında, son hedefe gönderilmeden önce verileri depolamak için geçici olarak bir arabellek (bir bellek alanı veya queue) kullanılır. Bu, örneğin sabit sürücü veya yarıiletken sürücü gibi daha yavaş aygıtları beklemek için harcanan süreyi azaltır. Düşük seviyeli giriş ve çıkış işlevleri, standart C kitaplığının bir parçası değildir, ancak genellikle "çıplak metal"(bare metal) programlamanın (çoğu gömülü programlama gibi herhangi bir işletim sisteminden bağımsız programlama) parçasıdır. Birkaç istisna dışında, uygulamalar düşük seviyeli girdi ve çıktı içerir.

C programcılarının tanımsız davranışa veya muhtemelen hatalı ifadelere sahip, derleyici tarafından sağlanandan daha büyük bir titizlikle ifadeleri bulmasına ve düzeltmesine yardımcı olmak için bir dizi araç geliştirilmiştir. Tool lint, diğerlerine yol açan ilk türdü.

Otomatik kaynak kodu checking ve auditing herhangi bir dilde faydalıdır ve C için Lint gibi bu tür birçok araç vardır. Yaygın bir uygulama, bir program ilk yazıldığında şüpheli kodu algılamak için Lint kullanmaktır. Bir program Lint'i geçtiğinde, C derleyicisi kullanılarak derlenir. Ayrıca, birçok derleyici isteğe bağlı olarak aslında hata olması muhtemel sözdizimsel olarak geçerli yapılar hakkında uyarabilir. MISRA C, gömülü sistemler için geliştirilmiş, bu tür şüpheli kodlardan kaçınmak için özel bir kurallar dizisidir.

Diziler için sınır denetimi, arabellek taşmasını algılama, serileştirme, dinamik bellek izleme ve otomatik çöp toplama gibi C'nin standart bir parçası olmayan eylemleri gerçekleştirmek için derleyiciler, kitaplıklar ve işletim sistemi düzeyinde mekanizmalar da vardır.

Purify veya Valgrind gibi araçlar ve bellek ayırma işlevlerinin özel sürümlerini içeren kitaplıklarla bağlantı kurma, bellek kullanımındaki çalışma zamanı hatalarını ortaya çıkarmaya yardımcı olabilir.

C dili deyimleri ve ifadeleri, tipik olarak, hedef işlemci için talimat dizileriyle iyi bir şekilde eşleşir ve sonuç olarak, sistem kaynaklarında düşük bir çalışma zamanı talebi vardır - yürütülmesi hızlıdır.

Zengin operatör seti ile C dili, hedef CPU'ların birçok özelliğini kullanabilir. Belirli bir CPU'nun daha ezoterik talimatlara sahip olduğu durumlarda, bu talimatlardan yararlanmak için belki de içsel işlevlerle bir dil varyantı oluşturulabilir - pratik olarak tüm hedef CPU özelliklerini kullanabilir.

Dil, yapıların ikili veri blokları üzerine bindirilmesini kolaylaştırarak verilerin anlaşılmasına, gezinmesine ve değiştirilmesine olanak tanır - veri yapıları, hatta dosya sistemleri yazabilir.

Dil, tamsayı aritmetiği ve mantığı ve belki de farklı boyutlardaki kayan nokta sayıları için bit işleme dahil olmak üzere zengin bir operatör grubunu destekler - uygun şekilde yapılandırılmış verileri etkili bir şekilde işleyebilir.

C oldukça küçük bir dildir, yalnızca bir avuç ifade içerir ve kapsamlı hedef kod oluşturan çok fazla özelliği yoktur - anlaşılırdır.

C, ara sıra dünyayı durduran çöp toplama olayları için herhangi bir endişe duymadan, bellek işleme operasyonlarına makul verimlilik ve öngörülebilir zamanlama sağlayan bellek allocation ve deallocation üzerinde doğrudan kontrole sahiptir - öngörülebilir bir performansa sahiptir.

Platform donanımına işaretçiler ve type punning ile erişilebilir, böylece sisteme özgü özellikler (örn. Kontrol/Durum Kayıtları, G/Ç kayıtları) (e.g. Control/Status Registers, I/O registers) C ile yazılmış kodla yapılandırılabilir ve kullanılabilir – üzerinde çalıştığı platformla iyi etkileşime girer.

Bağlayıcıya ve ortama bağlı olarak, C kodu, Assembly dilinde yazılmış kitaplıkları da çağırabilir ve Assembly dilinden çağrılabilir - diğer alt düzey kodlarla iyi bir şekilde birlikte çalışır.

C ve onun arama kuralları ve bağlayıcı yapıları, hem C'ye hem de C'den yapılan aramalarla birlikte diğer yüksek seviyeli dillerle birlikte yaygın olarak kullanılır - diğer yüksek seviyeli kodlarla iyi bir şekilde birlikte çalışır.

C, kütüphaneler, çerçeveler, açık kaynak derleyiciler, hata ayıklayıcılar ve yardımcı programlar dahil olmak üzere çok ergin ve geniş bir ekosisteme sahiptir ve fiili standarttır. Sürücülerin C'de zaten mevcut olması veya bir C derleyicisinin arka ucuna(back-end) benzer bir CPU mimarisi olması muhtemeldir, bu nedenle başka bir dil seçmek için azaltılmış teşvik vardır.

Tarihsel olarak, C bazen web uygulaması, sunucu ve tarayıcı arasında bilgi için bir "ağ geçidi" olarak Ortak Ağ Geçidi Arayüzü(Common Gateway Interface) (CGI) kullanılarak web geliştirme için kullanılmıştır. C, hızı, kararlılığı ve neredeyse evrensel kullanılabilirliği nedeniyle yorumlanan (interpreted) diller yerine seçilmiş olabilir. Web geliştirmenin C'de yapılması artık yaygın bir uygulama değildir ve diğer birçok web geliştirme aracı mevcuttur.

C'nin geniş kullanılabilirliğinin ve verimliliğinin bir sonucu, diğer programlama dillerinin derleyicileri, kitaplıkları ve yorumlayıcılarının genellikle C'de uygulanmasıdır. Örneğin Python,Perl, Ruby, ve PHP referans uygulamaları C ile yazılmıştır.

C, programcıların algoritmaların ve veri yapılarının verimli uygulamalarını oluşturmalarını sağlar, çünkü donanımdan soyutlama katmanı incedir ve ek yükü düşüktür, bu da hesaplama açısından yoğun programlar için önemli bir kriterdir. Örneğin, GNU Çoklu Hassas Aritmetik Kitaplığı, GNU Bilimsel Kitaplığı, Mathematica ve MATLAB tamamen veya kısmen C dilinde yazılmıştır. Birçok dil, C'de kitaplık işlevlerini çağırmayı destekler. Örneğin, Python tabanlı framework NumPy, yüksek performans ve donanım etkileşimi yönleri için C'yi kullanır.

C bazen diğer dillerin uygulamaları tarafından bir ara dil olarak kullanılır. Bu yaklaşım taşınabilirlik veya kolaylık için kullanılabilir; C'yi bir ara dil olarak kullanarak, makineye özel ek kod oluşturucular gerekli değildir. C, oluşturulan kodun derlenmesini destekleyen, satır numarası önişlemci yönergeleri ve başlatıcı listelerinin sonunda isteğe bağlı gereksiz virgüller gibi bazı özelliklere sahiptir. Bununla birlikte, C'nin bazı eksiklikleri, C-- gibi ara diller olarak kullanılmak üzere özel olarak tasarlanmış diğer C-tabanlı dillerin geliştirilmesine yol açmıştır. Ayrıca, çağdaş büyük derleyiciler GCC ve LLVM'nin her ikisi de C olmayan bir ara temsile sahiptir ve bu derleyiciler, C dahil birçok dil için ön uçları (front ends) destekler.

C ayrıca son kullanıcı uygulamalarını uygulamak için yaygın olarak kullanılmaktadır. Bununla birlikte, bu tür uygulamalar daha yeni, daha yüksek seviyeli dillerde de yazılabilir.

malloc ve free ile standart dinamik bellek işleme hataya açıktır. Hatalar şunları içerir: Bellek ayrıldığında ancak serbest bırakılmadığında bellek sızdırıyor; ve önceden boşaltılan belleğe erişim.

İşaretçilerin kullanımı ve belleğin doğrudan manipülasyonu, belki de programcı hatası veya yetersiz veri denetimi nedeniyle belleğin bozulmasının mümkün olduğu anlamına gelir.

Yüksek seviyeli programlama dillerinde yaygın olarak bulunan string değişken tipi C'de bulunmadığı için bunun yerine char ile belirli bir uzunlukta karakter dizisi array şeklinde hafızada tutulur. Mesela char a[]="Merhaba"; şeklinde bir karakter dizisi tanımlanabilir. Fakat daha sonra bu değişkene a[]="Nasılsın?"; şeklinde direkt olarak yeni bir değer atanamaz. Bunun yerine strcpy fonksiyonu kullanılabilir. Bu da diğer programlama dillerine nazaran C'nin zorluklarından biridir.

Derleyici tarafından üretilen kodun kendisi birkaç kontrol içerdiğinden, programcının tüm olası sonuçları göz önünde bulundurması ve arabellek taşmalarına, dizi sınırları denetimine, yığın taşmalarına, bellek tükenmesine, tür koşullarına, dizi yalıtımına vb. karşı koruma yükü vardır.

İşaretçilerin kullanımı ve bu araçların çalışma zamanı manipülasyonu, derleme zamanında belirlenemeyen aynı verilere (aliasing) erişmenin iki yolu olabilir. Bu, diğer dillerde mevcut olabilecek bazı optimizasyonların C'de mümkün olmadığı anlamına gelir. FORTRAN daha hızlı kabul edilir.

Oluşturulan kodda düşük seviyeli değişkenler için sınırlı standartlaştırma desteği vardır, örneğin: farklı işlev çağırma kuralları ve ABI; farklı yapı paketleme kuralları; daha büyük tamsayılar içinde farklı bayt sıralaması (endianness dahil). Pek çok dil uygulamasında, bu seçeneklerden bazıları önişlemci yönergesi#pragma aile, bazıları ise ek anahtar sözcüklerle ör. __cdeclçağrı kuralını kullanın. Ancak yönerge ve seçenekler tutarlı bir şekilde desteklenmemektedir.

Dil özelliklerinin uygunsuz kullanımına karşı sürdürülemez kodlara yol açabilecek birkaç koruma vardır. Zor kod için bu tesis, International Obfuscated C Code Contest ve Underhanded C Contest. gibi yarışmalarla kutlandı.

C, istisna işleme için standart destekten yoksundur ve yalnızca hata denetimi için dönüş kodları sunar. setjmp velongjmp standart kitaplık işlevleri 'te makrolar aracılığıyla bir try-catch mekanizmasını uygulamak için kullanılmıştır.

Bazı amaçlar için, kısıtlı C stilleri benimsenmiştir. Örneğin. MISRA C veya CERT C, hata olasılığını azaltmak amacıyla. CWE gibi veritabanları, C vb.'nin güvenlik açıklarına sahip olma yollarını ve azaltma önerilerini saymaya çalışır.

C, C++, C#, D, Go, Java, JavaScript, Perl, PHP, Rust ve Unix'in C kabuğu gibi sonraki birçok dili hem doğrudan hem de dolaylı olarak etkilemiştir. En yaygın etki sözdizimsel olmuştur; bahsedilen dillerin tümü, C'nin deyim (statement) ve (az ya da çok tanınabilir şekilde) ifade (expression) sözdizimini, C'den bazen kökten farklı olan tür sistemleri, veri modelleri ve/veya büyük ölçekli program yapıları ile birleştirir.

Nesne yönelimli programlama dilleri popüler hale geldiğinde, C++ ve Objective-C, C'nin nesne yönelimli yetenekler sağlayan iki farklı uzantısıydı. Her iki dil de başlangıçta kaynaktan kaynağa (source to source) derleyiciler olarak uygulandı; kaynak kodu C'ye çevrildi ve ardından bir C derleyicisi ile derlendi.

C++ programlama dili (başlangıçta "C with Classes" olarak adlandırıldı) Bjarne Stroustrup tarafından C benzeri bir sözdizimi ile nesne yönelimli işlevsellik sağlamaya yönelik bir yaklaşım olarak geliştirilmiştir. C++, daha fazla yazma gücü, kapsam belirleme (generic programming) ve nesne yönelimli programlamada yararlı olan diğer araçları ekler ve şablonlar aracılığıyla genel programlamaya izin verir. Neredeyse C'nin bir üst kümesi olan C++ şimdi, birkaç istisna dışında C'nin çoğunu destekliyor.

Objective-C, başlangıçta C'nin üzerinde çok "ince" bir katmandı ve hibrit bir dinamik/statik yazım paradigması kullanarak nesne yönelimli programlamaya izin veren katı bir C üst kümesi olmaya devam ediyor. Objective-C sözdizimini hem C'den hem de Smalltalk'tan alır: ön işleme, ifadeler, işlev bildirimleri ve işlev çağrılarını içeren sözdizimi C'den miras alınırken, nesne yönelimli özelliklerin sözdizimi orijinal olarak Smalltalk'tan alınmıştır.