Switch Case sorusu

Başlatan baran123, 25 Ağustos 2015, 21:04:38

baran123

main
{
init();

while(1)
{
}

}

init()
{
state = 0;

swtich(state)
{
case 0 : state = 1; break;
case 1 : state = 2; break;
...
}
}

Case 1 işlenir mi ? yoksa 0 işlenip state 1 yapılsa bile break olduğu için döngü biter mi ?

Tagli

İşlenmez. Yani kod case 1: içine girmez, init'ten çıkıp yoluna devam eder.
Gökçe Tağlıoğlu

muhittin_kaplan

fonksiyondan çıkarsın. 1 işletilmez

baran123

Denedim işlenmiyormuş.Teşekkürler.

magnetron

bu yapının aynısı VB de de var
orda "select case" şeklinde

yalnız bende case ler çok fazla yaklaşık 50 tane

benim merak ettiğim acaba uygun yani o an aranan case 'i bulana kadar
mesela ben o anda diyelim case "z" arıyorum

"z" yi bulana kadar "a" "b" "c" ..... hepsini tarıyor mu ?
çünkü benim programda bir interpreter çalışıyor yani sürekli komut satırlarını tarayıp uygun case i çalıştırıyor
ve bilgisayar çok yavaşlıyor
bu arada bendeki sürüm VB 6.0

baran123

#5
@magnetron
Evet tahminimce tarıyordur.Çünkü yazılım akışı yukarıdan aşağıya doğru olduğundan sizin z yi bulabilmesi için hepsine sıra ile bakması lazım.Daha performanslı bir kullanım için değerlerinizin ayır edici bir özelliği olması gerekir.Belki farklı algoritmalar vardır.
Mesela
void yiyecekBul(yiyecek)
{
    switch(yiyecekler)
    {
        case meyveler: 
            switch(meyve)
            {
                case elma:  break;
                case armut: break;
            }
        break;

        case sebzeler:
            switch(sebze)
            {
                case domat:  break;
                case pattes: break;
            }
        break;
    }
}

void yiyecekBul(yiyecek)
{
   switch(yiyecekler)
   {
       case elma:   break;
       case armut:  break;
       case domat:  break;
       case pattes: break;
   }
}

Komik bir örnek oldu :D

MrDarK

Büyük olasılıkla case sıralaman nereden başlıyorsa en üstte ondan itibaren bakıyor. Fakat şöyle bir not ekleyeyim bende buraya;

kod alanı az kaldığı için case mantığının fazla kod alanı yediğini düşünerek aynı şeyleri if else if lerle yazdığımda daha fazla kod alanı tuttuğunu bildireyim :) Yani switch case kullanımı daha az yer kapladı. Derleyici ARM GCC
Picproje Eğitim Gönüllüleri ~ MrDarK

sadogan

#7
Emin deyilim ama ilgili case adresini hesaplayıp direk oraya gider diye düşünüyorum.
8051 de bile dptr+a komutu vardı.
Hatta 16f819 için bir zamanlar asm yazdığım case yapısı söyle
CALL	CEKBUTON
	MOVF	TEMP,W
	ADDWF	PCL,F
	GOTO	NORMAL_MOD		;0
	GOTO	AYAR_MOD		;1
	GOTO	EKSILT			;2
	GOTO	AYAR_DEGERI_GOSTER	;3 
	GOTO	ARTIR			;4
	GOTO	TABLA_GOSTER		;5
	GOTO	AYAR_MOD_GOSTER	;6
	GOTO	NORMAL_MOD		;7

NORMAL_MOD				;0
	CALL	NORMAL_MOD_RUTINI
	GOTO   	LOOP
		
AYAR_MOD				;1
	CALL	 AYAR_MOD_GOSTER_RUTINI ;*
	GOTO   	LOOP

EKSILT					;2
	CALL	EKSILT_RUTINI
	GOTO   	LOOP

AYAR_DEGERI_GOSTER			;3
	CALL	AYAR_DEGERI_GOSTER_RUTINI
	GOTO   	LOOP
ARTIR					;4
	CALL	ARTIR_RUTINI
	GOTO   	LOOP

TABLA_GOSTER				;5
	CALL	TABLA_GOSTER_RUTINI	
	GOTO   	LOOP
AYAR_MOD_GOSTER
	CALL	AYAR_MOD_GOSTER_RUTINI	;6
	GOTO	LOOP				
					;7

Gökhan BEKEN

#8
@magnetron hocam bunun için farklı bir yöntem önereyim, fonksiyon gösterici denen bir olay var.
Bu konuda bir yazı yazmıştım: http://gokhanbeken.com/cc-fonksiyon-gostericilerifonksiyonu-adresi-ile-cagirmak

mesela sizin case'inize 0 ila 255 arasında toplam 256 çeşit veri giriyor, bunların her birinde farklı bir fonksiyon var.
Yani şöyle:
state = 255;
swtich(state)
{
   case 0 : islem0(); break;
   case 1 : islem1(); break;
   ...

   case 254 : islem254(); break;
   case 255 : islem255(); break;

   ...
}

Yukarıdaki örnekte 255'inciyi bulana kadar bütün hepsini taramak zorunda kalacak.

Oysa aşağıdaki yapıda böyle birşeye gerek yok:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>


void islem0(void);
void islem1(void);
void islem2(void);
void islem3(void);
void islem4(void);
void islem5(void);
void islem6(void);
void islem7(void);
void islem8(void);
void islem9(void);

void (*fonksiyon_cagir)(void);

void* fonksiyonAdresleri[10]; //fonksiyonlarin pointer adreslerini tutan dizi
unsigned char state = 8;

int main(int argc, char *argv[]) {
	
	//fonksiyonlarin adreslerini bir kereye mahsus diziye atiyoruz:
	fonksiyonAdresleri[0]=&islem0;
	fonksiyonAdresleri[1]=&islem1;
	fonksiyonAdresleri[2]=&islem2;
	fonksiyonAdresleri[3]=&islem3;
	fonksiyonAdresleri[4]=&islem4;
	fonksiyonAdresleri[5]=&islem5;
	fonksiyonAdresleri[6]=&islem6;
	fonksiyonAdresleri[7]=&islem7;
	fonksiyonAdresleri[8]=&islem8;
	fonksiyonAdresleri[9]=&islem9;
	

	
	
	fonksiyon_cagir=fonksiyonAdresleri[state];
	

	for(state=0;state<10;state++){
		fonksiyon_cagir=fonksiyonAdresleri[state];
		fonksiyon_cagir();
	}
	
	
	printf("\r\n");
  	return 0;
}

void islem0(void){printf("fonksiyon 0 \r\n");}
void islem1(void){printf("fonksiyon 1 \r\n");}
void islem2(void){printf("fonksiyon 2 \r\n");}
void islem3(void){printf("fonksiyon 3 \r\n");}
void islem4(void){printf("fonksiyon 4 \r\n");}
void islem5(void){printf("fonksiyon 5 \r\n");}
void islem6(void){printf("fonksiyon 6 \r\n");}
void islem7(void){printf("fonksiyon 7 \r\n");}
void islem8(void){printf("fonksiyon 8 \r\n");}
void islem9(void){printf("fonksiyon 9 \r\n");}


mesaj birleştirme:: 25 Ağustos 2015, 23:54:27

Bu da ekran görüntüsü
Özel mesaj okumuyorum, lütfen göndermeyin.

Tagli

Konu hakkında pek bilgim yok ama bana da mantıklı gelen sadogan'ın anlattığı gibi olması. Yoksa zaten switch-case kullanmak için bir neden kalmazdı, çünkü if-else daha esnek bir yapı. "Computed Goto" yöntemiyle karşılaştırma ile zaman kaybetmeden doğrudan atlama yapılabilir. Ancak, süreksiz girdilerde bu iş nasıl yapılıyor onu aklımda canlandıramadım. Mesela case'ler 1, 2, 3 değil de 23, 45, 100 olsa acaba tablo boş mu bırakılıyor yoksa başka bir yöntem mi var? Boş tablo bilgisayarda sorun olmaz ama belleği sınırlı gömülü sistemler için iyi bir yaklaşım olmaz.
Gökçe Tağlıoğlu

z

ASM yazımda bu işlemi JMP tabloları ile yapıyoruz ve bu tablolarda Jump adresini seçen girdiler birbirini takip edecek veriler olmak zorunda.
Biz sadece en son adresin ötesinde değer gelip gelmediğini test ediyoruz. Değer bu değerden küçükse jmp tablsundan sıçramaya izin veriyoruz.

Programı yazarken buna dikkat ediyoruz. Eğer dinamik bir tablo olmayacaksa yani jmp adresleri program içinde değiştirilmeyecekse tabloları ramda değil romda tutuyoruz.
Bana e^st de diyebilirsiniz.   www.cncdesigner.com

magnetron

@Gökhan hocam

C 'de function pointer var - kullanıyorum da

ama ilk mesajda belirttiğim gibi bana VB 6.0 da lazım

muhittin_kaplan

hocam ben kavrayamadım tam istediğinizi, biraz daha açık yazarmısınız ?
(select case in daha efektif bir halini mi arıyorsunuz vb de ? )

magnetron

@muhittin hocam

diyelim VB 6.0 'da şöyle bir kodumuz  var

    Select Case var
    Case "A"
    -----------------
    Case "B"
    ------------------
    Case "C"
    -----------------
    -----------------
    -----------------
    -----------------
   Case "Z"
   ------------------
  End Select

bu select case kodunu kısaltmalardan oluşan
bir text dosyası çalıştırıyor

mesela şöyle

A   ... buraya bir parametre giriyor ve "A" case'i bu parametreyi alıp onunla bişey yapıyor
C   ...
Z   ...
Y   ...
G   ...
J    ...
M   ...
END

PLC 'lerin STL dilini biliyorsanız onun gibi bişey

bu text dosyası sürekli bir şekilde baştan sona işleniyor

işte problem burda başlıyor

benim tahminin VB 6.0 text dosyasından her satırı alıp
select case kodunun içinde o satırdaki emir "A" veya "H" veya "Y" neyse
onu arıyor

işte benim tahminim "A" emrini hemen buluyor "Y" emrini bulmak için
bütün select case kodunu sonuna kadar tarıyor

bu da bilgisayarı çok yavaşlatıyor

250 - 300 satırlık bu text dosyasını işlerken en baba Intel core işlemci bayılıyor
saniyede 20 scan 'e düşüyor

ben de bu tartışmayı görünce bu problemi sormak istedim

VB 6.0 da buna bir çare var mı diye
yani C dilindeki @Gökhan hocamın bahsettiği function pointer gibi

Gökhan BEKEN

Doğrudan çözüm olmasa bile C dilinde yazılmış bir DLL işinizi görecektir.
Ben işlemciyi yoracak her işi C dilinde yazdığım DLL ile yaparım. Pointer ihtiyacı olan projelerde de aynısını yaparım.
Özel mesaj okumuyorum, lütfen göndermeyin.