Tam Sürümünü Görmek İçin : fonksiyon icinde static degisken?
Selam.
elimde soyle bir ponter var:
static char *data[10];
bir fonksiyon icinde fonksiyonu her cagirdigimda bu pointerin tuttugu degerler korunsun istiyorum. ama her cagirisimda da *data[0] pointerina yeni deger aktarip diger degerleride bir sonraki pontera aktarmam gerekiyor. bunu da soyle yapabilirmiyim??:
data[1]=data[0]
. .
. .
gibi....
bir de bu fonksiyon bu degerleri saklarmi? bu tanimladigim ponter icin memory allocation yapmam gerekirmi?
turkce terimler kullanamadim ozur dilerim.
tesekkurler
acehreli
16/12/2005, 01:47
Oncelikle, tabii ki o bir pointer degil array (dizi)... :)
O dizi yerel static oldugu icin,
- yalnizca tanimlandigi islev icinde gorulur,
- ilk degerini islev ilk cagrildiginda alir
- islev her cagrildiginda son aldigi degerini korur.
Baska ilginc olan, o dizinin icindeki isaretcilerin gosterdikleri dizgilerin islev her cagrildiginda gecerli olup olmayacaklaridir. data[0]'a atanan o yeni deger kim tarafindan veriliyorsa, o degerin gecerli kalacagi onlar tarafindan saglanmalidir.
Ben bu ornekte isaretcilerin gecerli kalmalarini saglamak icin dizgileri global yaptim. Kod C gibi gorunse de C++ olarak derledim:
#include <stdio.h>
#include <assert.h>
enum Islem { Islem_degistir, Islem_kullan };
char const * const sifirinci = "sifirinci";
char const * const birinci = "birinci";
char const * const ikinci = "ikinci";
unsigned int const dizi_uzunlugu = 10;
void foo(Islem islem)
{
static char const * data[dizi_uzunlugu] = { sifirinci, /* gerisi 0 olur */ };
switch (islem)
{
case Islem_kullan:
printf("%s\n", data[0]);
break;
case Islem_degistir:
data[0] = (data[0] == birinci) ? ikinci : birinci;
break;
default:
assert(!"Tanimsiz islem");
break;
};
}
int main()
{
for (int i = 0; i != 5; ++i)
{
foo(Islem_kullan);
foo(Islem_degistir);
}
return 0;
}
Ote yandan, dizilere bulasmak yerine baska veri yapilarina da bakilabilir. Eger data'yi bir kuyruk yapisi gibi kullaniyorsan, ve C++ ise, belki de std::queue yapisi daha uygun olur.
Ayni sekilde char* dizgileri yerine std::string bu tur sorunlarin cogunu ortadan kaldirir.
Ali
acehreli
16/12/2005, 03:01
mr1yh1, ne olur ki :) Benim de basima geliyor bazen. Keske yine de gonderseydin...
Ali
Soyle bi kod yazdim:
<CODE>
#include <cstdlib>
#include <iostream>
using namespace std;
void func( char *ccdata){
static char *data[2]={"ali veli"};
char *temp;
temp=data[0];
data[0]=ccdata;
data[1]=temp;
cout<<"data[0]="<<data[0]<<endl;
cout<<"data[1]="<<data[1]<<"\n";
}
int main(int argc, char *argv[])
{
char *tt={"sifirinci data"};
char *tt1={"birinci data"};
func(tt);
func(tt1);
}
</CODE>
programin ciktisi:
data[0]=sifirinci data
data[1]=ali veli
data[0]=birinci data
data[1]=sifirinci data
burada func() ilk cagrildiginda data[0] "sifirinci data" aktarildi. data[0] in degeri de data[1] kaydirildi. fonksiyon ikinci cagrilisinda data[0] a "birinci data" aktarildi bu arada data[0] in fonksiyonun bir onceki cagrilisinda tutulan degeri data[1] aktarildi.
Size bu arada bi soru sorayim??
Fonksiyon icindeki static char *data[2]={"ali veli"}; data ya ilk deger vermessem program istedigimi yapmiyor.
ama kitaplarda static tanimlanan degisken otomatik olarak 0 olarak ilkdegerin atanacagi soyluyor???
mr1yh1, ne olur ki :) Benim de basima geliyor bazen. Keske yine de gonderseydin...
Ali
peki :) o zaman bu tarz karmaşaları aşamak için yararlandığım yöntemi anlatayım.
C yi sağdan sola doğru okununca daha kolay.
char *data[10] =>
yani data[10] dizisi , char* tutuyor.
@neolion
NULL değeri atanmış bir pointeri kullanmaman lazım.
static int i; // tamam i = 0 , kullanabilirsin.
static char* c ; // c = NULL , kullanamazsın.
Oh be ceviz netimize kavustuk. cevaplar icin tesekkurler.
bir sorumdaha olcak.
bir program yaziyorum. Borland C++ kullaniyorum editor olarak. Ansi C++ a mumkun oldugunca bagli kalarak.
cok buyuk miktarlarda unsigned char datalari uzerinde islem yaptigim icin pointer hizli olmasi icin isaretci kullaniyorum.
soru 1: programimi 256mb ram li laptopumda calistirirken ,bir isaretci icin adrese ulasilamadi deyip kesip atiyor programi. Ayni program lab taki 512mb ramli makinada sorunsuz calisiyor. sebebi nedir sizce? iki makinada winXP
soru 2: isaretcilere bellekte yer ayirma islemini "new" ile yapiyorum bazi kitaplarda c++ kitabi olmasina ragmen "malloc" fonskiyonu kullaniyorlar. sebebi nedir?
Bir fonksiyon icinde "new" ile ayirdigim bellek alani "delete" ile silmez isem bu alan fonksiyonla isim bittikten sonra otamatik kendisi silinirmi? yoksa illede o fonksiyon icinde silmelimiyim?
tesekkurler
acehreli
25/12/2005, 09:32
neolion, keske yeni bir konu acsan... Yine uzayip giden bir konumuz olacak... :)
1) Programinda tanimsiz davranis var; bazen istedigin gibi calisiyor
2) Normalde new kullanilir cunku genelde ayirdigimiz bellekte bir de nesne olustururuz. Hemen olusturacak nesnemiz olmadiginda ise bellegi malloc ile de ayirabiliriz. Ozetle: new bellek ayirir ve nesne kurar; malloc ise yalnizca bellek ayirir.
Her new'e karsilik bir delete olmazsa kaynak sizintisi olur. Dikkat edersen yalnizca "bellek sizintisi" demedim... Cunku delete once bozucu islevi cagirir, sora bellegi geri verir. Eger sonlandirilan nesnenin bozucusu baska kaynaklar da geri veriyorsa onlar da sizarlar... :)
Ali
Ozur dilerim Ali hocam. Bu seferlik buradan devam etsek olurmu?
1. cevabinizi biraz daha acarmisiniz?
ozaman kendimize ait bir nesne icin "new" kullaniriz ama built in type mesela bir char degiskeni icin "new" kullanmaya gerek yok anladigim kadariyla degilmi?
saygilar
acehreli
25/12/2005, 11:19
1) Eger bir program ancak bazi durumlarda ve/veya bazi ortamlarda dogru calisiyorsa, buyuk olasilikla hatalidir. Bellek erisim hatasindan da bahsettigine gore, bence programda bir hata var. Bazen calisiyor olmasi seni yaniltiyor...
2) new ile ilgili sorunu tam ne anlamda sordugunu anlamadim... :( Aslinda new kullanarak temel turlere (ve butun POD'lere (plain old data)) de ilk deger atanabilir:
char * c0 = new char();
// c0 simdi '\0'
char * c1 = new char;
// c1'in degeri belirsiz
char'dan sonra gelen parantezler nesnenin sifirlanmasina neden olur. Ayni sey POD'ler icin de gecerlidir:
struct Veri
{
int i;
char c;
};
/* ... */
Veri * v0 = new Veri();
// Simdi v0.i == 0 ve v0.c == '\0'
// Ama eger parantez kullanmazsak:
Veri * v1 = new Veri;
// Simdi v1.i ve v1.c'nin degerleri belirsiz
Varsayilan kurucusu olan turlerde ise parantezler kullanilmasa bile varsayilan kurucu cagrilir.
Eger sorunu new kullanmanin tek gereginin kurucu cagirmak olup olmadigini anlamak icin soruyorsan, tabii ki dogru degil. Cunku dogal olarak, nesneler kurulurken new kullanilmasa bile kurucu cagrilir. Eger BenimTurum'un varsayilan kurucusu varsa,
BenimTurum nesne; // varsayilan kurucu cagrilir
Daha once soylediklerimi temel turlerle kullanici turleri arasinda ayrim yapmak icin soylemedim. Yalnizca malloc'un salt bellek ayirdigini, new'un ise kurucu da cagirdigini vurgulamak istedim. Tabii simdi yazdiklarim daha once soylediklerimi tamamlamis oldular: new, kurucusu olmayan turleri de sifirlayabilir; ama eger parantezleri kullanirsak...
Nesne kurmakla (construction) nesne sifirlamayi (zero-initialization) birbirinden ayirmak gerek...
Ali
Temel turler icin "new" kullanmanin pratiklik acisindan avantaji veya dezavantaji ni ogrenmek istemistim. "new" farkini da ogrenmis oldum bu arada :)
temel turler icin malloc islevini kullanmami mi tavsiye edersiniz.
saygilar
acehreli
26/12/2005, 01:31
Oncelikle, new veya malloc kullanmanin gerekmedigi bir suru durum oldugunu hatirla. Ikisini de kullanmamaya calis. Eger mutlaka gerekiyorsa da new kullan.
new kullandigin zaman da mutlaka akilli gosterge kullan... :)
Ali
Forum Yazılımı : vBulletin v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.