PDA

Tam Sürümünü Görmek İçin : Başlık Dosyası Tahmin etme


DaesAgelmar
28/03/2004, 18:06
elimde M/M/1 kuyruk siteminin benzetim modelinin bir kodu var kodu kitaptan aldım ama student book olduğu için derlemeye çalıştığım zaman derleyemedim ufak çaplı bir araştırmadan sonra
#include <stdlib.h>
#include<conio.h>
#include "rand.h"
başlık dosyaları ile karşılaştık acaba bu rand .h başlık dosyası bizim oluşturmamız gereken bir dosyamı eğer öyle ise kaynak koddan bunun nasıl oluşturulduğunu bilebilirmiyiz


DaesAgelmar
29/03/2004, 18:33
öneri ve yorumlarınızı bekliyorum

Arkantos
29/03/2004, 20:06
Evet aynen dediğin gibi #include "rand.h" gibi bir başlık dosyası bu başlık dosyasının senin programının kaynak dosyasının olduğu dizinde (Örneğin ana.cpp dosyanın olduğu dizinde) bulunması gerektiğini gösterir.
#include <iostream> gibi bir ifade ise derleyicinin kurulu olduğu dizinde Include dizininde (Örneğin Devcpp için C:\Dev-C++\Include dizininde olduğunu) gösterir. Ve genellikle #include <xxx.h> gibi (tırnaklara dikkat) başlık dosyalarını koda eklemene gerek yoktur. Zaten yukarda bahsettiğim dizinde bu başlık dosyası vardır.

Rastgele sayı üretmek istiyorsan bir örnek C++ kodu:


#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
srand(GetTickCount());
int sayi1 = rand()%100;
// Bu program 0-99 arası ve dahil rastgele sayı üretiyor
cout << endl << "Rastgele Sayi = " << sayi1 << endl;
return 0;

}

acehreli
29/03/2004, 23:13
Basliklarini cift tirnaklarla veya acili parantezlerle belirtmenin tek farki, derleyicinin onlari aradigi dizinlerin farkli olmasidir. Yani, derleyici cift tirnaklarla bildirilen basliklari baska dizinlerde, acili parantezlerle bildirilenleri baska dizinlerde arar.

Basliklarin arandiklari dizinlerin sirasini -I ve arkadasi secenekler yardimiyla degistirebiliriz.

Arkantos'un dedigi gibi; kendi basliklarimizi cift tirnaklarla, kutuphanenin basliklarini da acili parantezlerle yazmak en dogru harekettir. Ancak, kendi basliklarimizin diger kutuklerle ayni dizinde bulunmasi sart degildir. Ornegin biz, su anda calistigim projede arayuzu bildiren basliklari ayri bir dizinde tutuyoruz. Derleyiciye onlari nerede bulabileceklerini -I secenegi yardimiyla bildiriyoruz.

Arkantos, aslinda kullanilan adlari bildiren butun basliklarin koda eklenmesine gerekir. Bazi derleyiciler <stdio.h> gibi basliklari bastan bilir gibi calisirlar ama bu davranis standart degildir.

C'de, bildirilmemis olan islevlerin int dondurdukleri ve belirsiz sayida parametre aldiklari varsayilir. (C'nin yeni standardinda da hala boyle mi acaba; yoksa her islevin bildirilmesi mi gerekiyor? Hatirlamiyorum :) Ne olursa olsun, en iyisi, kullandigimiz her adin tanimlandigi her basligi koda eklemektir.

Kaldi ki, bu varsayim yalnizca islevler icin gecerlidir. Nesnelerin ve sabitlerin ne olduklarini mutlaka basliklari ekleyerek bildirebiliriz. Ornegin su program, stdout'un ne oldugu bilinmedigi icin yasal degildir:


int main()
{
fprintf(stdout, "%d\n", 42);
}


Orada fprintf'in ne tur bir islev oldugu konusunda varsayim yapilir ama stdout bilinemez.

C++'ta her adin daha onceden bildirilmis olmasi gerekir. O dilde C'nin yaptigi gibi bir varsayim soz konusu degildir.

Arkantos, kutugun belittigin dizinde zaten bulundugunu soyluyorsun ama derleyicin o dizindeki kutukleri tek tek acip hangisini kullanacagini anlamasini bekleyemeyiz. Zaten o yuzden verdigin programdaki <iostream> basligini eklemek zorunda kaldik.


http://forum.ceviz.net/showthread.php?t=6811

sayfasindaki konuda rastgele sayilar uretilirken % islecinin kullanilmasinin neden iyi bir secim olmadigini gosteren fikirler ve baglantilar var.

Ali

DaesAgelmar
31/03/2004, 11:29
konuyla ilgili detaylı bilgileriniz için çok teşekkür ederim bu bilgiler ışığında yazılmış olan bir kodu inceleyerek başılk dosyasının nasıl oluşturulduğunu tahmin edebilirmiyiz. bunu sormamın sebebi kodun içerisinde bulunan rand.h başlık dosyasını kendim oluşturmak zorunda kalmam fakat C bilgimin bunun için yeterli olduğu kanısında değilim kodları inceleyerek bir tahmin de bulunma ihtimali nedir?

acehreli
31/03/2004, 21:35
DaesAgelmar, konudan ayrildigimiz icin ozur... :)

Basligin icerigini tahmin ederek ne kazanacagindan emin degilim. Cunku o basligin bildirdigi seylerin tanimlanmis oldugu kutuphaneyi de bulman gerekecektir. O kutuphaneyi bulabiliyorsan basligi da bulabilirsin demektir.

Sablonlar icin durum farkli: Onlarin basligini bulmak yeterlidir cunku kodun buyuk cogunlugu baslik icinde tanimlanmistir.

Yine de basliklarda nelerin bulunduguna bakalim:

1) Islev bildirimleri:

Elimizde soyle bir kod oldugunu dusunelim. Bu koda bakarak foo'nun tahmin etmeye calistigimiz baslikta bildirilmis oldugundan supheleniyor olalim.

int i = /* ... */
char c = /* ... */

double sonuc = foo(i, c);

Bu koda bakarak foo'nun sirasiyla int ve char turlerine donusebilen iki tane parametre aldigini ve double'a donusebilen bir parametre dondurdugunu soyleyebiliriz.

Yani o islev baslikta soyle tanimlanmis olabilir:

double foo(int, char);

Ama bambaska sekilde de tanimlanmis olabilir:

float foo(unsigned int, int);

2) Makro sabitler:

Elimizdeki kod soyle olabilir:

char c[BIR_SABIT_SAYI];

Bu durumda BIR_SABIT_SAYI'nin ne oldugu hakkinda hicbir sey bilmiyoruz. Baslikta sunlar gibi bir satir bulunabilir:

#define BIR_SABIT_SAYI 8
#define BIR_SABIT_SAYI 10000

Kim bilir...

3) Yapi tanimlari:

Kod soyle olabilir:

BirYapi yapi;
yapi.i = 5;

BirYapi nasil bir yapi acaba. Soyle mi:

struct BirYapi
{
int i;
double baskaBirOge;
};

yoksa soyle mi:

struct BirYapi
{
double i;
long dizi[BIR_SABIT_SAYI];
char * ad;
};

vs. vs.

Bu kadar lafi neden soyledigimden bile emin degilim :) Kisacasi: Hayir, bir basligi tahmin etmek genelde olanaksizdir.

Ali

DaesAgelmar
02/04/2004, 15:34
bu açıklmalaeınız için çok teşkkürler ali bey sayenizde kafamdaki bir çok soru işareti ile birlikte kitaplarda bulamadığım yada gözden kaçırdığım bir çok konuda fikir sahibi oldum .konumuza geri dönersek sonuç olarak çözmeye çalıştığım problem "rand.h" başlık dosyası rassal sayı üretmek amacıyla yazılmış ve hazırlamak zorunda olduğum ödevde ise buna uygun kodlara göre düzenlenmiş. sonuç olarak yazdıklarınızdan anladığım "kodu incele, eksiklikleri kendin tamamla yada uyarla ve çöz " basamaklarından oluşan bir hareket planı gerektirmekte acaba uyarlamak zorunda olduğum kodu buraya yazsam kodu inceleyerek bana fikir verebilirmisiniz?

acehreli
02/04/2004, 22:42
Ben bu odevde ne oldugu bilinmeyen rand.h basliginin isini hala anlamis degilim :) Acaba "buna benzer bir sey yapin" dediler de aslinda o basligin odevle dogrudan bir ilgisi yok mu?

Ben ve digerleri tabii ki koda bakarak fikir bildirmek isteriz.

Kolay gelsin,
Ali

DaesAgelmar
03/04/2004, 15:58
aslında ödevin veriliş tarzı ve açıklması birazcık anlaşılır olsa bende daha iyi ifade edebilirdim belki ama maalesef. ödevi veren hocamız SIMAN benzetim diline hakim bununla birlikte C den pek anladığı söylenemez ama SIMAN dili sentakslarının daha anlaamadığı için ödevimizi C dilinde kodlayıp vermemiz gerektiğini söyledi. aslında kod o kadar öenmli değil ama istenilen çıktıyı sağlamak içinde verilmiş olan örneği inceleme zorunluluğumuz var yani bir nevi "bu kod haricinde bişi yapamazsınız" dayatması kodu bi editörle yazıp birazdan bilgizinize sunucam
kodların kitaptaki yazılış sırasına göre yazıyorum umarım anlaşılır oluyorlardır

DaesAgelmar
05/04/2004, 12:13
#include <stdio.h>
#include <math.h>
#include "rand.h" /*header file for random number generator/*
#define Q_LIMIT 100 /*limit on queue length*/
#define BUSY 1 /*mnemonics for severs bing busy*/
#define IDLE /* an idle*/
int next_event_type, num_cuts_delayed,num_delays_required,num_events,nu m_in_q,server_status;
float area_num_in_q,area_server_status,mean_interval,mea n_service,time,time_arrival[Q_LIMIT+1],time_last_event,time_next_event[3],total_of_delays;
FILE *infile,*outfile
void initialize(void);
void timing(void);
void arrive (void);
void depart(void);
void report(void);
void update_time_avg_stats(void);
float expon(float mean);

DaesAgelmar
05/04/2004, 12:25
main()
{
infile=fopen("mm1.in","r");
outfile=fopen("mm1.out","w");
num_events=2;
fscanf(infile,"&f %f %d", &mean_interval, &mean_service, &num_delays_required);
fprintf(outfile,"single-server queeing system\n\n");
fprintf(outfile,"mean interval time %11.3 f minutes\n\n;mean_interval);
fprintf(outfile,"mean service time %16.3 f minutes\n\n",mean_service);
fprintf(outfile,"numbers of customers %14d *n\n",num_delays_required);
initialize();
while(num_cuts_delayed<num_delays_required)
{
timing();
update_time_avg_stats();
switch(next_event_type)
{
case1:
arrive();
break;
case2:
depart();
break;
}
}
report();
fclose(infile);
fclose(outfile);
return 0;
}

DaesAgelmar
05/04/2004, 12:35
void initialize(void)
{
time=0.0;
server_status=IDLE;
num_in_q=0;
time_last_event=0.0;
num_cuts_delayed=0;
total_of_delays=0;
area_num_in_q=0.0;
area_server_status=0;
time_next_event[1]=time+expon(mean_interval);
time_next_event[2]=1.0e+30;
}

DaesAgelmar
05/04/2004, 12:49
void timing(void)
{
int i;
float min_time_next_event=1.0e+29;
next_event_type=0;
for(i=1;i<=num_events;i++)
{
if(time_next_event[i]<min_time_next_event)
{
min_time_next_event=time_next_event[i];
next_event_type=i;
}
}
if(next_event_type==0)
{
printf(outfile,"\nEvent list empty at time %f ",time);
exit(1);
}
time=min_time_next_event;
}

DaesAgelmar
05/04/2004, 13:14
Aslında kodun bütünü şu şekilde önerilerinizi bu bütün üstüne yapsanız


/* External definitions for single-server queueing system. */

# include <stdio.h>
# include <math.h>
# include "rand.h"
# define QjLlMiT
# define BUSY
# define IDLE

/ * Meadpr file for random-number generator * /
100 /* Limit on queue lenght */
1 / * Mnemonics for server's being busy * / 0 /* andidle */

int next_eventjype, ftutojcustsjlelayed, num_delaysjrequired, num_events| numjnji, server_status;
float areajnumjhjk area_server_status, meanjnterarrival, mean_servicie, time, time_arrival[Q_LÎMIT + 1], timejast_e4ent, time_next_event [3], total^of^delays;
FILE *infile, *oiltfile;
void initialize (void);
void timing (voia);
void arrive (void);
void depart (void);
void report (void);
Void updateJime_avg_stats (void) ;
float expon (float mean);

I
main () / * Main function * /
{ J
/ * Open input and output files * / infile = fopett(ecmtoUn", <V'); outfile = fbpen ("Mhil.our,' rW);
/ * Specify the number of events for the timing function
numjevents = 2;
/* Read injhıt parameter */
fscanf (infile, cc%f %f %d", &meanjnterarrival, &mean__service, &niim_delaysjrequired);
/ * Write report heading and input parameters * /
fprintffcutfile, "Single server queueing system\n\n"), fprintfÇoutfİle, <cMeaninteraarivaltime%11.3f minutes\n\n",
meartjnterarrival); fprintf^outfile, C€Meanservicetime%16.3f minutes\n\n",
meain_service); fprintf(outfile, <eNumberofcustomers%14d minutes\n\n",
num_delays_required);
/ * Initialize the simulation * /
initialize ();
/ * Run the simulation while more delays are still needed * /
while (num_eusts_delayed < numjlelaysjrequired) {
/ * Determine next event * /
timing ();
/ * ^Jpdate time__average statistical accumulators * /
I
updatejtime_avg_stats (•);
/ * } nvoke the appropriate event function * /
swi eh (next_eventjype) {
| case 1: / .'
arrive (); break; case 2: depart (); break;
} | •
/ * Invoke the report generator and end the simulation * / report (); |
fclose(infile); fclose(outfile);
return 0;

void initialize(void) /* initialization function */
{ j
/ * Initialize the simulation clock * / time = 0.0;!
/ * Initialize! the state variables * /
i
server_statıis = IDLE; nuınjn_q j = 0; timejast_event = 0.0;
/ * Initializei the statistical counters * /
num_custsjîelayed = 0;
total_of_delays = 0.0;
area_num_inji = 0.0;
area^serveri^status = 0.0;
/ * Initializei event list. Since ho customers are present, the departure (service completion) event is eliminated from consideration * /
time_jiext_6vent [1] = time + expon(meatijnterarrival); timejiext_event [2] = l.Oe+30;
• * " - •'' ' 5 " * " : • '* •" '•> '.' ''''.' , ••'••• ....
void timing(void) :/* Timing function */
{ i
int i;
float minjime_next_event = l.Oe+29;
next_evenUtype =0;
/ * Determine the event type of the next event to occur * /
for (i = 1;! i <= num_events; -Hi) (
if (tinie_next_eventti] < miiij:imejiext_event) {
min_timejiext__event = time_next_eventti];
ne&_eventjype = î;
> ı ft /
} ! ' '
I * Check tb see whetheir the event list is empty * /
if(next_eWntJype ==^0) ( / * The eVent list İs empty, oo stop the Simulation * / fprint(ouifile, "\nfiveht list empty at time %f\ time);
' | •
/ * The event list is not eöpty, so advance the simulation clock * / time = min_time_next_event;

void arrive(void) j/ * , Arrival event function * /
{ !
float delay;
/ * Schedule next arrival * / ? -
time_next_4vent[l] = time -fexpon(meanjnteramval);
/* Check to see whether server is busy */
ı
if (server jtatus = = BUSY) {
/ * Server is busy, so increment number of customers in queue * /
/ * Check to see aheher an overflow condition exists * / if (numjnj > QJLIMIT) {
/i * The queue has overflowed, so stop the simulation * /
! fprint(outfıle,c%Overfîow of the array time^arrival at"); I fj>rint(outfile,atime %P, time);
} |
/ * there is still room in the queue> so store the time of arrival of the arriving ciistomer at the (new) end of time_amval * /
tim£_anival[numjnjj] = time;
else
/ * Server İs isle, so arriving customer has a delay of zero. (The following two statements are for program clarity and do not affect the results of the simulations) * /
delay = 0.0;
total j>f_delay += delay;
/ * increment the number of customers delayed, and make server busy * /
serer_statUs ^
/ * Schedule â departure (service completion) * /
= tittiö + expoft(mean_service);


l
void depart (void) /* Departure event function */
{
int i; j
float delay;
/ * Check to see whether the queue is empty * /
if (nümJnJ| = = 0) {
/ * The queue is empty so make the server idle and eliminate the departure (service completion) event from consideration * /
i
servei*_status = IDLE;
time next_event[2] = l.Oe+30; } else {
/ * The queue is non empty, so decrement the number of customers in queue * / — numjn_q;
/ * Compute the delay of the customer who is begining service and update th6 total delay accumulator * /
delay! = time~time_arrival[l];
totaTofjlelays += delay;
/ * Increment the number of customers delayed, and schedule departure * /
-H- nüm_custs_delayed;
timejnext_event[2] - time + expoft(meaii_service);
ı
/ * Mpve each customer İn queue (if any) up one place * /
for (ji = 1; i <=nutnjn_q; ++i) tîme_arrival[i] = time_arriv
void report (void) /* Report generator function */
( I
/* Compute and write (&ltiniate& of desired measures of performance * /
fprintf (outfıle, "VnVttAvöfâge delay in queued! 1.3f minutes\n\n",
totai_of_delays / hurrt^custs_delayed )j fprintf (outfjle, "Average humber in queue%10.3f\n\n",
area num_in_q / tittie); fprintf (outffie, "Server utilization^ 15.3 An\n",
area|_server_statUS / time); fprintf(outfıle, "Time simulation endedHÜJf\ time);

void üpdate_tirne_âvg_stât$(Völd) /* Update area accumulators for time average statistics *'/
{ İ
float time_sincejast_evettt;
f^^n-:^^^--'^-''^ •-•y^-vs^^^*.^-^ ;'•-,« r» • ••• , , . .
/* Compute tittle smöe last 0Vetit, and update lâst-fevent-tıme marker */
üttöjBince_İasfc^evöttt > time - timejastjîveüt;
timejast_eyent = time;
/ * Update area imdef tiutiiber itt queue ftirictioit * / area_num_in_q -f= numjii_q * time_siiicejast_event; / * Update area under server busy Indicator âıtıction * / areajserver' status 4-= server_status * time_sincejast_event;
) T ' -
float expon (float mean) / * Exponential variate generation function * /

a U(0,l) random variate */
float u;
/ * Generate ;
u =rand(l)-
/ * Return ah exponential random variate with mean "mean" * /
return -mean * log(u);

kodu scanner da tarattıktan sonra sanırım biraz bozulmalar olmuş genel olarak yukarıda yazılan kodu iki servise sahip bir sistem olarak modifiye edicem
önerilerinizi bekliyorum 7-04-2004 saat 17:00 kadar sürem var :D

acehreli
05/04/2004, 19:04
Kodun gordugum kadarinda "rand.h" basligini kullanan hicbir sey yok. Bence ilk yapman gereken o satiri cikartip kodu derlemeye calismak olmali.

/* #include "rand.h" */ /*header file for random number generator*/

Yazim yanlislarindan kaynaklanan bir kac tane derleme hatasini giderince geri kalan hatalarin "rand.h"nin eklenmemis olmasindan kaynaklandigindan suphelenmeye baslayabilirsin.

Benim gordugum yanlislar sunlar:

- exit islevinin kullanilabilmesi icin <stdlib.h> basliginin eklenmis olmasi gerekir

- printf(outfile... yerine
fprintf(outfile... olmali

- case1 ve case2 yazarken 'case'lerden sonra bosluk olmali

- IDLE'dan sonra bir deger yazilmali. Belki soyle:

#define IDLE 0

- "nu m_in_q" yerine "num_in_q" yazilmali

- "mea n_service" yerine "mean_service" yazilmali

- &f yerine %f olacak

- "%11.3 f" yerine "%11.3f" olacak

- "%16.3 f" yerine "%16.3f" olacak

- Bir yerde */ yerine /* yazmissin

Bunun disinda, kodun en zayif tarafi, global degiskenler kullaniyor olmasi. Bu kod, basi henuz global degiskenlerle derde girmemis birisi tarafindan yazilmis gibi gorunuyor. :)

Hele ornegin infile ve outfile degiskenleri yalnizca main icinde kullaniliyorlar. Onlarin global olarak tanimlanmalarinin hicbir nedeni yok.

DaesAgelmar, bu kodu oldugu gibi mi kullanacaksin? "Uyarlamak"tan ne kastediyorsun? Konunun icinde olmadigim icin ben tam olarak anlamiyorum ama mesaj kuyrugu benzetimi gibi bir sey oldugu anlasiliyor. (?)

Kisacasi: "rand.h" satirina kafani takmana gerek yok gibi gozukuyor. Olsa olsa kodun gormedigimiz kisminda rastgele bir sayi elde etmek icin kullaniliyordur. O satiri yazarsan onun isini yapan baska bir islev onerebiliriz.

Ali

DaesAgelmar
06/04/2004, 16:31
kodun tamamını yazdım yukarıda !!?

acehreli
06/04/2004, 20:58
1) Nasil olduysa kodun parcalarina yazdigim yanit kodun butununden sonra yer almis. Walla ben yazdigimda kodun tamami ortada yoktu :)

2) DaesAgelmar, kodda biraz degil bayagi bozulmalar olmus. :)

3) Ben bu kodun ne yaptigini veya nasil iki servise ayrilacagini anlayamam. Onun icin hala ilk sorulan soruya takilmis durumdayim. En sonunda rassal sayilarin update_time_avg_stats islevinde kullanildigini anlamis olduk. Orada galiba soyle bir sey var:

float u;
u = rand(l); /* 1 de olabilir */

Ama galiba orada rand(1) var. Cunku orada 'l' (le) diye bir degisken goremiyorum.

Benim tahminim su: O satirda 0'la 1 arasinda rastgele kesirli bir sayi elde ediliyor. Eger bu tahmin dogruysa, yapman gerekenler sunlar:

a) "rand.h" satirini koddan cikart

b) Kendi kullanacagimiz time islevinin bildirildigi

#include <time.h>

basligini ekle. (Bu baslik standart degildir ama POSIX standardina uyan her sistemde bulundugu icin sende de buyuk olasilikla vardir.)

c) Koddaki global 'time' degiskeninin adini baska bir seye degistir cunku yoksa biraz sonraki adimdaki 'time' isleviyle karisikliga neden olacaktir. Onu ornegin g_time yap.

Eger bir sonraki adim yerine baska bir yontem kullanmak istersen o zaman bu adima da gerek yok.

d) main'in bas tarafina bir yere su satiri ekle:

srand(time(0));

Boylece rassal sayilarin geldigi sayi dizisini biraz olsun rastgele bir noktasindan kullanmaya baslamis oluyoruz.

e) update_time_avg_stats islevinden daha onceki bir yere su islevi yerlestir:

double frandom()
{
return (double)rand() / ((unsigned int)RAND_MAX + 1);
}

Bu islev, [0,1) araliginda kesirli rassal sayilar uretir. Eger gercekten asil kodun yegledigi float turunu kullanmak gerekiyorsa, o zaman sunu kullan:

float frandom()
{
return (float)rand() / ((unsigned int)RAND_MAX + 1);
}

f) Koddaki rand(1) yerine frandom() yaz:

u = frandom();

Benim bu kadar bilgiyle verebilecegim yardim bu kadar. :(

Ali

Arkantos
06/04/2004, 23:16
Ben bu kodun ne yaptığını anladım sanırım.En azından şu satırını:
------->updatejtime_avg_stats (• ;) ;
Herhalde böyle komik komik şekiller felan çiziyor :p

DaesAgelmar
07/04/2004, 01:50
ali bey önerilerini için çok teşekkür ederim en azından zahmet edip cevap vermiş ve beni bilgilendirmiş oldunuz için ayrıca daha önce açtığım konuda ki önerileriniz ilesayenizde bilgi seviyemi arttırmış oldum. forumun amacı olan bilgi paylaşımı ve karşılıklı fikir alışverişi mantalitesinin tam olduğunu görmekten sevinç duymaktayım. Yardımlarınızın devamı ve başarılı olmanız dileğiyle

tekrar teşekkürler......

DaesAgelmar
07/04/2004, 01:53
arkantosa ise renkli önerileri için söylecek bişey bulamıyorum :p