Struct Problemi

Merhaba. Aşağıdaki problemi anlayamıyorum. Özellikle b ve c maddelerini. Kodunu yazabilir veya yardımcı olabilir misiniz?

  1. Bir okul için yapı tasarlayınız ve bu yapıyı aşağıdaki işlemlerde kullanınız.
    a. okul_yapisi adlı yapının isim (dizgi), öğrenci_sayi (tam sayı), ogretmen_sayi (tam sayı), sehir (dizgi) elemanlarını oluşturunuz.
    b. struct okul_yapisi a değişkeni, b göstergesi ve c adlı 10’luk bir yapı dizisi tanımlayınız.
    c. Okul yapısında a değişkeni, b göstergesi ve c adlı 10’luk bir yapı dizisi tanımlayınız.
    d. Yukarıda tanımlanan a ve c değişkenlerine bilgileri okuyunuz.
    e. b göstergesinin a yapısını göstermesini sağlayınız.
    f. b’nin gösterdiği yapıdaki ve c dizisindeki bilgileri yazdırınız.

Acaba şöyle bir şey mi yapmak istemiştiniz?

#include <stdio.h>

struct okul_yapisi{
    char isim[10];
    char sehir[10];
    int ogrenci_sayisi;
    int ogretmen_sayisi;
    int a;
    int *b;
    int c[10];
};

int main(){
    struct okul_yapisi okul;
    okul.a = 20;
    okul.b = &okul.a;
    printf("a = %d\n", *okul.b);
    for (int i = 0; i < 10; i++){
        okul.c[i] = i * i;
        printf("c[%d] = %d\n", i, okul.c[i]);
    }
    return 0;
}

Çıktı:

a = 20
c[0] = 0
c[1] = 1
c[2] = 4
c[3] = 9
c[4] = 16
c[5] = 25
c[6] = 36
c[7] = 49
c[8] = 64
c[9] = 81
2 Beğeni

Hocam teşekkür ederim direkt kodu yazmışsınız istediğim şekilde. Bu benim uzaktan eğitim için verilen ödevim fakat ben şurayı anlayamadım. “b” ve “c” maddesinin farkı nedir? Yoksa fark yok aynı şeyi söylüyor ama hoca yanlış mı yazdı? Direkt kodu almaktansa bunların cevabı daha önemli benim için. Çok teşekkürler. Kodunuzu inceleyip kendim mantık yürütmeye çalışacağım.

1 Beğeni

Özür dilerim, sizinle direk kodu paylaştım. Benim b ve c maddelerinden anladığım şey aynı. Belki de dediğiniz gibi hocanız yanlışlıkla iki defa yazmıştır.

1 Beğeni

Hocaya mail attım bakalım neymiş işin aslı. Çok teşekkürler gece gece uğraştığınız için <3

b ile c degil, a ile b ayni seyi (okul_yapisi struct’inin elemanlarini) soyluyor. Tanimlar birbiriyle celisiyor, dogru olan da a muhtemelen. (Yani struct okul_yapisi { dizgi isim; tam_sayi ogrenci_sayi; ... })

c’de istedigi de bu struct’i tutan
bir degisken (struct okul_yapisi),
bir pointer (struct okul_yapisi *)
ve bir array (struct okul_yapisi[])
deklare etmek.

b’de anlatılmak istenen typedefmiş. hocanın yolladığı maili alıntılıyorum.

“Söyle anlatiyim b şıkkında typedef kullanarak okul diye bir struct üretiyorsun. C şıkkında artık okul kelimesini kullanarak struct üretebileceğin için okulu kullanarak üç ader struct tanımı yapıyorsun. Bunlardan b işaretçi, c ise dizi, a ise normal struct. Bir dene bakalım yine anlamazsan yazarsın. Kolay aslında, soruyu kitaptan yazmıştım pek güzel anlatamamışlar. İyi çalışmalar,sevgiler.”

Bu doğrultuda aşağıdaki kodu yazdım. Hocanın istediğinin tam karşılığı mı bilmiyorum ama çalışıor gibi.

#include <stdio.h>

struct okul_yapisi {

	char isim[15];
	int ogrenci_sayi;
	int ogretmen_sayi;
	char sehir[10];
};


int main() {

	typedef struct okul_yapisi Okul;
	
	Okul a, *b, c[10];
	
	
	scanf("%s %d %d %s",&a.isim,&a.ogrenci_sayi,&a.ogretmen_sayi,&a.sehir);
	
	int i;
	for(i=0;i<1;i++) {
		
		scanf("%s %d %d %s",&c[i].isim,&c[i].ogrenci_sayi,&c[i].ogretmen_sayi,&c[i].sehir);
	}
	
	b = &a;
	
	printf("b nin degeri:\n");
	printf("Isim = %s\nOgrenci Sayi = %d\nOgretmen Sayi = %d\nSehir = %s\n\n",b->isim,b->ogrenci_sayi,b->ogretmen_sayi,b->sehir);
	
	printf("c nin deggeri:\n");
	for(i=0; i<1;i++) {
		printf("isim = %s\nOgrenci Sayi = %d\nOgretmen Sayi = %d\nSehir = %s\n",c[i].isim,c[i].ogrenci_sayi,c[i].ogretmen_sayi,c[i].sehir);
	}
	

	system("pause");
	return 0;}
1 Beğeni

Aynen oyle :+1:

Su anda gerekli (veya faydali bile) olmayabilir ama kodu bir yerlere yollayacak olsam yapacagim degisiklikler:

  • 1 ve 10 sayilarini bir #define makrosuna almak
  • C89 ile calisiyorsak i'nin deklarasyonunun yukari gelmesi lazim
  • C99+ ile calisiyorsak for'un icine almak daha iyi
  • Pointer/array indexlemek icin dogru tip size_t
  • scanf buffer overflow’a yol aciyor (hic detayli incelemedim, “%15s” filan kullanmak cozum oluyor muydu hatirlamiyorum—ama gcc warning veriyor.)
  • system icin stdlib.h include etmek gerek, pause da tasinabilir degil (bende calismiyor mesela). (Buraya da “satir oku” gibi bir cozum getirilebilir fakat bu sefer de scanf’ten kalan \n'ler sorun olabilir)
  • main'in aldigi parametreleri (veya parametre almadigini) yazmak daha iyi: int main(void)

Bi de sasirtmaca: typedef'in tanimladigi tip ismi struct’la ayni olabilir:

typedef struct okul_yapisi okul_yapisi;
3 Beğeni

Ben de aşağıdaki ifade uyarı yükseltiyor.

scanf("%s %d %d %s", &a.isim, &a.ogrenci_sayi, &a.ogretmen_sayi, &a.sehir);

Uyarı da şöyle:

a.c: In function ‘main’:
a.c:14:10: warning: format ‘%s’ expects argument of type ‘char *’, but argument 2 has type ‘char (*)[15]’ [-Wformat=]
  scanf("%s %d %d %s", &a.isim, &a.ogrenci_sayi, &a.ogretmen_sayi, &a.sehir);
         ~^            ~~~~~~~
a.c:14:19: warning: format ‘%s’ expects argument of type ‘char *’, but argument 5 has type ‘char (*)[10]’ [-Wformat=]
  scanf("%s %d %d %s", &a.isim, &a.ogrenci_sayi, &a.ogretmen_sayi, &a.sehir);

Bu yukarıdaki yerine şöyle yapınca uyarı almıyorum.

scanf("%s %d %d %s", a.isim, &a.ogrenci_sayi, &a.ogretmen_sayi, a.sehir);

Aynı durum for döngüsündeki scanf için de geçerli. &c[i].isim yerine c[i].isim ve &c[i].sehir yerine c[i].sehir yazınca uyarı almıyorum.

Bunun nedeni ne?
Bende uyarı vermeyen kodlar şu şekilde:

#include <stdio.h>

struct okul_yapisi {
    char isim[15];
    int ogrenci_sayi;
    int ogretmen_sayi;
    char sehir[10];
};

int main() {
    typedef struct okul_yapisi okul_yapisi;
    okul_yapisi a, *b, c[10];
    scanf(
        "%s %d %d %s",
        a.isim, &a.ogrenci_sayi, &a.ogretmen_sayi, a.sehir
    );
    for(int i = 0; i < 1; i++){
        scanf(
            "%s %d %d %s",
            c[i].isim, &c[i].ogrenci_sayi, &c[i].ogretmen_sayi, c[i].sehir
        );
    }
    b = &a;
    printf("b'nin değeri:\n");
    printf(
        "isim: %s ogrenci sayi: %d ogretmen sayi %d sehir: %s\n",
        b->isim, b->ogrenci_sayi, b->ogretmen_sayi, b->sehir
    );
    printf("c'nin değeri:\n");
    for(int i = 0; i < 1; i++){
        printf(
            "isim: %s ogrenci sayi: %d ogretmen sayi: %d sehir: %s\n",
            c[i].isim, c[i].ogrenci_sayi, c[i].ogretmen_sayi, c[i].sehir
        );
    }
    return 0;
}

scanf fonksiyonuna format stringi’nden sonra verilen argümanların, scan edilen değerlerin hafızada nereye yazılması gerektiğini belirten pointerlar olması gerekiyor. .isim ve .sehir ise halihazırda birer pointer görevi gördüklerinden, ekstra olarak & ile bir pointer level’i daha eklemek gcc tarafından pek uygun bulunmamış :d

1 Beğeni

Açıklama için teşekkür ederim. <3

Ha evet, karakter pointer’i yerine array pointer’i kullanilmis. Degerleri ayni ama turleri farkli.

scanf olunca okumamisim bile uyariyi, buffer overflow UB’den beter.

1 Beğeni