Bu C programının C++ karşılığı nedir

Başlatan Erdem , 08 Ağustos 2012, 21:14:58

Erdem

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
 
typedef struct {
  size_t         width;
  size_t         height;
  unsigned char *data;
} Image;
 
static Image * image_new (size_t width,
           size_t height)
{
  Image *image;
 
  image = malloc (sizeof *image);
  image->width = width;
  image->height = height;
  image->data = malloc (width * height);
 
  return image;
}
 
static void image_free (Image *image)
{
  free (image->data);
  free (image);
}
 
static void image_fill (Image *image,
            unsigned char  value)
{
  memset (image->data, value, image->width * image->height);
}
 
/**
 * image_set_pixel:
 *
 * Sets a pixel passed in signed (x, y) coordinates, where (0,0) is at
 * the center of the image.
 **/
static void image_set_pixel (Image *image,
                 ssize_t        x,
                 ssize_t        y,
                 unsigned char  value)
{
  size_t tx, ty;
  unsigned char *p;
 
  tx = (image->width / 2) + x;
  ty = (image->height / 2) + y;
 
  p = image->data + (ty * image->width) + tx;
 
  *p = value;
}
 
static void image_save (const Image *image,
            const char  *filename)
{
  FILE *out;
 
  out = fopen (filename, "wb");
  if (!out)
    return;
 
  fprintf (out, "P5\n");
  fprintf (out, "%zu %zu\n", image->width, image->height);
  fprintf (out, "255\n");
 
  fwrite (image->data, 1, image->width * image->height, out);
 
  fclose (out);
}
 
static void draw_circle (Image         *image,
             int            radius,
             unsigned char  value)
{
  int x, y;
 
  for (x = -radius; x <= radius; x++) {
    y = (int) sqrt ((double) (radius * radius) - (x * x));
 
    image_set_pixel (image, x, y, value);
    image_set_pixel (image, x, -y, value);
  }
}
 
int main (int argc, char *argv[])
{
  Image *image;
 
  image = image_new (600, 600);
 
  image_fill (image, 0xff);
  draw_circle (image, 200, 0);
  image_save (image, "circle.pgm");
 
  image_free (image);
 
  return 0;
}


Arkadaşlar bu C programının C++ karşılığını yazabilecek var mı.

Ayrıca bu program ne yapıyor. Tamam ne yaptığını biliyorum aslında bir tane çember çiziyor. Ama neden bu kadar çok malloc kullandığını anlamadım. Neden dinamik olarak bellek tahsis etme ihtiyacı duymuş.

bocek

dinamik olarak ayırmasının sebebi image değişkenini Image pointeri olarak tanımlamış olması.
bunun da sebebi image_new fonksiyonunun dönüş değerinin Image pointeri olması.
onun da sebebi pointer olarak tanımlayınca, değer döndürürken Image struct'ının elemanlarını tek tek kopyalamak yerine sadece Image tipindeki değişkenin adresini döndürmesi yetiyor. yani daha hızlı oluyor.
malloc ile dinamik olarak bellek ayırmasının sebebi de belirttiğim gibi Image tipindeki değişkeni pointer olarak tanımlama isteği.
yani bir pointer var ama pointerin gösterdiği adreste yeterince yer olmalı ki Image değişkeni oraya sığsın ve biz de başkasına ait alanlara veri yazmaya çalışıp hata oluşturmayalım. pointer olarak tanımlamasaydı malloc ile yer ayırmasına da gerek kalmayacaktı.
malloc, c++'taki new operatörünün, free de delete operatörünün görevini görüyor.
1 ya da 0. işte 'bit'ün mesele..

Erdem

Teşekkürler. Bu arada asıl öğrenmek istediğim şey olan bu programın D karşılığını öğrendim.
import std.stdio;
import std.algorithm;
import std.math;
 
struct Image {
    size_t         width;
    size_t         height;
    ubyte[]        data;
 
    this(size_t width, size_t height)
    {
        this.width = width;
        this.height = height;
        data.length = width * height;
    }
 
    void fill(ubyte value)
    {
        std.algorithm.fill(data, value);
    }
 
    /**
     * image_set_pixel:
     *
     * Sets a pixel passed in signed (x, y) coordinates, where (0,0) is at the
     * center of the image.
     **/
    void set_pixel(sizediff_t     x,
                   sizediff_t     y,
                   ubyte          value)
    {
        size_t tx = (width / 2) + x;
        size_t ty = (height / 2) + y;
 
        data[(ty * width) + tx] = value;
    }
 
    void save(string filename)
    {
        auto file = File(filename, "wb");
 
        file.writeln("P5");
        file.writefln("%s %s", width, height);
        file.writefln("255");
 
        file.rawWrite(data);
    }
}
 
void draw_circle (ref Image      image,
                  int            radius,
                  ubyte          value)
{
    foreach (x; -radius .. radius + 1) {
        int y = cast(int)sqrt(cast(double)(radius * radius) - (x * x));
 
        image.set_pixel(x, y, value);
        image.set_pixel(x, -y, value);
    }
}
 
void main()
{
    auto image = Image(600, 600);
 
    image.fill(0xff);
    draw_circle(image, 200, 0);
    image.save("circle.pgm");
}


Bu arada bu resmi oluşturduğumuz resim biçim Netpbm olarak geçiyor ve kolaylıkla şu şekilde bir resim dosyası oluşturabiliyor.



Ayrıca kolaylıkla resim dosyası oluşturabiliyoruz ve resim dosyasının biçimi de çok basit. Bu örneği bir kaç tane çember çizme algoritması ile aldığım sonuçları karşılaştırmak için kullanmayı düşünüyorum.

fatih6761

@bocek arkadaşım aslında new ve delete bildiğinden daha güzel.new hem malloc ile bellek ayırıyor, hemde nesnenin Constructor ilkelendirme fonksiyonunu çağırıp nesneyi initialize ediyor.
delete ise önce neseneyi Destructor ile sonladırıp ( Dispose oluyor ) nesneyi bellekten siliyor.Nesne yönelimi programlama dillerinin bu giib ekstra özellikleri var...

Erdem

#4
Arkadaşlar aynı soruyu D forumlarında da sormuştum. Konuya burdan ulaşabilirsiniz:

http://ddili.org/forum/post/7284

Hatta biliyormusunuz bilmiyorum  :D github'a çok harika yeni özellikler eklemişler. Ben de ufak bir kod parçası oluşturdum.

https://gist.github.com/3298771

speak48

c dekini düzgün çalışması için
  fprintf (out, "%zu %zu\n", image->width, image->height);
yerine
  fprintf (out, "%d %d\n", image->width, image->height);
yazılması lazım

nedenmi malloc kullanılmış
1.image boyutu değişken olduğu için kullanıcı istediği boyuttaki imageyi oluşturabilsin diye
    auto image = Image(600, 600);
eğer mallocsuz bu işi her boyut için baştan fonksiyon taımlanmalı ve ayrı ayrı data saklanmalı.
mesela
600x600 için  image_600x600() fonksiyon bunun içinde char image [600*600] datası
640x480 için image_640x480() fonksiyon bunun içinde char image [640*480] datası
2. c her kod tip uyumu sağlandığı sürece c++ tada çalıştırlabilinir.

c kodunu c++ çevirmek daha anlaşılır kılmaz.
c yi anlamıyorsak zaten c++ hiç anlıyamayız.

cpp anlamak için c de ne yaptığına ,c yi anlamak için assembly de ne yaptığına bakılır.
ama windowsta çalıştığımız için windows apilerini bilmeden hiç birşey anlaşılmaz.
ben şuan baştan sona api leri inceliyom ve şunu farkettim c ne iş yapıyosa bu işleri apilerle yaptırıyo.
consol açma yazı yazma dosya yazma
c aracı işi yapan windows.

saygılar






Erdem

Alıntı yapılan: speak48 - 29 Eylül 2012, 12:26:44
c dekini düzgün çalışması için
  fprintf (out, "%zu %zu\n", image->width, image->height);
yerine
  fprintf (out, "%d %d\n", image->width, image->height);
yazılması lazım

Benim ortamımda düzgün çalışıyor  ;)

size_t, ptrdiff_t, intptr_t ve uintptr_t gibi türlerle çalışırken buradaki z boyut belirtiyor. Örneğin size_t işaretsiz tamsayıdır ama boyutu 32 bitlik ortamda ya da 64 bitlik ortamda çalışmanıza göre değişir.

Buradaki z boyutu size_t kadar olan ve bir C99 başlığı olan inttypes.h'da tanımlı bir tamsayı belirtir.

Bu durumda windows ortamı için z yerine I kullanılabilir ya da platformdan bağımsız olması için
PRIu32 makrosu kullanılabilir.

http://www.viva64.com/en/k/0023/

#include <stdio.h>
#include <inttypes.h>

int main()
{
    size_t   i = 0;
    uint32_t k = 0;

    printf("i = %zu k = %"PRIu32"\n", i, k);
    return 0;
}


Alıntı yapılan: speak48 - 29 Eylül 2012, 12:26:44
c yi anlamıyorsak zaten c++ hiç anlıyamayız.

Buna katıldığımı pek söyleyemem. C küçük bir dildir. C++ ise C'ye göre çok daha gelişmiş özellikleri olan karmaşık bir dildir. Örneğin C'nin kaynak yönetimi yöntemleri C++'da kullanılmaz. C'nin elden ele hata kodu geçirme yöntemi ile C++'nin hata atma düzeneği farklıdır.

İşte C++'nin karmaşıklığını gösteren örnek bir program.

https://gist.github.com/3803796

Alıntı yapılan: speak48 - 29 Eylül 2012, 12:26:44
ama windowsta çalıştığımız için windows apilerini bilmeden hiç birşey anlaşılmaz.

Ben windows'ta çalışmıyorum  :D

Buna da katılmıyorum. Tek bir platforma bağlı kalmak, o dil hakkındaki bilgilerinizi geliştirmez  sadece kullandığınız platformun kütüphanelerini öğrenirsiniz. Başka platformlara geçince de sudan çıkmış balığa dönersiniz.

Ben win32 api ile uğraşmayalı neredeyse 10 yıl oluyor. Onu da C++ In Action Industrial Strength Programming kitabını okurken uğraşmıştım. Burada nesne yönelimli  programlama teknikleri ve MVC tasarım deseni kullanarak win32 api kütüphanelerinin kullanımı anlatılmış. Bu arada kitabın yazarı Bartosz Milewski daha önceden Microsoft'ta çalışmış bir yazılım mühendisi.

http://www.relisoft.com/book/win/index.htm

Ama ben bu kodların büyük kısımını Gentoo altında yazmıştım  :)

Win32 api ile kod yazmayı , hele böyle teknikler kullanmadan da biraz angarya olarak gördüğümü söylemeliyim.

speak48

bu kadar şey biliyonsan madem c++ ta karşılığınıda sen yazarsın zaten.

Alıntı Yapc yi anlamıyorsak zaten c++ hiç anlıyamayız.

bu sözümüde bırak katılıp katılmamayı adeta ispatlamışsın.
bende c++ sın zor olduğunu kastediyorum zaten

Alıntı Yapama windowsta çalıştığımız için windows apilerini bilmeden hiç birşey anlaşılmaz.
sonuçta os altında çalışmıyormusun ha windows ha linux

apiler bu işin temeli  sadece api ve asm ilede çok baba program yazılabiliniyor.
apileri ben bilmiyorum yeni başladım ama değerini çok anlıyan birisiyim.
demek istediğim tüm dillerin dönüp dolaşacağı yer api ve assembliy
ha bide c ve c++ varken d ile uğraşmayıda gereksiz bulurum
çünkü bizde yok tcl,piton,c# ... biraz uğraşınca ülen bunlar bu işeri nasıl yapıyo nasıl çalışıyo anlamayınca
pek faydalı olmuyor.

Erdem

#8
Alıntı yapılan: speak48 - 29 Eylül 2012, 18:28:11
bu kadar şey biliyonsan madem c++ ta karşılığınıda sen yazarsın zaten.

Aslında hala C'nin bellek işlemlerini yeteri kadar bildiğimden emin değilim.

O yüzden bazen emin olmak için soruyorum.

Örneğin assembly ve C'de bellek ayrıldıktan sonra bir de oradaki baytlara bazı değerler yazılması gerekir. C++'ın new'ü de aynısı yapar: bellek ayırır ve baytlara ilk değerleri verir. Ama new, C'nin malloc kullanan iki adımlık külfetini teke indirmiştir: yer ayır ve üyelere değer ata. (Ama programcı istemezse değer atanmaz.)

C konusunda da sadece bir kitabım var. C Primer Plus. Baştan sona okumadım ama takıldığım yerlerde açıp bakıyorum ;)

Zaten asıl amacım da D sürümünü yazmaktı. Onu da yazdım bile:

https://gist.github.com/3298771

Alıntı yapılan: speak48 - 29 Eylül 2012, 18:28:11
ha bide c ve c++ varken d ile uğraşmayıda gereksiz bulurum

Ben de tam tersini düşünüyorum. Neredeyse 2001 yılından beri C++ ile uğraşıyordum. Ama bir kaç sene önce D'ye geçtim. D öğrendikten sonra itiraf etmeliyim ki C++ ile uğraşmak biraz angarya gibi gelmeye başladı  :)

İşte bir örnek :

https://gist.github.com/3762946

mesaj birleştirme:: 29 Eylül 2012, 19:25:47

Bu arada C++03'ün yetersizlikleri C++11 ile düzeltiliyor.

C++11'in Bazı Yenilikleri ve D'deki Karşılıkları

İşin ilginç tarafı C++11 ile gelen yeniliklerin hepsi D'de zaten var. Hatta bazı olanaklar D'de daha iyi.

Bu konular bu seneki D ve C++11 seminerinde konuşulmuştu.

https://www.picproje.org/index.php/topic,39661.0.html

speak48

ya amacım zaten tartışmak değil bildiğim kadar yol göstermek çünkü
benim ihtiyacımı api çözecekken kimse beni apiye yönlendirmedide
zaten c++ da new operatorü mallocu çağırmakta.
mallocta büyük ihtimal bi api cağırır.

ha hangisi daha anlaşılır bence malloc ve daha alt seviyesi çünkü ne yaptığını anlarsın.
ama hangisi kolay tabiki new.
peki ben hangisini kullanırım tabiki bir elektronikçi olarak her zaman temelini kullanma isteğim vardır.

Erdem

Aslında C'nin kaynak yönetimi yöntemleri C++'da kullanılmaz derken kasdettiğim buydu. C++ için kesinlikle malloc kullanılmaz yerine new kullanılır.

http://stackoverflow.com/questions/184537/in-what-cases-do-i-use-malloc-vs-new

Aralarında çok önemli farklar var:

- malloc bellek ayırır

- new hem bellek ayırır hem de nesne kurar (nesnenin kurucu işlevini (constructor) çağırır

- free belleği geri verir

- delete hem nesnenin sonlandırıcı işlevini (destructor) çağırır, hem de belleği geri verir

C++'ta hemen her durumda new ve delete kullanılır. malloc veya arkadaşları kullanıldığında bunun için geçerli bir neden vardır ve onu yapan zaten o nedeni biliyordur  ;)

speak48

bu c++ ta hiç malloc kullanılmaz demek değil.
new yerine malloc herzaman kullanılmaz demek
newle classta yaratıldığı için mallocla class yaratmazsın.
tabiki cpp kadar struct ve mallocla herşey yapıldı.

ama benim anlamadığım d nesi ?
şuan bir yerde çalışıyomusunuz?
d nerde kullanılır hangi şirketler kullanır?
amacınız d ile nedir kendi işlemlerinizimi yapmak?
bende hendi işlemlemlerimi matlabda yapmayı severimde.



Erdem

Alıntı yapılan: speak48 - 29 Eylül 2012, 20:51:52
ama benim anlamadığım d nesi ?

Herşeyden önce D bir sistem programlama dili. Bu konuda Scott Meyers'ın The D Programming Language kitabında bir giriş yazısı var. Aslında bu bölümü çevirebilseydik çok süper olurdu  ;-)  Oradaki görüşleri kısaca özetlersek:

C++ gerçekten çok başarılı bir dil oldu ama gözardı edilemeyecek bir gerçek var ki C++ karmaşık bir dil. Bu karmaşıklık C++'nin geniş tabanlı kullanıma sahip iki takipçisi C# ve Java'nın tasarımını da etkiledi. Her ikisi de C++'nin karmaşıklığından uzak durarak - sağladığı işlevselliği kolay kullanılabilir bir şekilde sağlamaya çalıştılar. Eğer hızlı bir şekilde kod üretmek istiyorsanız Java ve C#, C++'ye göre daha iyi bir seçim olabilir.

Fakat C++ sadece üretken bir dil olarak tasarlanmadı; C++ bir sistem programlama dili. Yani C++'nin tasarım amaçlarından bir tanesi C'ye bu yönde rakip olmak. Burada sistem programlama derken donanımla haberleşmek, gömülü sistemler ve sürücüler yazmak, kısacası üzerinde çalıştığı donanımın son damla performansını kullanacak şekilde tasarlandığını düşünebiliriz. Örneğin bir sistem programlama dili ile bir işletim sistemi yazılabilir.

D ise bu noktada sistem programlama konusunda C++'nin yeni nesil geleceği olarak düşünebiliriz. Java ve C# gibi C++'nin karmaşıklığından mümkün olduğu kadar uzak bir dil. Bellek yönetimi konusunda çöp toplama mekanizması var ama eğer isterseniz belleği kendiniz de yönetebiliyorsunuz. Örneğin C++ Unicode desteği vermiyor ama D daha başlangıçtan Unicode desteği veriyor. Bu da demek oluyor ki değişken isimlerini D'de kendi dilinizde kullanabiliyorsunuz. C++00x sadece çok kısıtlı olarak Unicode desteği veriyor.  C++ çok karmaşık ve güçlü bir dilken, D en az C++ kadar güçlü ve daha az karmaşık bir dil olarak karşımıza çıkıyor.

Kısaca diyebiliriz ki D, C++'daki boşlukları tespit edip o boşlukları dolduran, yeni, yazım açısından daha basit bir sistem programlama dili olarak karşımıza çıkıyor. Bir sistem programlama dili olduğu için bir işletim sistemi bile yazmak mümkün.

Bir de Andrei Alexandrescu diğer dillerle karşılaştırmasını yaptığı bir sahra çölü haritası mı ? ! öyle bir resim üzerinde diğer dillerle karşılaştırmasını yaptığı ilginç bir videosu var:

Three Cool Things About D - The Case for the D Programing Language

Alıntı yapılan: speak48 - 29 Eylül 2012, 20:51:52
şuan bir yerde çalışıyomusunuz?

Evet bilgisayar programcısı olarak çalışıyorum.

Alıntı yapılan: speak48 - 29 Eylül 2012, 20:51:52
d nerde kullanılır hangi şirketler kullanır?

Sizi buraya alalım.

http://stackoverflow.com/questions/56315/d-programming-language-in-the-real-world

Sonra benim tanıdıklarım arasında Peter Alexander isminde bir programcı var. Kendisi Codemasters'ta oyun programcısı olarak çalışıyor.

http://poita.org/

Bizim Ali bey Slikon Vadisinde yazılım mühendisi olarak çalışıyor.

http://acehreli.org/resume.html

Alıntı yapılan: speak48 - 29 Eylül 2012, 20:51:52
amacınız d ile nedir kendi işlemlerinizimi yapmak?

Zaten yapıyorum. Bu aralar D'nin yanında biraz Python da öğrenmeye başladım.

speak48

gerbay güzel  konuştunuz.
bende donanımcıyım ama c++ ile gui yazmam gerekti.
bu başlıkla alakası yok ama ben gene sorayım
bu forumda c++ ta bana yardım edecek arkadaş varmı?
veya bana yardım edebilcek bu forumdamı yok türkiyedemi yok?
önerebileceğiniz bir forum varmı?

Erdem

C++ konusunda ceviz forumları iyidir.

http://forum.ceviz.net/c-c/

Eğer kesmezse  comp.lang.c++. moderated haber grubuna takılabilirsiniz  ;)