c programlama

Başlatan eembahtiyar, 10 Haziran 2017 - 02:13:30

« önceki - sonraki »

0 Üyeler ve 1 Ziyaretçi konuyu incelemekte.

eembahtiyar

struct Sample {
        int i;
        long l;
        double d;
};
yukarıdaki yapının uzunluğu linux sisteminde kaçtır.
türlerin ayrı ayrı uzunluklarının toplamına eşit olması gerekmiyor mu?

edge35

Ben de merak ettim nasıl oluyor böyle  :-\ :-\

#include <stdio.h>
int main()
{
struct Sample {
        int i;
        long l;
        double d;
};
struct bos{

};
struct intt{
int a;
};
struct doublee{
double b;
};
struct longg{
long c;
};
struct intlong{
int  a;
long c;
};
struct doublelong{
double  a;
long c;
};
struct intdouble{
int  a;
double c;
};


printf("int \t\t-> %ld\n",sizeof(int));
printf("long \t\t-> %ld\n",sizeof(long));
printf("double \t\t-> %ld\n",sizeof(double)); puts("");

printf("struct bos \t-> %ld\n",sizeof(struct bos)); puts("");

printf("struct intt \t-> %ld\n",sizeof(struct intt));
printf("struct longg \t-> %ld\n",sizeof(struct longg));
printf("struct doublee \t-> %ld\n",sizeof(struct doublee)); puts("");

printf("struct intlong \t\t-> %ld\n",sizeof(struct intlong));
printf("struct doublelong \t-> %ld\n",sizeof(struct doublelong));
printf("struct intdouble \t-> %ld\n",sizeof(struct intdouble)); puts("");

printf("struct Sample \t-> %ld\n",sizeof(struct Sample));

return 0;
}


Kod (ÇIKTI) Seç
muhammed@myilmaz:~/Documents$ ./a
int -> 4
long -> 8
double -> 8

struct bos -> 0

struct intt -> 4
struct longg -> 8
struct doublee -> 8

struct intlong -> 16
struct doublelong -> 16
struct intdouble -> 16

struct Sample -> 24


Sorunlarımı çözerken her şeyiyle öğrenmeye çalışıyorum. Bana balık verenden Allah razı olsun, ama bana balık tutmayı öğretenden Allah daha çok razı olsun :)

Death Pro

Alıntı yapılan: edge35 - 10 Haziran 2017 - 17:21:17
Ben de merak ettim nasıl oluyor böyle  :-\ :-\

#include <stdio.h>
int main()
{
struct Sample {
        int i;
        long l;
        double d;
};
struct bos{

};
struct intt{
int a;
};
struct doublee{
double b;
};
struct longg{
long c;
};
struct intlong{
int  a;
long c;
};
struct doublelong{
double  a;
long c;
};
struct intdouble{
int  a;
double c;
};


printf("int \t\t-> %ld\n",sizeof(int));
printf("long \t\t-> %ld\n",sizeof(long));
printf("double \t\t-> %ld\n",sizeof(double)); puts("");

printf("struct bos \t-> %ld\n",sizeof(struct bos)); puts("");

printf("struct intt \t-> %ld\n",sizeof(struct intt));
printf("struct longg \t-> %ld\n",sizeof(struct longg));
printf("struct doublee \t-> %ld\n",sizeof(struct doublee)); puts("");

printf("struct intlong \t\t-> %ld\n",sizeof(struct intlong));
printf("struct doublelong \t-> %ld\n",sizeof(struct doublelong));
printf("struct intdouble \t-> %ld\n",sizeof(struct intdouble)); puts("");

printf("struct Sample \t-> %ld\n",sizeof(struct Sample));

return 0;
}


Kod (ÇIKTI) Seç
muhammed@myilmaz:~/Documents$ ./a
int -> 4
long -> 8
double -> 8

struct bos -> 0

struct intt -> 4
struct longg -> 8
struct doublee -> 8

struct intlong -> 16
struct doublelong -> 16
struct intdouble -> 16

struct Sample -> 24


Açıkçası bende merak ettim neden böyle diye. Burada güzel açıklamışlar.
https://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member

edge35

Alıntı yapılan: Death Pro - 12 Haziran 2017 - 00:15:25
Açıkçası bende merak ettim neden böyle diye. Burada güzel açıklamışlar.
https://stackoverflow.com/questions/119123/why-isnt-sizeof-for-a-struct-equal-to-the-sum-of-sizeof-of-each-member
İngilizce anlatımları hiç sevmiyorum ya  :P Kısa cümleler olunca iyi de böyle uzun açıklamaları okurken zorlanıyorum. Kaydettim, bir ara oturur okurum artık :D


Sorunlarımı çözerken her şeyiyle öğrenmeye çalışıyorum. Bana balık verenden Allah razı olsun, ama bana balık tutmayı öğretenden Allah daha çok razı olsun :)

Sh4oTT

Bildiğim kadarıyla, yapıların boyutu içerisindeki değişkenlerin boyutları toplamı kadardır.

unixmania

Alıntı yapılan: Sh4oTT - 13 Haziran 2017 - 07:31:43
Bildiğim kadarıyla, yapıların boyutu içerisindeki değişkenlerin boyutları toplamı kadardır.

Her zaman oyle olmaz. compiler bazen performansi arttirmak icin hizalama/yuvarlama yapabilir. mesela yukardaki gibi 8in katlarina yuvarlar.

Death Pro

Alıntı yapılan: unixmania - 13 Haziran 2017 - 11:08:58
Alıntı yapılan: Sh4oTT - 13 Haziran 2017 - 07:31:43
Bildiğim kadarıyla, yapıların boyutu içerisindeki değişkenlerin boyutları toplamı kadardır.

Her zaman oyle olmaz. compiler bazen performansi arttirmak icin hizalama/yuvarlama yapabilir. mesela yukardaki gibi 8in katlarina yuvarlar.

Platform ve tabiki derleyiciye bağlı olarak işlemcinin (CPU) 4 veya 8 in katlarında veriye erişmesi daha kolaydır. Yukarıda verdiğim linkte anlatıyo zaten. Uzun anlatmalarının sebebi bilen var bilmeyen var. Böyle uzun anlatmaları çok iyi. Eğer çok uzunsa bahsi geçen konunun kaynak internet sayfasını veriyolar zaten.

Amenofis

Bu konu yanlış yerde değil mi? Neyse.

İşlemcilerin çoğu bellekten yazmaça veri çekmek için hizalanmış adreslere ihtiyaç duyar. Mesela int 4 byte diyelim. Bellekten int çekebilmek için verinin olduğu adres 4' ün katları olması lazım. Struct elemanları bellekte peşpeşe dizilir ama bu diziliş hizalama kuralı bozabilir.

struct {
int a;
int b;
};

Burada sorun yok. Derleyici ilk elemanın büyüklüğüne göre başlangıç adresini ayarlar ve "a" 4 byte olduğu için ondan sonra gelen "b" de hizalanmış adrese yerleşmiş olur. Fakat;
struct {
int a;
char c;
int b;
};

Problem burada başlar. a'dan sonra gelen c, 4'ün katı olan adresin ilk byte ını işgal ederek b'nin hizalanmasını engeller. Derleyici sorunu çözmek için c'den sonra 3 byte daha dolu olduğunu farzeder (padding) ve b'yi hizalanmış adresten başlatır. İşte struct boyutlarının fazla olması görünmeyen "pad" lerden kaynaklı.

Bu donanımsal bir problem olduğu ve bazı işlemcilerde şart olduğu için derleyiciler işi garantiye almak için sormadan hizalama yaparlar. Bildiğim kadarıyla Intel core işlemciler bu sorunu tamamen çözdü. Yani işlemci herhangi bir başlangıç adresinden 1-8 byte arasındaki veriyi alabiliyor. Arm işlemcilerde ise hizalama olmadan erişime izin veriliyor ancak performans düşüşü oluyor. Derleyiciye pad olayını iptal etmesini söylemek mümkün.

struct __attribute__ ((__packed__))
{
...

edge35

[mention=627676]@Amenofis[/mention] bu güzel açıklama için teşekkürler


Sorunlarımı çözerken her şeyiyle öğrenmeye çalışıyorum. Bana balık verenden Allah razı olsun, ama bana balık tutmayı öğretenden Allah daha çok razı olsun :)

Death Pro

[mention=627676]@Amenofis[/mention]

Teşekkürler açıklama için.

eembahtiyar

yorumlarınız için teşekkürler [mention=627698]@Death Pro[/mention][mention=627153]@Death Pro[/mention][mention=627128]@unixmania[/mention]

Neof07

@Amenofis, Çok güzel anlatmışınız teşekkürler. Benim küçük bir sorum olucak. Bellekten yazmaça veri çekmek tam olarak ne oluyor ? Yazmaç dediğiniz şey nedir ?

Amenofis

Alıntı yapılan: Neof07 - 05 Temmuz 2017 - 23:34:08
@Amenofis, Çok güzel anlatmışınız teşekkürler. Benim küçük bir sorum *olacak. Bellekten yazmaça veri çekmek tam olarak ne oluyor ? Yazmaç dediğiniz şey nedir ?

Yazmaç (Register), işlemcinin üzerinde işlem yapacağı veriyi tutan küçük hücrelerdir. Bellek saklama alanı, yazmaç ise operasyon alanıdır. İşlemci sadece yazmaçlar üzerinde işlem yapabilir.

Neof07

@Amenofis, teşekkürler.

Sh4oTT

Teşekkürler hocam @Amenofis