2010-05-15 25 views
6

Kısa bir süre önce C'deki küçük bir kişisel proje (BGR değeri dönüştürme programına RGB değeri) başlattım ve RGB'den BGR'ye dönüştüren bir fonksiyonun yalnızca dönüşümü değil, aynı zamanda dönüşümü de gerçekleştirebileceğini fark ettim. Açıkçası bu demek ki iki fonksiyona ihtiyacım yok rgb2bgr ve bgr2rgb. Ancak, bir makro yerine bir işlev işaretçisi kullanmam sorun olur mu? Örneğin: Meraktan öznel bir soru daha var olarakÖnişlemci "makro işlevi" ile işlev işaretçisi - en iyi uygulama?

int rgb2bgr (const int rgb); 

/* 
* Should I do this because it allows the compiler to issue 
* appropriate error messages using the proper function name, 
* not to mention possible debugging benefits? 
*/ 
int (*bgr2rgb) (const int bgr) = rgb2bgr; 

/* 
* Or should I do this since it is merely a convenience 
* and they're really the same function anyway? 
*/ 
#define bgr2rgb(bgr) (rgb2bgr (bgr)) 

ben ille yürütme verimliliğinde bir değişiklik için aramıyorum. Tip güvenliğinin ne yöntemle ne de kayıp olduğu bilinmemektedir. Fonksiyon göstergesinin sadece bir kolaylık olması mı, yoksa habersiz olduğum daha pratik faydaları var mıdır?

+9

Şahsen, her ikisini de kullanan bir isim ile geldim, int intap_rb() ';) – caf

+0

@caf: Kesinlikle başka harika bir fikir. Bu tamamen sorunu önler, ancak mantıken sağlam bir alternatiftir. +1 – Dustin

cevap

6

Bir başka olasılık, sadece ikinci fonksiyonun ilkini çağırması ve derleyicinin onu optimize etmekten endişe etmesine izin vermektir (bir kuyruk çağrısında olduğu gibi).

+0

İyi fikir. Sonuçta, optimizasyon derleyicimden neden daha iyi bir kod oluşturmaya çalışmalıyım? Genel olarak davranışı, sadece temel makine talimatlarını değiştirmez. Kayıt için, herhangi bir byte'ı, bir işlev işaretçisi, bir makroyu veya gerekmeyen öğelerin ikili/yürütülebilir dosyalarını sıyırdıktan sonra gerçek işlevi çağıran bir alt yordamı kullanarak kaydetmedim. Sonunda, derleyicinin üç baytı değişti (evet, sadece üç), optimizasyon devam ettiği sürece, kodumuzu inline montajı kullanarak daha az portatif yapmaktan çok daha iyisini yapamam. Teşekkürler! : D – Dustin

5

Makroyu kullanırdım. Daha yaygın ve daha idiyicidir ve çeviri birimlerini geçerken daha az sorunla karşılaşır (yani, makroyu statik olarak bildirmekten endişelenmenize gerek yoktur). Ayrıca, bir işlev işaretçisi kullanarak, çoğu derleyicide satır eklemeyi engellersiniz.

Son olarak işlev işaretçisi ile, müşteriler bunu yapmak mümkün değil:

int evil(const int bgr) { /* Do something evil */ } 

bgr2rgb = evil 

Tabii, muhtemelen bunu istemiyorum, ama aşağı bgr2rgb benzer isimli bir değişken olabileceği mümkündür sadece bir yazım hatası alır hat ....

ben bu şekilde tanımlamak buna rağmen makro, daha güvenli - bir fonksiyon benzeri makro burada gerek yoktur:

#define bgr2rgb rgb2bgr 
+1

İşlevsel satır kaybından söz ettiğiniz için teşekkür ederiz. Kesinlikle bilmeye değer bir şey! Ayrıca, belli bir fonksiyona yeniden atanmasını engelleyerek, fonksiyon göstergesini niteleyebilirim. İşlevsel olmayan bir makronun kullanıldığı gibi, bunun için herhangi bir fayda görmüyorum, ancak int bgr2rgb = 0; 'gibi bir şeyin saçma olduğu bir sorunu hayal edebiliyorum. Güvenlik açısından, işlev benzeri bir makro daha iyidir çünkü böyle bir sorunu önlemektedir. Sonuçta, tüm makroların garip isimleri yoktur. Genel olarak büyük girdi! Umarım daha düşünceli cevaplar vardır! – Dustin

+2

İşlev benzeri makro daha iyidir, çünkü tek bir sonuç almadan "bgr2rgb" adlı bir yapı üyenize sahip olabileceğiniz anlamına gelir. – caf

+0

@caf: Katılıyorum, ancak işlev benzeri bir makroyla, bgr2rgb işlevini bir işlev işaretçisine atayamazsınız. Dustin'in ilk yöntemini kullanmak, hem makro problemleri önlediğinden daha iyidir. – tomlogic

İlgili konular