C ve C++ Programlama Dilleri

Kerem Vatandas
5 min readDec 5, 2018

Bu yazı C ve C++ programlama dilleri arasında ki farklılıklar, yeni standart ile gelen bazı değişiklikler vb konuları soru cevap şeklinde, maddeler olarak topladığım bir makaledir.

  • C++11 standartları ile beraber dil büyüklüğü neredeyse 2 katına çıktığını söyleyebiliriz. Bunun devamında C++14 standartları(minör) ve C++17 standartları(major) gelmiştir. C++20 standartları için çalışmalar devam etmektedir.
  • C++11 standartları ile dilin daha fazla genişlemesi konusunda birçok iyi ve kötü yorumlar yapıldı. Ama şu konu atlanıyor, Bjarne Stroustrup’un da yaptığı açıklamalarda C++ dilinin zaten küçük bir dil olma gibi bir amacı yoktur. Bu bakımdan C++11 standartlarıyla birlikte gelen yeniliklerle dil tamamen yenilendi. Hatta kendi tabirleri ile Modern C++ deniliyor.
  • C++ dilinin en övündüğü alanlardan başında Data Abstraction(Veri Soyutlama) gelmektedir.
  • C++ dili size uygulama yazarken birçok programlama tekniği ile geliştirme yapmanıza izin verir. (Nesne Yönelimli, Prosedürel, Çoklu Paradigmalı vs.)
  • C ve C++ dillerinde derleyici büyüklüğü zaten tartışılmaması gereken bir konudur. C dilinin amacı dili ve derleyiciyi olabildiğince küçük tutmaktır.
  • Peki bunu nasıl yapıyorlar? C derleyicisinin kontrolleri C++ derleyicileri kadar katı ve fazla değildir. Bu demek oluyorki, c programcıları kod yazarken hata yapma olasılıkları daha yüksektir. Derleyici kısmında ki kontrolleri azaltarak ve bazı mekanizmaları çıkartarak derleyiciyi küçük tutuyorlar.
  • C++ dili içerisinde ki C daha güvenlidir. Çünkü derleme zamanı kontrolleri daha fazladır.
  • C dilinde kullandığımız pointer kavrami C++ da yerlerini referanslara bırakıyor. (Yanlış anlaşılmasın pointer kavramı hala kullanılmaktadır. Referanslar sadece seviyesi yükseltilmiş notasyonel bir hiledir.)
  • C++ dilinde diziler çok nadir kullanılırlar. Bunun yerine vektor yada array sarmalayıcıları kullanılır. Örneğin C dilinde char str[100] yazı tutar ama C++ dilinde bunu kullanmayacağız. Char yerine string sınıfını kullanacağız. Bu cümleden şöyle bir anlam çıkarmayın! C++ dilinde char str[] kullanamıyoruz. Tabiki de kullanabiliyoruz fakat buna gerek yok.

C dilinden C++ diline geçerken performans kaybediyor muyuz?

  • Kesinliklikle PERFORMANS kaybetmiyoruz. Dilin geliştirilirken dikkat ettiği kısımlardan biri de PERFORMANS kaybetmemektir.

C ile C++ arasında ki bazı farklılıkları kod parçalarıyla inceleyelim.

Geri dönüş değeri ile ilgili örnek

main fonksiyonunun geri dönüş değeri ve tipi

  • C dilinde neden main fonksiyonun geri dönüş değeri int ? Bunun sebebi exit fonksiyonuna yapılan çağrıdır. Non-zero başarısızlık, zeri ise başarı olarak kabul edilir. (Stdlib exit_clear, exit_success)
  • void main olarak tanımlasak ne olur? C dilinde main fonksiyonunun geri dönüş değerini void olarak kullanırsak programın başarıyla yada başarısızlık ile bittiği görülmeyecektir.
  • Diğer bir konu C dilinde main Recursive olarak çağırılabilir mi? C dilinde main Recursive olarak çağırılabilir. C++ dilinde ise bu yasaklanmıştır. C++ dilinde main fonksiyonuna return deyimi yazmaya gerek yoktur ama geliştirici olarak return yazın. Geri dönüş türü ise kesinlikle int olmalıdır.

KODU INCELEYELIM. C ve C++ derleyecileri bu koda nasıl bir davranış sergilerler

Aşağıda ki kodu inceleyelim.

  • Kodun devamı var gibi düşünün. Şimdi C89 standartlarına göre kural şöyle yerel bildirimler blokların başında yapılmalıdır. Yani executable statement(yürütülebilir deyim)den sonra bildirim yapamayız. Bu kesinlikle kötü bir kural. Zaten bu kural konulduğuna da pişman olunulmuş sonradan.
  • Önce şu deyim mevzusunu hatırlayalım. C dilinde deyimler 2’ye ayrılıyordu. DECLARATION STATEMENT ve EXECUTABLE STATEMENT.
  • Şimdi OOP’de bu kural böyle olsaydı ileride çok büyük sıkıntılar çıkarabilirdi. Örnek olarak kodun bakımı.
  • Bir ismin scope nu ne kadar daraltırsak o kodun bakımını yapmak o kadar kolay olacaktır.
  • Konuya geri dönecek olursak artık yerel bildirimlerin blok başında yapılmasına gerek kalmadı. C++ dilinde artık gerekli yerlerde değişken tanımlaması yapılabilir. Böyle de yapılması gereklidir.
  • Burada diğer önemli bir konu ömür konusudur. Yerel değişkenler C de otomatik ömürlü de olabilir, statik ömürlüde olabilir. Statik ömürlü demek programın başından sonuna kadar bellek alanını korumasıdır.
  • Neler statik ömürlü hatırlayalım… Global değişkenler | Static keywordü ile tanımlananlar | Fonksiyonlar | Stringler.
  • Otomatik ömürlü nesnelere ilk değer vermezsek, garbage value ile hayata başlar. Çöp değerler hayata başlamanın zararı var mı? Eğer onu çöp değerle kullanırsak zararı var. Bu aslında bildirimin blok başında yapılmasının bir zorlaması. C++ da şuna alışmalıyız, eğer çok önemli bir nedeni yoksa tüm nesnelere ilk değer vererek hayata başlatın. Gene bu bildirim ile ilgili fazlaca kullandığımız bir yer daha var. for döngüleri, döngü değişkeni. Örneğin for(int k=0;….) C99 da bu eklenmiştir ve böyle kullanabiliyoruz. C++ da tabiki de bunu böyle kullanabiliyoruz. Java, C# gibi diller bu olayı C++ dan biraz daha önce görüp eklemişler. Şimdi bu kural olmasaydı örneğin C89 da kullanıyor gibi düşünelim, bize zararı nedir? Öncelikle scope unu gereksiz yere genişletiyor, aynı zamanda program sonuna kadar bu değişken visible durumda oluyor. Ama yeni kurala göre for parantezi içinde tanıtılan değişkenin ömrü döngünün bloğunun sonuna kadardır.

auto keywordü ile ilgili olarak C ve C++’da anlam değişimi var.

  • Sonuç olarak auto artık C++11 standartlarında type detection. Yani tür bilgisi çıkarımını derleyici yapıyor.

C++11 decltype

decltype(exp) x; //x in türü exp neyse o

C89 standartlarında bool türü yok, C++ dilinde var

  • 0 = False ve 1 = True anlamına gelmektedir.
  • bool hemen hemen her sistem de 1 byte (char altı olacak)
  • C++ dilinde true ve false artık birer keyword
bool x = false; // yada true
  • C dilinde karşılaştırma türü int, C++ dilinde bool
  • bool ile diğer türler arası otomatik tür dönüşümü vardır.
bool x = 13; // non-zero bütün değerler True
  • Yani artık bool gereken yerler de direk olarak true false kullanmalıyız.

Karakter Sabiti Konusu

  • ‘A’ C dilinde int, C++ dilinde char

Veri Kaybı

double d = 34.7;
int ival = d; // d değeri 34
  • C ve C++ da legal bir davranış ama veri kaybı vardır. Bazı dillerde direk veri kaybına sebep olan davranışlar sentaks dışı yani direk hata.
  • C++11 de uniform initializer getirildi. Yani bunun anlamı veri kaybına yol açabilecek dönüşümleri geçersiz kılmak

C ve C++ Dilinde Dönüşümler

  • C ve C++ dillerinde dönüşümler iki kategoriye ayrılıyor. IMPLICIT TYPE CONVERSION ve EXPLICIT TYPE CONVERSION
  • implicit dönüşüm otomatik dönüştürme. Şöyle anlatayım ival + dval olsun. Derleyici bunun için geçici bir nesne oluşturuyor. Bu işlemi double türünde yapıyor. Yani dönüştürme otomatik oluyor.
  • explicit ise operatör yardımıyla yapılan dönüşümlerdir. i1 ve i2 int türden değişkenler olsun. i1/i2 olarak bölme yapmamalıyız. int/int sonuç int çıkar. 10/3 = 3 olur. C dilinde tür dönüştürme operatürü (). Normalde olması gereken (double)i1/i2 … Ama artık C++ ta bunuda yapmamamız gerekiyor. Artık bunun için yeni 4 tane type cast operatörü geldi. Bu operatörler
static_cast
const_cast
reinterpret_cast
dynamic_cast
  • NULL C dilinde sembolik bir sabittir. C++ dilinde null var ama kesinlikle kullanmamalıyız. C++11 standartlarıyla yeni bir keyword eklendi. nullptr
ptr = 0;
// C ve C++ geçerli (ptr bir pointer olarak düşünelim)
// Otomatik olarak null dönüşümü yapıcak, bir pointera null atamak istediğimizde 0 yazabiliriz fakat C++11 de böyle yapmamalıyız.
  • C++11 de nullptr var. nullptr bir adres sabiti. Yani atama şu şekilde olmalı;
ptr = nullptr;
  • C++ dilinde mecbur kalmadıkça önişlemci komutlarını kullanmayacağız. Çünkü çok tehlikeli durumlar yaratabiliyor define komutu. Bunu ileri ki yazılarımda değinirim.
  • null sembolik sabitini bazi C derleyicileri (void*)0 olarak define etmiş.
int *ptr = (void*)0; // yanlış olur
// C++ dilinde void* türden T* türüne otomatik tür dönüşümü yok.

C++ dilinde ilk değer verme sentaksları;

C++ dilinde pointerlar hala var ama C dilindeki kadar yoğun kullanmayacağız. C++ da seviyesi daha yüksek olan referansları kullanacağız.

C++ dilinde pointer ile primitive türler arası otomatik tur dönüşümü yok. C dilinde var.

  • Sonuç olarak C++ dilinde pointer değişkenlere adres olmayan bir verinin atanması veya farklı türden bir adresin atanması sentaks hatası.

--

--