Arduino'da küresel değişkenler kötü mü?

Programlamada nispeten yeniyim ve okuduğum en iyi kodlama uygulamalarının birçoğu, global bir değişken kullanmak için çok az iyi neden olduğunu (ya da en iyi kodun hiçbir şekilde küresel olmadığını) belirtiyor.

Bunu akılda tutmak için elimden gelenin en iyisini yaptım, bir SD kart ile bir Arduino arayüzü oluşturmak için yazılım yazarken, bir bilgisayarla konuşun ve bir motor kontrolörü çalıştırın.

Şu anda yaklaşık 1100 satırlık “başlangıç ​​seviyesi” kodu için 46 küreye sahibim (satırda birden fazla işlem yapılmadı). Bu iyi bir oran mı yoksa daha fazla azaltmaya mı bakmalıyım? Ayrıca, küre sayısını daha da azaltmak için hangi uygulamaları kullanabilirim?

Bunu burada soruyorum çünkü genel olarak bilgisayar programlaması yerine Arduino ürünlerine kodlama için en iyi uygulamalarla özellikle ilgileniyorum.

20
@LookAlterno: "Kaçınıyorum" ve "yapamazsın" çok farklı şeylerdir.
katma yazar James Hopkin, kaynak
Bir Arduino'daki küresel değişkenler, PC'ninkinden daha az kötüdür. İnsanları bir döngü değişkeni, global değişken olarak bildirdiklerini gördüm. TBH Onları denemek ve onlardan kaçınmak, ancak hafıza yönetiminde onların yeri var.
katma yazar Thomas Myron, kaynak
@LookAlterno - Küresel değişkenlerle ilgili en büyük sorun zayıf programcılar. Her değeri bir argüman olarak iletmelisiniz (5'ten az tutmaya çalışın), çünkü bu kodunuzu bölümlere ayırır ve tekrar kullanmanıza izin verir. İşlevleri birlikte programlara kopyalamak ve yapıştırmak gerçekten kolaydır, ancak yalnızca olabildiğince globlardan kaçınırsanız. Aynı zamanda yekpare fonksiyonları önler, eğer 20 arda 2000 hat fonksiyonuna geçiyorsanız, o zaman yeniden düzenlemelisiniz.
katma yazar Thomas Myron, kaynak
Aslında, bazı gömülü programcılar yerel değişkenleri yasaklar ve bunun yerine genel değişkenler (veya işlevli statik değişkenler) gerektirir. Programlar küçük olduğunda basit bir durum makinesi olarak analiz etmeyi kolaylaştırabilir; çünkü değişkenler birbirlerinin üzerine asla yazmazlar (yani: yığın ve yığın tahsis edilen değişkenleri yaptıkları gibi).
katma yazar Hououin Kyouma, kaynak
@LookAlterno Err, tuhaf makroları ve kütüphaneleri olan sadece C ++ olduğu için Ardunio'da dersler yazamaz mısın? Eğer öyleyse, her değişken global değildir. Ve C'de bile, genellikle değişkenleri (belki de yapılar içinde) global değişkenlere sahip olmak yerine işlevlere dönüştürmeyi tercih etmek en iyi yöntem olarak kabul edilir. Küçük bir program için daha az kullanışlı olabilir, ancak program büyüdükçe ve karmaşıklaştıkça genellikle işe yaramaz.
katma yazar sarath, kaynak
Arduino'da global değişkenlerden kaçınamazsınız. Bir işlev/yöntem kapsamı dışındaki her değişken bildirimi geneldir. Dolayısıyla, fonksiyonlar arasında değerleri paylaşmanız gerekiyorsa, her bir değeri argüman olarak iletmek istemediğiniz sürece, küresel olmaları gerekir.
katma yazar user31481, kaynak
@Muzer. C ++ sınıflarını yalnızca kütüphane geliştirme ve daha büyük programlar için kullanıyorum. Nedenlerden dolayı C ++ 'ı önlüyorum.
katma yazar user31481, kaynak
katma yazar Brian, kaynak
@LookAlterno Bu, C/C ++ 'nın sıradan bir gerçekçiliğidir (buna rağmen ad alanları), ki bu Arduino’ya özgü değildir ve sizin belirttiğiniz gibi, hiçbir şekilde küresel değişkenlerin önlenemeyeceği sonucuna yol açmaz; yapabilir ve sık sık gerekir. Platform bir Arduino olduğunda, bu sorunun cevabının dil düzeyinde olmadığı, ancak platformda mantıklı olan tasarım kalıplarında ve küreleri arzu edip etmediklerinde farklılık gösterebilir.
katma yazar Not that Charles, kaynak
@Muzer huh, her zaman İşlem olduğunu sanıyordum. TIL
katma yazar Sonic Splasher, kaynak
Statik ve global değişkenler, derleme zamanında hafıza tüketimini bilme avantajını sunar. Çok sınırlı hafızaya sahip bir arduino ile bu bir avantaj olabilir. Bir aceminin mevcut hafızayı tüketmesi ve takip edilemeyen arızalar yaşaması oldukça kolaydır.
katma yazar mgpugne, kaynak
Hey Hepsi: Bu beklenenden daha popüler oldu. Son 9 ayda çok şey öğrendim ve bunu "diğer benler" için mümkün olduğunca faydalı yapmak istiyorum. Bu yazıyı yeni başlayanlar için kodumu geliştirmeme yardımcı olan derslere/fikirlere bağlantı ekleyerek eklersem insanlar memnun olur mu? Borsa kurgusu konusunda% 100 hala emin değilim, bu yüzden 1. sormam gerektiğini düşündüm.
katma yazar cocco, kaynak

8 cevap

Onlar kendi başlarına şeytan değildir, ancak onları kullanmak için iyi bir neden olmayan yerlerde aşırı kullanma eğilimindedirler.

Global değişkenlerin avantajlı olduğu birçok zaman vardır. Özellikle, bir Arduino programlama, kaputun altında, bir PC'nin programlanmasından oldukça farklıdır.

Küresel değişkenlere en büyük fayda statik tahsisattır. Özellikle sınıf örnekleri gibi büyük ve karmaşık değişkenlerle. Kaynak yetersizliği nedeniyle dinamik ayırma ( new vb. Kullanımı) kaşlarını çattı.

Ayrıca normal bir C programında yaptığınız gibi tek bir çağrı ağacı almazsınız (tek main() işlevi, diğer işlevleri çağırır) - bunun yerine iki ayrı ağacı etkin bir şekilde elde edersiniz ( setup() çağıran işlevler, ardından loop() çağıran işlevler), bu da bazen genel değişkenlerin hedefinize ulaşmanın tek yolu olduğu anlamına gelir (yani, her ikisini de içinde kullanmak istiyorsanız setup() ve loop() ).

Yani hayır, onlar kötü değiller ve bir Arduino'da bir PC'dekinden daha fazla ve daha iyi kullanıyorlar.

26
katma
Doğru, çok hızlı bir şekilde gözden kaçtım ve sınıfların kullanılmaması ile ilgili soruların bazılarını karıştırdım.
katma yazar JaanusSiim, kaynak
Sınıflar yığınla tahsis edilebilir. Kuşkusuz, yığına büyük örnekler koymak iyi değil, ama yine de.
katma yazar JaanusSiim, kaynak
@JAB Her şey tahsis edilmiş yığın olabilir.
katma yazar Majenko, kaynak
Bu durumda muhtemelen bunları döngüde() (değerlerini yinelemeler arasında tutmaları gerekiyorsa, gerekirse statik olarak) tanımlar ve onları çağrı zincirindeki işlev parametrelerinden geçirirdim.
katma yazar Majenko, kaynak
Bu bir yol ya da referans olarak iletmek: void foo (int & var) {var = 4; } ve foo (n); - n şimdi 4'tür.
katma yazar Majenko, kaynak
Global değişkenlerden kaçınmak için duyduğum nedenlerden birinin Arduino dışındaki bir sistemle ilgisi var, Global değişkenler programın dışına veya dışına maruz kalabilir. Bu C ++ ifadesi en iyisini ifade eder. "C dili global bir anahtar kelimeye sahip değil. Bir işlevin dışında bildirilen değişkenlerin" dosya kapsamı "var, yani dosya içinde görünürler." Bu, dosya değişken alanının çalıştırılmadan önce düzenlenebildiği statik durumlarda olduğu gibi, çalıştırmadan önce program kapsamı dışında değiştirilen değişken alanını gösterir ve potansiyel güvenlik riskleri yaratır
katma yazar Clems, kaynak
Tamam, sanırım bunu yapabilirim. Eğer (örneğin) statik var n loop() 'da tanımlanmışsa. n foo (var) ' a ve foo (var) 'a iletersem n = [yeni değer] . [yeni değer] 'i geri döndürmem ve loop() ' da n = [yeni değer] 'a sahip olmam gerekir mi?
katma yazar cocco, kaynak
Tamam, ya sadece loop() 'da (ya da loop() ' da adı geçen birden fazla işlevde) kullandığım bir şeyse? Onları başlangıçta tanımlamaktan farklı bir şekilde kurmak daha iyi olur mu?
katma yazar cocco, kaynak
setup() ve loop() arasında iletişim kurulamaması, kendi başına, daha standart bir araç kullanmak ve iyi bir eski kullanmak için mükemmel bir nedendir. main() veya _main() giriş noktası.
katma yazar Megatron, kaynak

Mesajınızı görmeden kesin bir cevap vermek çok zordur. gerçek kod

Global değişkenler kötü değildir ve çoğu zaman gömülü bir anlam ifade ederler. genellikle çok fazla donanım erişimi yaptığınız ortam. Var sadece dört UARTS, sadece bir I2C portu, vs. Belirli donanım kaynaklarına bağlı değişkenler için küresel. Ve gerçekten, Arduino çekirdek kütüphanesi şunları yapar: Seri , Seri1 , vb. değişkenler. Ayrıca, programın global durumunu temsil eden bir değişken genellikle bir küreseldir.

Şu anda yaklaşık 1100 satır [kod] için 46 küreselim var. Bu bir   iyi oran [...]

Sayılarla ilgili değil. Kendine sorman gereken doğru soru, Bu küresellerin her biri için, küresel olarak sahip olmanın bir anlamı var mı? kapsamı.

Yine de, 46 küresel bana biraz yüksek görünüyor. Bunlardan bazıları sabit kalırsa değerleri, bunları const olarak nitelendirin: derleyici genellikle en iyi duruma getirecektir depoları. Bu değişkenlerden herhangi biri sadece bir tek içinde kullanılıyorsa işlevi, yerel hale getirin. Değerinin çağrılar arasında kalmasını istiyorsanız işleve statik olarak nitelendirin. Ayrıca azaltmak değişkenleri bir arada gruplandırarak "görülebilir" globals sayısı sınıf ve bu sınıfın bir küresel örneğine sahip olmak. Ama sadece bunu ne zaman bir şeyler koymak mantıklı. Büyük bir GlobalStuff sınıfı oluşturma Çünkü tek bir küresel değişkene sahip olmak uğruna, kod temizleyici.

16
katma
Hayır. static yalnızca değeri korumanız gerektiğinde içindir. İşlevde yaptığınız ilk şey, değişkenin değerini geçerli zamana ayarlanmışsa, eski değeri tutmaya gerek yoktur. Tüm bu statik olan bu durumda bellek harcıyor.
katma yazar Phil Hannent, kaynak
Bu, her iki noktayı da genel olarak lehine ve şüphecilikleriyle ifade eden çok yönlü bir cevaptır. +1
katma yazar Not that Charles, kaynak
Tamam, açıklama için teşekkürler.
katma yazar cocco, kaynak
Tamam! Yalnızca bir işlevde kullanılan bir değişkenim varsa, ancak işlev her çağrıldığında yeni bir değer alırsam statik hakkında bir şey bilmiyordum ( var = millis() ) bunu statik yapmalı mıyım?
katma yazar cocco, kaynak

Global değişkenlerle ilgili ana sorun kod bakımıdır. Bir kod satırı okurken, parametre olarak iletilen veya yerel olarak bildirilen değişkenlerin bildirimini bulmak kolaydır. Global değişkenlerin bildirimini bulmak çok kolay değil (çoğu zaman gerektirir ve IDE).

Çok sayıda global değişkeniniz olduğunda (40 zaten çoktur), çok uzun olmayan açık bir isme sahip olmak zorlaşır. Ad alanını kullanmak, global değişkenlerin rolünü netleştirmenin bir yoludur.

C'deki ad alanlarını taklit etmenin kötü bir yolu:

static struct {
    int motor1, motor2;
    bool sensor;
} arm;

İntel veya arm işlemcide, global değişkenlere erişim diğer değişkenlerden daha yavaştır. Muhtemelen Arduino'nun tam tersi.

5
katma
AVR'de globaller RAM'de bulunurken, statik olmayan çoğu yerel CPU işlemcilere ayrılır ve bu da erişimini daha hızlı hale getirir.
katma yazar Sprogz, kaynak
Sorun, gerçekte beyanı bulmak değil; Kodun hızlı bir şekilde anlaşılması önemli ancak sonuçta ne olduğuna ikincildir - ve burada asıl sorun, kodunuzun bilinmeyen bir kısmının tuhaf yapmak için genel bildirgeyi kullanabildiği hangi varyasyonun bulunmasıdır. Açık bıraktığınız bir nesneyi olan şeyler, herkesin istediği şeyi yapması için açık.
katma yazar Not that Charles, kaynak

Bir PC için programlama yaparken bunları kullanmamama rağmen, Arduino için bazı avantajları var. Çoğu zaten söylenmişse:

  • Dinamik bellek kullanımı yok (bir Arduino'nun sınırlı yığın alanında boşluklar oluşturma)
  • Her yerde kullanılabilir, bu nedenle bunları argüman olarak iletmenize gerek yoktur (bu, yığın alanını giderir)

Ayrıca, bazı durumlarda, özellikle performans açısından, gerektiğinde öğeler oluşturmak yerine genel değişkenleri kullanmak iyi olabilir:

  • Yığın alanındaki boşlukları azaltmak için
  • Dinamik olarak bellek ayırmak ve/veya serbest bırakmak çok uzun zaman alabilir
  • Değişkenler, birçok nedenden dolayı kullanılan bir küresel listenin öğelerinin bir listesi gibi, örneğin, yeniden kullanılabilir. SD için bir kez arabellek olarak, daha sonra da geçici bir dize arabellek olarak.
5
katma

Her şeyde olduğu gibi (gerçekten kötülükten uzak olanların dışında) küresellerin kendi yerleri vardır.

Örneğin. Her yerde yazabilmeniz için gereken bir hata ayıklama seri bağlantı noktasına veya bir günlük dosyasına sahipseniz, bunu global hale getirmek genellikle mantıklı olur. Benzer şekilde, kritik bir sistem durumu bilgisine sahipseniz, bunu global hale getirmek genellikle en kolay çözümdür. Programdaki her bir işleve geçmeniz gereken bir değere sahip olmanın bir anlamı yoktur.

Diğerlerinin dediği gibi, 46 sadece 1000'den fazla kod satırı için çok görünüyor, fakat ne yaptığınızla ilgili ayrıntıları bilmeden, fazla kullanıp kullanmadığınızı söylemek zor.

Ancak her küresel için kendinize birkaç önemli soru sorun:

Ad açık ve belirli mi, bu nedenle yanlışlıkla aynı adı başka bir yerde kullanmayı denemem mi? Adı değiştirmediyse.

Bunun hiç değişmesi gerekiyor mu? Eğer değilse o zaman bir const yapmayı düşünün.

Bunun her yerde görünmesi gerekiyor mu, yoksa değer işlev çağrıları arasında korunacak şekilde yalnızca küresel mi olacak? Bu nedenle, işlev için yerel yapmayı ve statik anahtar sözcüğünü kullanmayı düşünün.

Dikkatli olmadığımda bir kod tarafından değiştirilirse işler gerçekten kötü bir şekilde batırır mı? Örneğin. Eğer iki ilişkili değişkeniniz varsa, genel olan isim ve kimlik numaralarını söyleyin (bu, neredeyse her yerde bazı bilgilere ihtiyaç duyduğunuzda global kullanımıyla ilgili önceki nota bakınız), o zaman bir tanesi diğer kötü şeyler olmadan değişebilirse. Evet, sadece dikkatli olabilirsiniz ama bazen biraz dikkatli olmanız iyi olur. örneğin, onları farklı bir .c dosyasına yerleştirin ve ardından ikisini de aynı anda ayarlayan ve bunları okumanıza izin veren işlevleri tanımlayın. Daha sonra sadece ilişkili başlık dosyasına işlevleri dahil edersiniz, bu şekilde kodunuzun geri kalanı yalnızca tanımlanmış işlevler aracılığıyla değişkenlere erişebilir ve bu yüzden işleri karıştırmaz. Bu, temelde, bir c ++ sınıfının izin verdiği şeyi yapmanın saf bir yoludur, ancak sınıfları nasıl tanımlayacağınızı ve yaratacağınızı öğrenmek zorunda kalmadan bir kerede çok fazla öğrenmemeniz gerekir.

- güncelleme - Sadece genel kodlama yerine Arduino'ya özgü en iyi uygulama hakkında sorular sorduğunuzu fark ettim ve bu daha genel bir kodlama yanıtı. Ama dürüst olmak gerekirse, çok fazla fark yok, iyi uygulama iyi uygulama. Arduino'nun startup() ve loop() yapısı, bazı durumlarda küreselleri diğer platformlardan biraz daha fazla kullanmanız gerektiği anlamına gelir, ancak bu durum pek değişmez. platformun sınırları ne olursa olsun, platformun sınırları dahilinde yapabileceğiniz en iyisini hedefliyorsunuz.

4
katma
goto 'nın kötü olduğunu düşünüyorsanız, Linux kodunu kontrol edin. Muhtemelen, tıpkı try ... catch blokları kadar kötüler.
katma yazar nreich, kaynak
Arduinos hakkında hiçbir şey bilmiyorum ama çok fazla masaüstü ve sunucu geliştirme yapıyorum. goto s için kabul edilebilir bir kullanım (IMHO) var ve bu da yuvalanmış döngülerden kopuyor, alternatiflerden daha temiz ve kolay anlaşılıyor.
katma yazar sagelynaive, kaynak

Onlar kötülük mü? Olabilir. Globals ile ilgili sorun, herhangi bir zamanda, herhangi bir zamanda, herhangi bir fonksiyon ya da kod parçası tarafından, kısıtlama olmaksızın, erişilebilmesi ve değiştirilebilmesidir. Bu, izini sürdürebilmek ve açıklamak zor diyelim, diyelim. Bu nedenle, mümkünse sıfıra geri getirerek küresel miktarının en aza indirilmesi arzu edilir.

Kaçınılabilirler mi? Neredeyse her zaman evet. Arduino'nun sorunu, sizi setup() ve siz loop() olarak kabul ettikleri bu iki işlev yaklaşımına zorlamalarıdır. Bu özel durumda, bu iki işlevin arayan işlevinin kapsamına erişemezsiniz (muhtemelen main() ). Elinizde olsaydı, kendinizi tüm kürelerden kurtarabilir ve bunun yerine yerlileri kullanabilirsiniz.

Aşağıdakileri hayal edin:

int main() {
  setup();

  while (true) {
    loop();
  }
  return 0;
}

Bu muhtemelen bir Arduino programının temel işlevinin neye benzediğidir. Hem setup() hem de loop() işlevinde ihtiyacınız olan değişkenler daha sonra tercihen main() işlevinin kapsamında bildirilir. küresel kapsamdan ziyade. Daha sonra argüman olarak geçirerek (gerekirse işaretçiler kullanarak) diğer iki fonksiyona erişilebilir hale getirilebilirler.

Örneğin:

int main() {
  int myVariable = 0;
  setup(&myVariable);

  while (true) {
    loop(&myVariable);
  }
  return 0;
}

Bu durumda, her iki fonksiyonun imzasını da değiştirmeniz gerektiğini unutmayın.

Bu mümkün veya arzu edilmeyebileceği için, zorlanan program yapısını değiştirmeden Arduino programından çoğu kürenin çıkarılmasının sadece bir yolunu görüyorum.

Doğru hatırlıyorsam, C yerine Arduino için programlama yaparken C ++ 'ı mükemmel bir şekilde kullanabiliyorsunuz (henüz) OOP (Nesneye Yönelik Programlama) veya C ++, biraz alışmak ve biraz okumak alabilir.

Teklifim bir Program sınıfı oluşturmak ve bu sınıfın tek bir küresel örneğini oluşturmak olacaktır. Bir sınıf, nesnelerin planı olarak düşünülmelidir.

Aşağıdaki örnek programı göz önünde bulundurun:

class Program {
public:      
  Program();

  void setup();
  void loop();

private:
  int myFirstSampleVariable;
  int mySecondSampleVariable;
};

Program::Program() :
  myFirstSampleVariable(0),
  mySecondSampleVariable(0)
{

}

void Program::setup() {
 //your setup code goes here
}

void Program::loop() {
 //your loop code goes here
}

Program program;//your single global

void setup() {
  program.setup();
}

void loop() {
  program.loop();
}

Voilà, kendimizi hemen hemen tüm dünyalardan kurtardık. Uygulama mantığınızı eklemeye başlayacağınız işlevler Program :: setup() ve Program :: loop() işlevleri olur. Bu işlevler, myFirstSampleVariable ve mySecondSampleVariable örneğine özgü üye değişkenlerine erişirken, geleneksel setup() ve loop() işlevler erişemez, çünkü bu değişkenler özel sınıf olarak işaretlenir. Bu kavram veri kapsülleme veya veri gizleme olarak adlandırılır.

Size OOP ve/veya C ++ 'ların öğretilmesi, bu sorunun cevabının kapsamı dışında olduğundan, burada duracağım.

Özetlemek gerekirse: kürelerden kaçınılmalı ve küreler miktarını büyük ölçüde azaltmak neredeyse her zaman mümkün. Ayrıca Arduino için programlama yaparken.

En önemlisi, cevabımın sizin için biraz faydalı olduğunu umuyorum :)

3
katma
Eh, hala programın herhangi bir yerine ulaşılabilen küresel bir durumdur, yalnızca globalProgram.setup() Program :: example (). Setup() üzerinden erişirsiniz. >. İlgili global değişkenleri bir sınıfa/yapıya/isim alanına koymak, özellikle de birkaç ilgili işlev tarafından gerekli olmaları durumunda faydalı olabilir, ancak singleton düzeni bir şey eklemez. Başka bir deyişle, statik Program p; genel depolama alanına sahiptir ve statik Program & example() , basitçe Program globalProgram; .
katma yazar Tomas Andrle, kaynak
Bir singleton etkili bir şekilde küresel, sadece kafa karıştırıcı bir şekilde giyinmiş. Aynı olumsuz tarafları vardır.
katma yazar Tomas Andrle, kaynak
İsterseniz eskizde kendi main'inizi() tanımlayabilirsiniz. Bu hisse senedi şöyle görünür: github.com/arduino/Arduino/blob/1.8.3/hardware/arduino/avr/…
katma yazar per1234, kaynak
@patstew Nasıl aynı dezavantajlara sahip olduğunu düşündüğünüzü açıklar mısınız? Kanımca veri kapsüllemesi kullanabildiğinize göre bence değil.
katma yazar gebeyaw, kaynak
@ per1234 Teşekkürler! Kesinlikle Arduino uzmanı değilim, ancak ilk önerimin o zaman da işe yarayacağını düşünüyorum.
katma yazar gebeyaw, kaynak
@patstew Ben böyle düşünmedim. Bence sen haklısın. Gönderimi değiştireceğim. Anlamak daha kolay hale getirecek.
katma yazar gebeyaw, kaynak
@ Graham Ne tür bir disiplinden bahsettiğinizi merak ediyorum? Sanırım neden bahsettiğin hakkında bir fikrim var ama disiplin 'iyi kapsüllenmiş kod' yaratmayacak. Accessor/mutator modeli, kodunuzu nasıl ayarladığınıza bağlı olarak bazen küçük bir performans maliyeti ile birlikte gelir. Bununla birlikte, bir çok pahalı işlem bir derleyici tarafından optimize edilebilir.
katma yazar gebeyaw, kaynak
Uzun süredir gömülü bir kodlayıcı olarak, düzenli olarak "Global Variables Bad" ın döküm kuralından insanları () eğitmem gerekiyor. Her zaman argümanları geçmek kodu yavaşlatır. Bir bilgisayarda bu oldukça önemsiz, ancak gömülü dünyada bu hala çok büyük bir mesele. Erişimci/mutator modeli, işlem süresi pahasına ses kapsüllemesini garanti etmenin bir yoludur. Genel değişkenlere sahip kapsüllenmiş bir kod yazmak mükemmel bir şekilde mümkündür - ancak disiplini nasıl tasarladığınıza ve başkalarının nasıl kullanması gerektiğini açıkça belirtmeniz gerekir.
katma yazar Maxim Krizhanovsky, kaynak

Genel değişkenler hiçbir zaman kötü değildir . Onlara karşı genel bir kural, daha iyi kararlar verebilmeniz için tecrübe kazanmanız için yeterince uzun süre hayatta kalmanıza izin veren bir engeldir.

Global bir değişken ne demek, bir şeyin yalnızca birinin olduğuna dair içsel bir varsayımdır (birden fazla şey içerebilecek global bir dizi veya haritadan bahsetmiş olmamızın bir önemi yoktur, yine de sadece olduğu varsayımını içerir) biri böyle bir liste veya haritalama ve birden fazla bağımsız olanlar değil).

Yani bir küreselden faydalanmadan önce kendinize sormak istersiniz: bu şeyden daha fazlasını kullanmak isteyeceğim düşünülebilir mi? Çizgide doğru olduğu ortaya çıkarsa, bu şeyi genelleştirmek için kodu değiştirmeniz gerekecektir ve muhtemelen kodunuzun diğer bölümlerinin bu benzersiz varsayımlara dayandığı yol boyunca bulursunuz. Onları da düzeltmek zorunda kalacağım ve süreç sıkıcı ve hataya açık hale geliyor. “Globals kullanmayın” öğretilir çünkü genel olarak globals'ı baştan korumak için oldukça küçük bir maliyettir ve daha sonra büyük bir maliyet ödemek zorunda olma potansiyelinden kaçınır.

Ancak, küresellerin sağladığı basitleştirici varsayımlar, kodunuzu daha küçük, daha hızlı hale getirir ve daha az bellek kullanır, çünkü kullandığı şeyin nosyonunu dolaşmak zorunda değildir, dolaylı olarak yapmak zorunda değildir. İstediğiniz şeyin belki de mevcut olmaması ihtimalini göz önünde bulundurun, vb. Yerleşik olarak, bir PC'de olduğundan daha büyük kod boyutuna ve/veya CPU zamanına ve/veya belleğine sahip olma ihtimaliniz daha düşüktür, bu nedenle bu tasarruf önemli olabilir. Ayrıca birçok gömülü uygulama gereksinimlerinde daha fazla sağlamlığa sahiptir - çipinizin yalnızca belirli bir çevre biriminden birine sahip olduğunu bilirsiniz , kullanıcı bir USB portuna veya başka bir şeye başka bir fiş takamaz.

Eşsiz görünen bir şeyden daha fazlasını istemek için başka bir yaygın neden test yapmaktır - iki bileşen arasındaki etkileşimi test etmek, bir bileşenin test örneğini bir işleve geçirebiliyorken kolaydır, oysa global bir bileşenin davranışını değiştirmeye çalışmaktır. daha zor bir teklif. Fakat gömülü dünyadaki testler başka yerlerden çok farklı olma eğilimindedir, bu yüzden bu sizin için geçerli olmayabilir. Bildiğim kadarıyla Arduino'nun hiçbir test kültürü yok.

Öyleyse devam edin ve değerli göründüğü zaman küreler kullanın. Polis polisi gelip seni almaz. Yanlış seçimin senin için yolun üstünde daha fazla işe neden olabileceğini bil, bu yüzden emin olmazsan ...

2
katma

Arduino'da Küresel Değişkenler Kötü mü?

Global değişkenler dahil hiçbir şey içsel olarak kötü değildir. Bunu "gerekli bir kötülük" olarak nitelendiriyordum - hayatınızı çok daha kolaylaştırabilir ancak dikkatle yaklaşılması gerekir.

Ayrıca, küresel sayısını daha da azaltmak için hangi uygulamaları kullanabilirim?

Global değişkenlerinize erişmek için sarmalayıcı işlevlerini kullanın. bu yüzden en azından kapsam perspektifinden yönetiyorsunuz.

0
katma
Genel değişkenlere erişmek için sarmalayıcı işlevlerini kullanırsanız, değişkenlerinizi bu işlevlerin içine de koyabilirsiniz.
katma yazar nreich, kaynak