Picproje Elektronik Sitesi

BİLGİSAYAR => Donanım ve Yazılım => Konuyu başlatan: Klein - 21 Haziran 2013, 03:07:21

Başlık: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: Klein - 21 Haziran 2013, 03:07:21

int void ( int *x)
{
     return( *x +5);
}


Yukarıdaki gibi pointer parametre alan bir fonksiyona. Nasıl sabit değer geçebilirim?
Sabit değerden kasıt bir adres  değil. Doğrudan değer geçmekten bahsediyorum.
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: fatih6761 - 21 Haziran 2013, 03:29:57
Hocam biraz daha açar mısınız? Girdi-çıktı ne olacak mesela? Örnek verebilir misiniz?
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: yilmaz_kk - 21 Haziran 2013, 08:29:17
&degisken

gibi birşeyden bahsetmiyorsunuz sanırım. Biraz daha açarsanız yardımcı olmaya çalışırız.
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: polleme - 21 Haziran 2013, 08:29:42
örneğin fonksiyon f olsun. Eğer fonksiyonunuz

void f(int *p) {
   *p = 1;
   return *n;
}

şeklinde ise buna sabit değer geçmek için fonksiyon şu şekilde çağrılır:

int main() {
   int x = 20;
   f(&a);
}



mesaj birleştirme:: 21 Haziran 2013, 08:31:08

fonksiyon içi return *p; olacaktı.
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: Klein - 21 Haziran 2013, 13:52:12
Biraz daha açayım.
Fonksiyonumuz bu.

int topla ( int *x)
{
     return( *x +5);
}



Bunu şu şekilde çağırırız. Sorun yok.

int a = 3;
int b;

b = topla(&a);


sonucumuz 8 oldu.

Ama ben bunu bazen yukarıda olduğu gibi, bir değişkenin adresi ile, bazen de  doğrudan 3 sayısı ile çağırmak istiyorum.

int b;

b = topla(& 3); // tabi bu şekilde çağıramıyoruz. Aradığım şey bu fonksiyona doğrudan 3 değerini geçmek.


Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: polleme - 21 Haziran 2013, 13:54:29
Böyle birşey hiç görmedim, yapılamayacağını tahmin ediyorum.
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: Klein - 21 Haziran 2013, 14:17:56
Aslında esas asru bu değil. Basitleştirmek için böyle yazdım.
Esas soru şu.


typedef struct
{
char *Header[3];
char *format;
void *Register;
void *MinVal;
void *MaxVal;
uint16_t (*EditorType)(uint16_t);
uint16_t (*ParentMenu)(uint16_t);
uint16_t (*SubMenu)(uint16_t);

}Menu_Type;


const Menu_Type SubMenu [] =
{
{{"Alarmlar\0","Alarmlas\0","Alarme\0"}, "%s",(uint16_t *)&TestReg, 0 ,(char *) &AlarmTitles, ScrollType, MainMenu, AlarmReset},
{{"Basınc\0","Pressure\0","Druck\0"}, "%5.3f",(float *)&PressureVal, 0 ,(float *) &SensorGain, FloatEditor, MainMenu, Save},
};



2x16 Ekranda kullandığım , yukarıdaki gibi bir menü yapım var.
Programın başında menüyü , min-max değerlerini , hangi fonksiyonların işletileceğini vs.. tanımlıyorum.
Min ve Max değerleri bazen başka bir değişkene bağlı olabiliyor , bazen de sabit bir değer olabiliyor. Başka bir değişkene bağlı olduğunda sorun yok. Tanımlarken o değişkenin adresini veriyorum. Ancak Sabit bir değer veremiyorum.  Soru bu başka bir değişken vs.. tanımlamadan , doğrudan yapının il kullanıma hazırlık kısmında sabit değeri nasıl veririm?
Nasıl bir değişkenin adresini fonksiyona parametre olarak geçebiliyorsam , bu parametreye vereceğim sabitin adresini de fonksiyona geçebilmek istiyorum.
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: controller - 21 Haziran 2013, 14:41:14
Biraz saçma bir çözüm olabilir, her zaman çalışacağının garantisini de veremem ancak şöyle bir yöntem izlenebilir.

Fonksiyona parametre olarak pointer değil normal integer geçirirsiniz. Değişkenlerin adres değerleri genelde yüksek olur (1000000+).

Sizin fonksiyona geçirme ihtimaliniz olan değişkenin maksimum değeri örneğin 1000 i geçmiyorsa, fonksiyon içinde bu değeri kontrol edip eğer 1000 den küçük ise doğrudan kullanırsınız. Eğer 1000 den büyük ise bu değeri int* e cast ederek bu adresdeki değeri okuyarak işlem yaparsınız.

Biraz kirli bir çözüm oldu ama bence uygulanabilir.


mesaj birleştirme:: 21 Haziran 2013, 14:50:34

Test kodunuda vereyim;

#include<stdio.h>

int topla (int x)
{
    if(x<1000) return(x +5);
else return(*(int*)x +5);
}

int main(void)
{

int a = 3;
int b;

b = topla((int)&a);
printf("%d\n", b);


b = topla(3);
printf("%d\n", b);

}
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: Klein - 21 Haziran 2013, 14:59:13
O biraz riskli gibi. Aslında şöyle bir çözümüm var.


typedef struct
{
    ...
    float  MinVal;
    float  MaxVal;
    void *MinParam;
    void *MaxParam;
    ...
}Menu_Type;


Tanımlamayı yaparken eğer sabit değer kullanılacaksa, MinVal ve MaxVal değerlerini sabit girip , MinParam ve MaxParam işaretçilerine Bu değişkenlerin adresini girebilirim.
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: mufitsozen - 21 Haziran 2013, 15:22:45
Alıntı Yapint b;

b = topla(& 3); // tabi bu şekilde çağıramıyoruz. Aradığım şey bu fonksiyona doğrudan 3 değerini geçmek.

Bu bilhassa yapilmamasi istenen bir durum. Fortran gibi eski (dinazor) dillerde bu sekilde kullanim mumkundu ama bu yuzden asagidaki ornek gibi hatalar yapilabilir. Bu yuzdende sabit degerlerin adreslerini gecirmek butun modern dillerde yapilamaz.

asagidaki ornek aciklayici olabilir!

diyelimki soyle bir fonksiyon olabilse

void foo(int *x)
{
     *x = *x + 1;
}

simdi diyelimki foo(&5) diye cagirabildiniz.

Artik literal 5 olan heryerde 5 değil 6 degeri kullanilir (cunku hafizadaki literal degerini foo`da degistirdiniz.

yani printf("x=%d",5) derseniz ekrana 6 yazilir!
yada y= x+ 3 dediniz y 8 değil 9 olur vs.

O yuzden literal degerleri call-by-reference yapilmasina izin verilmez.

Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: Klein - 25 Haziran 2013, 05:19:45
aşağıdaki gibi pointer parametreli bir fonksiyonu

void foo(char *x);


foo("merhaba dünya") şeklinde sabit parametreyle veya foo(Buffer) gibi bir parametre ile çağırabiliyoruz.

Parametrede sabit kullandıysak fonksiyon derlenirken  bu dizi bir tabloya yerleştiriliyor ve çağırırken dizinin adresini geçiyor.
Burada dizi romda tutulduğu için dizi üzerinde bir değişiklik yapamıyoruz. Yapmak istediğimizde hata oluşuyor.

Aynı şey 1 byte veya 1 Word sabitler için de geçerli olabilir.
Özellikle "literal" tanımını kullanmıyorum. Literallerin derlenmesi de , mcu tarafından işlenmesi de farklı.
ama değerin sabit olması bunun literaller gibi işlenmesi gerektiği anlamına gelmemeli. Aynen yukarıdaki örnekte olduğu gibi , tek byte veya Word değeri bir tabloya koyar ve adresi oradan çekebilir.






mesaj birleştirme:: 25 Haziran 2013, 05:50:16

Nihayet hallettim.


void foo( int *x)
{
......
}

// fonksiyon çağrısı
foo(&(int){sabit değer});

Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: Gökhan BEKEN - 25 Haziran 2013, 10:45:35
Alıntı yapılan: Klein - 25 Haziran 2013, 05:19:45
Nihayet hallettim.


void foo( int *x)
{
......
}

// fonksiyon çağrısı
foo(&(int){sabit değer});


öyle çalışmaz hocam, böyle deneyin.

void guzel_fonksiyon( int *x)
{
printf("%d",x);
}

int main ()
{
guzel_fonksiyon((int *)6); // sabit sayıları böyle girebilriz. Ekrana 6 yazar.
}
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: controller - 25 Haziran 2013, 12:11:36
@Klein ve @meftun

gerçekten verdiğiniz kodları çalıştırabiliyor musunuz?

Ekleme:

Evet, Klein'in kodu gcc de çalıştı ama MinGW de çalışmadı.

İkinci ek:

MinGW de parametrelere -fpermissive ekleyince çalıştı.
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: Klein - 25 Haziran 2013, 12:47:44
@meftun.

Sanırım soruyu yanlış anladın. Sabit sayı geçmekten kasıt, sabit sayının adresini geçmek. sabit adres geçmek değil.
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: Gökhan BEKEN - 25 Haziran 2013, 13:47:35
@benim kodu visual c++ da çalıştırdım.
Ancak @klein 'in yazdığı kodu çalıştıramadım bir türlü.
@controller o kodu nasıl çalıştırdığınızı biraz açarak yazar mısınız?
Başlık: Ynt: Pointer parametreli fonksiyona sabit değer geçmek.
Gönderen: Klein - 25 Haziran 2013, 14:38:50
@meftun
Aslında fonksiyonun çalışmıyor.  fonksiyona 6 sabitini ya da 6 sabitinin adresini değil  , doğrudan adres olarak 6 geçiyorsun ve printf ile parametrenin değerini değil adresini görüntülüyorsun. Bu seni yanıltıyor.

int a = 6;
int *p = &a;
güzel_fonksiyon(p);

şeklinde geçtiğinde 6 değerini göremediğini , p işaretçisinin adresini gördüğünü farkedeceksin.