Switch Case sorusu

Başlatan baran123, 26 Ağustos 2015, 00:04:38

baran123

Kod Seç

main
{
init();

while(
1)
{
}

}

init()
{
state 0;

swtich(state)
{
case 
state 1; break;
case 
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 ?
İdrak i meali bu küçük akla gerekmez, zira bu terazi bu kadar sıkleti çekmez.

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.
İdrak i meali bu küçük akla gerekmez, zira bu terazi bu kadar sıkleti çekmez.

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

26 Ağustos 2015, 02:21:42 #5 Son düzenlenme: 26 Ağustos 2015, 02:30:43 Baran Ekrem
@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
Kod Seç

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
İdrak i meali bu küçük akla gerekmez, zira bu terazi bu kadar sıkleti çekmez.

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

26 Ağustos 2015, 02:25:22 #7 Son düzenlenme: 26 Ağustos 2015, 02:36:46 sadogan
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
Kod Seç

	
CALL
	
CEKBUTON
	
MOVF
	
TEMP,W
	
ADDWF
	
PCL,F
	
GOTO
	
NORMAL_MOD
	
	
;
0
	
GOTO
	
AYAR_MOD
	
	
;
1
	
GOTO
	
EKSILT
	
	
	
;
2
	
GOTO
	
AYAR_DEGERI_GOSTER
	
;

	
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

26 Ağustos 2015, 02:52:31 #8 Son düzenlenme: 26 Ağustos 2015, 02:54:27 Gökhan BEKEN
@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:
Kod Seç
state 255;
swtich(state)
{
   case 
islem0(); break;
   case 
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:
Kod Seç

#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);

voidfonksiyonAdresleri[10]; //fonksiyonlarin pointer adreslerini tutan dizi
unsigned char state 8;

int main(int argcchar *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:: 26 Ağustos 2015, 02: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.

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.