Pointer parametreli fonksiyona sabit değer geçmek.

Başlatan Klein, 21 Haziran 2013, 03:07:21

Klein

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.

fatih6761

Hocam biraz daha açar mısınız? Girdi-çıktı ne olacak mesela? Örnek verebilir misiniz?

yilmaz_kk

&degisken

gibi birşeyden bahsetmiyorsunuz sanırım. Biraz daha açarsanız yardımcı olmaya çalışırız.

polleme

#3
ö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ı.

Klein

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.


polleme

Böyle birşey hiç görmedim, yapılamayacağını tahmin ediyorum.

Klein

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.

controller

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

}
Hesabım OG tarafından haksız bir şekilde pasif yapılmıştır.

Klein

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.

mufitsozen

#9
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.

Aptalca bir soru yoktur ve hiç kimse soru sormayı bırakana kadar aptal olmaz.

Klein

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

Gökhan BEKEN

#11
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.
}
Özel mesaj okumuyorum, lütfen göndermeyin.

controller

#12
@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ı.
Hesabım OG tarafından haksız bir şekilde pasif yapılmıştır.

Klein

@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.

Gökhan BEKEN

@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?
Özel mesaj okumuyorum, lütfen göndermeyin.