Struct kullanmak ve Hafıza

Başlatan mistek, 11 Aralık 2014, 00:43:50

mistek

Struct kullanmak hafıza kullanımını ne derece etkiler iyileştirir mi yoksa daha çok yer mi kaplar?

Programlarımda ne kadar sıklıkla kullanayım alışkanlık haline gelmeli mi?

Not: Daha önce hiç "typedef" dahi yazmadım ilk olacak.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

X-Fi

struct kullanımı hafıza kullanımını etkilemez. Compilier tarafında işlenir ve kodun okunmasını kolaylaştır ayrıca pointer ile sıralı okuyup yükleyebilmeniz için erişim düzenini de sağlar.
http://www.coskunergan.dev/    (Yürümekle varılmaz, lakin varanlar yürüyenlerdir.)

kimlenbu

Struct kullanmadan olur, yalnız 1000 satırda bitecek iş olur 1500 satır, kod okunamaz hale gelir, program daha da büyürse iyice içinden çıkılmaz bir hal alır. Programın modülerlikten uzak olduğu için kodların tekrar kullanılabilirliği kalmaz, benzer şeyleri baştan yazar durursun.

Başıma geldi ordan biliyorum :)

Her yerde kullanılacak diye bir şey de yok.

mistek


Deitel&deitel den Yapılar bölümünü okumaya başladım teşekkürler.

Alıntı yapılan: gerbay - 11 Aralık 2014, 01:41:34
struct sız yazılım olmaz..  iyileştirir mi kötüleştirir mi? bu sizin kullanımınıza bağlı..  iyileştirebilir de kötüleştirebilir de..

mesaj birleştirme:: 11 Aralık 2014, 01:43:11

soğansız yemek olur mu? ... gibi bir soru olmuş

O kadar önemli demek hocam :)
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

mistek

Proje dosyalarının birinde header dosyasında

typedef struct{
   uint8_t Bayrak1;
   uint8_t Bayrak2;
   uint8_t Bayrak3;

}Bayraklar;

extern Bayraklar Bayrak;

şeklinde struct tanımladım.

Kod dosyasında da
Bayraklar Bayrak; olarak yazdım.

Şimdi bu Bayrak yapısının elemanlarına diğer dosyalardanda erişmem gerekiyordu.

Bende gerekli olan dosyaların başında Bayraklar yapısını barındıran header dosyasını include ettim.

Proje hatasız derlendi. Herkes istediği yere ulaşıyor gibi gözüküyor.

Peki normalde bu şekilde mi yapılıyor ? Doğrusu nedir?

Bir sorum daha var ama karışmaması için buraya kadar olan kısmı çözünce soracağım.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

Burak B

Evet genel anlamda böyle yapılıyor. Ancak bu tarz global değişken aktarımı hatalı olmasa da doğru değil.
"... a healthy dose of paranoia leads to better systems." Jack Ganssle

mistek

#6
Peki nasıl yapmam daha doğru olur ?

mesaj birleştirme:: 11 Aralık 2014, 19:29:59

İkinci Sorum:
stm32f10x_exti.h dosyasını açıyorum. İçerisinde

typedef struct
{
  uint32_t EXTI_Line;               /*!< Specifies the EXTI lines to be enabled or disabled.
                                         This parameter can be any combination of @ref EXTI_Lines */
   
  EXTIMode_TypeDef EXTI_Mode;       /*!< Specifies the mode for the EXTI lines.
                                         This parameter can be a value of @ref EXTIMode_TypeDef */

  EXTITrigger_TypeDef EXTI_Trigger; /*!< Specifies the trigger signal active edge for the EXTI lines.
                                         This parameter can be a value of @ref EXTIMode_TypeDef */

  FunctionalState EXTI_LineCmd;     /*!< Specifies the new state of the selected EXTI lines.
                                         This parameter can be set either to ENABLE or DISABLE */
}EXTI_InitTypeDef;

Böyle bir yapı tanımlanmış.

Bende yine projemde bu header dosyasını include ederek farklı dosyalarda sadece
EXTI_InitTypeDef EXTI_InitStructure;
yazarak kullanabiliyorum.

Sormak istediğim extern yazmadan bunu nasıl yapıyorum?
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R

MrDarK

Alıntı yapılan: mistek - 11 Aralık 2014, 18:35:40
Proje dosyalarının birinde header dosyasında

typedef struct{
   uint8_t Bayrak1;
   uint8_t Bayrak2;
   uint8_t Bayrak3;

}Bayraklar;

extern Bayraklar Bayrak;

Ben şöyle kullanıyorum ;
o modülün adına değilde başka bir genel kullandığım header içine bu stractı tanımlıyorum.

Asıl kullanılan modülün C dosyasına ;
struct Bayraklar  g_StrctBayraklar;
şeklinde tanımlıyorum. Sonra bunu tüm projeye açmak için de aynı C dosyasının header'ına
extern struct Bayraklar  g_StrctBayraklar;

şeklinde tanımlandığı anda hepsi aynı yere bağlanmış oluyor. Eskiden hocam sizin yapıdaki gibi kullanıyordum nette o şekilde örnekler vardı. Incelediğim yazılımlarda farklı kullanım şekilleri gördüm ve bu yöntemin daha doğru olduğuna karar verdim.

Struct'ı da Global_Module_Header.h dosyası içine tanımlıyorum
Picproje Eğitim Gönüllüleri ~ MrDarK

Burak B

#8
Sorularını şöyle cevaplandırmaya çalışayım.

1- Öncelikle şunu iyi bilmek gerekir. Global değişkenler tehlikelidir. Çünkü en basit ifadeyle yazılan kod karmaşıklaştıkça kontrol edilmeleri zorlaşır. Hele ISR içerisinde kullanılıyorsalar işler iyice sarpasarabilir. Bu nedenle güvenli bir kod için global değişken kullanımı mümkün olan en az düzeye indirilmelidir. Hatta ortadan kaldırılmalıdır. Bunun için ne yapılabilir ?
a) Modüler kod yazılmalı ve modül(xxxx.c) içerisinde erişilmesi gereken bir bilgi varsa bu bilgi modülün sağladığı fonksiyonlar ile elde edilmeli.
b) Bu modül tarafından kullanılan özel veritipleri varsa (typedef struct ... bayrak_t) bunlar modülün header dosyası(xxxx.h) ile ifade edilerek diğer modüller tarafından kullanılabilir olmalı.
c) Multithread bir ortamda çalışılıyorsa (RTOS gibi) queue, semaphore ve mutexler ile veriler aktarılmalı.

Böylece xxxx.c modülü tarafından sağlanan  bayrak_t xxxx_bayrakdurumu(void); gibi bir fonksiyon ile okunması gereken bayrak bilgisi elde edilebilir. Ayrıca bu sayede gerekli değişkenin kontrolü de bu modülün elinden alınmamış olur. Yani takibi kolaylaşır.

2- extern derleyiciye biryerde bu tanıma uygun bir değişken olduğunu bildirir. Peki ya böyle bir değişken tanımlı değilse ? :)
     Mesela ben kodumda
     
     extern uint8_t xmen;
     

     şeklinde bir tanımlama yapsam ve bu kodu derlesem. Derleyici hata vermez. Kodu derler. Ancak ne zaman kodun içinde şöyle bir ifade kullansam
     
     ...
     xmen=5;
     

     derleyici durumu anlar ve bana böyle bir değişken tanımlanmamış der. extern bir tip tanımlama değildir.

   typedef struct ise bir veri türünü ifade eder. Bunun anlamı şudur bir modülün header dosyasında tanımlanan veri tipleri bu header dosyasını çağıran tüm diğer modüller tarafından anlaşılabilir.
"... a healthy dose of paranoia leads to better systems." Jack Ganssle

mir_as82

Hocam şu şekilde oluyor olay.
Benim yazdığım modül var bu modülün 2 adet dosyası var. .h ve .c (interface ve implementation files)
Ben modülümü kullanacak müşterilerimin, modülüm içindeki değişkenlere kendi oluşturacakları implementasyon dosyasından erişmesini istiyorsam bunu onlara bildirmek adına, .h dosyama "extern" diye bir type modifier olarak adlandırılan bir keyword ekliyorum. örneğin extern int projeDegiskeni;//gibi

Bu aynı zamanda derleyiciye bir mesaj da veriyor. "Derleyici sen bu extern ile yazılmış değişkenin ne olduğuna takılmaa o işi linker çözecek".
Derleyici her dosyayı tek tek ele alacağı için benim modül dosyamı görüyor ve oraya linker için referans yerleştiriyor.

Daha sonra benim modülümü kullanan müşterim alıyor kendi implementasyon dosyasında int projeDegiskeni = 10;
olacak şekilde kullanmalıdır.
Alıntı Kaan ASLAN: "Bildiğiniz gibi, C'de extern belirleyicisi ile bir nesne bildirimi yapıldığında bu bildirim bir tanımlama belirtmez. Yani bildirilen değişken için bellekte bir yer ayrılmaz.[2] Dolayısıyla extern belirleyicisi ile bildirilmiş olan bir nesnenin toplamda tek bir tanımlamasının bulunması gerekir. Bu tanımlama herhangi bir derleme biriminde yapılabilir. "

mistek

Teşekkürler arkadaşlar konu daha da netleşti şimdi.
boş işlerin adamı ---- OHM Kanunu: I = V/R ---- Güç Formülü: P = V*I = I^2*R = V^2/R