الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

شغل مخك مع السي ++(مساحة الكائنات)

مغلق
بدأه Asm4all في 3 يناير 2006 · 13 رد · 2,248 مشاهدة · في اختبر قداراتك
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ورحمة الله وبركاته...

نتعامل مع الـ struct والـ class على الحل لجمع مجموعة بيانات خاصة بعنصر واحد في مكان واحد, ونثق كل الثقة في طريقة صياغة البيانات داخل الـ stcuct و الـ class

عظيم , تابع هذا المثال :

#include <iostream>
#include <stdlib.h>
using namespace std;
class ST {
  unsigned char  x;
  unsigned long  y;
  unsigned short z;
public:
  inline unsigned char Get_X(void) {
    return x;
  }
  inline void Set_X(unsigned char value) {
    x = value;
  }
  inline unsigned long Get_Y(void) {
    return y;
  }
  inline void Set_Y(unsigned long value) {
    y = value;
  }
  inline unsigned short Get_Z(void) {
    return z;
  }
  inline void Set_Z(unsigned short value) {
    z = value;
  }
};
int main(int argc, char *argv[]) {
  ST rec;
  rec.Set_X(0x41);
  rec.Set_Y(0x42434445);
  rec.Set_Z(0x4647);
  cout << "size of unsigned char = " << sizeof(unsigned char) << endl;
  cout << "size of unsigned short = " << sizeof(unsigned short) << endl;
  cout << "size of unsigned long = " << sizeof(unsigned long) << endl;
  cout << "size of ST = " << sizeof(ST) << endl;
  cout << hex << rec.Get_X() << endl;
  cout << hex << rec.Get_Y() << endl;
  cout << hex << rec.Get_Z() << endl;
  system("PAUSE");	
  return 0;
}

قبل تجريب البرنامج , قم بقرائة الكود , واحسب مساحة البيانات داخل الكلاس

شغل البرنامج , واقرأ النتائج

هل هذا ما كنت تتوقعه ؟؟

إذا كانت إجابتك لا , فقم بتعديل الكود ( كود الكلاس) لكي يعمل كما توقعت

المطلوب باختصار : تصغير مساحة البيانات التي تستخدمها الكلاس الى أقل قيمة ممكنة

بالتوفيق ان شاء الله

#2

للتأكد أكثر من مقصود السؤال أكثر هل تقصد تصغير مساحـة الكلاس (وهذا ما أنا أحاول إيجاد إجابة عـنه منذ أمد بعيد) أو تصغير مساحـة الكائن الذي ننشأه منـه ...

من نصغر ST أو rec

#3

غير ترتيب العناصر, بحيث تضع العناصر الكبيرة اولا ..

الأمر في النهاية متروك للكومبايلر و ليس جزء من اللغة بحسب ما أظن.

class ST {
 unsigned long  y;
 unsigned short z;
 unsigned char  x;
....
#4

يمكنك تقليل المساحة باعادة ترتيب المتغيرات في الclass بحيث يكون بداية كل متغير مكان يكون عنوانه زوجي في الذاكرة

بمعنى

ضع الlong أولاً فسيحجز 32 بت كاملة و أي Double Word بفرض أنه بدأ من العنوان 0 فسيأخد المساحة من 0 الى 3

ثم ضع الshort فسيحجز 16 بت أيWord و سيأخذ المساحة من 4 الى 5

ثم ضع الchar الذي سيحجز 8 بت أي byte و سيأخذ المساحة من 6 و يتم اهمال البايت الأخير في الصف و هو البايت رقم 7 يكون هكذا تم حجز صفين بمجموع 32 بت اي 8 بايت

و لهذا ستجد أن مجموع المساحات نظرياً هو 7 بايت و لكن المساحة المحجوزة هي 8 بايت

هذا لأن عرض الRow في الMemory هو 4 بايت و بهذا يكون الMemory Access للعناوين الزوجية أسرع كثيراً من الباقي و هنا يقوم الCompiler بحجز المتغيرات بحيث يكون كل متغير يبدأ من أول Word حتى يكون الوصول له باسرع مايمكن

أما في الحالة التي كان عليها البرنامج أولاً فيتم حجز الchar أولاً و يتم اهمال باقي الWord و تخسر بايت ثم سيتم اهمال الWord التالية كلها لأنها لن تكفي لوضع الlong كاملاً و يتم وضع الlong بداية من الصف التالي و هكذا تكون خسر 3 بايت حتى الان ثم يأتي الshort في أول الصف الثالث و يتم اهمال باقي الصف و هو 2 بايت و تكون خسرت في النهاية 5 بايت و هذا يفسر لماذا حجز الكومبايلر في الحالة الأولى 12 بايت

Sr. Software Development Engineer
Hulu, LLC
My Blogs

#5

تعمدت ترتيب البيانات بهذا الشكل , لكي نمر بهذه المرحلة

التحليل جيد , والحل صحيح

وللعلم, لا يشترط وضع العناصر الكبيرة اولاً

هذا الترتيب يعطي 8 Bytes أيضاً

class ST {
unsigned char  x;
unsigned short z;
unsigned long  y;
....

و لكن ماذا لو تريد جعل البيانات في الكلاس 7 Bytes فقط ؟

حاول الحصول على 7 Bytes فقط

الحل سيكون بالاعتماد على لغة السي وليس على المترجم

#6

معنى كدة من كلام الاخ الباشمهندس أن لو حبيت أعمل struct or class أحط ف الاول المتغيرات اللى حجمها كبير يعنى زى المثال السابق بس أنا قراءت من فترة أن أنا عندى القدرة التحكم ف حجم الStruct in c Not in c++ وذلك عن طريق كتابة

#pragma pack(2)

كما ف ذلك المنتدى

instructurez

فاريت لو كلامى خاطى أتمنى تصحيحة وشكرا لكم :)

Muhammad Allam

Computer Science

@Resource(MappedURL="My Blog" )

#7

حل رائع , اول مره اعرف عنه , جربت

#pragma pack(1)

واشتغل تمام :D , اخرج 7 , كمساحة البيانات الخاصة بالكلاس

توجد طريقة اخرى :D , كوووووود , وليست تعليمة للمترجم

#8

طب بدون تلك التعليمة هل لو وضعت تريب المتغيرات من حيث الحجم ف الMemory هل هذا أيضا يؤثر ع حجم الclass or Struct ؟؟؟؟؟

Muhammad Allam

Computer Science

@Resource(MappedURL="My Blog" )

#9

أنا فكرت شوية و لقيت إننا ممكن نعمل Buffer يكون حجمه 7 بايت و يكون الكود بالشكل ده

#include <iostream>
#include <stdlib.h>
using namespace std;
class ST {
	unsigned char buffer[7];
public:
 inline unsigned char Get_X(void) {
   unsigned char* temp = (unsigned char*) &buffer[0];
   return *temp;
 }

 inline void Set_X(unsigned char value) {
   unsigned char* tmp = &buffer[0];
   *tmp = value;
 }


 inline unsigned long Get_Y(void) {
   unsigned long* temp =(unsigned long*) &buffer[1];
   return *temp;
 }

 inline void Set_Y(unsigned long value) {
   unsigned long* tmp =(unsigned long*) &buffer[1];
   *tmp = value;
 }

 inline unsigned short Get_Z(void) {
   unsigned short* temp = (unsigned short*) &buffer[5];
   return *temp;
 }

 inline void Set_Z(unsigned short value) {
    unsigned short* tmp = (unsigned short*) &buffer[5];
   *tmp = value;
}

};
int main(int argc, char *argv[]) {
 ST rec;
 rec.Set_X(0x41);
 rec.Set_Y(0x42434445);
 rec.Set_Z(0x4647);
 cout << "size of unsigned char = " << sizeof(unsigned char) << endl;
 cout << "size of unsigned short = " << sizeof(unsigned short) << endl;
 cout << "size of unsigned long = " << sizeof(unsigned long) << endl;
 cout << "size of ST = " << sizeof(ST) << endl;
 cout << hex << rec.Get_X() << endl;
 cout << hex << rec.Get_Y() << endl;
 cout << hex << rec.Get_Z() << endl;


 system("PAUSE");
 return 0;

}
#10

الله عليك يا باشمهندس ايه الحلاوه دي انت ولا اللي قاعد معايا في البيت

شوف الكود ده

#include <iostream>
#include <stdlib.h>
using namespace std;
class ST {
  unsigned char  local[7];
public:
  inline unsigned char Get_X(void) {
    return ((unsigned char)local[0]);
  }
  inline void Set_X(unsigned char value) {
    local[0] = value;
  }
  inline unsigned long Get_Y(void) {
    return *((unsigned long*)&local[1]);
  }
  inline void Set_Y(unsigned long value) {
    *((unsigned long*)&local[1]) = value;
  }
  inline unsigned short Get_Z(void) {
    return *((unsigned short*)&local[5]);
  }
  inline void Set_Z(unsigned short value) {
    *((unsigned short*)&local[5]) = value;
  }
};
int main(int argc, char *argv[]) {
  ST rec;
  rec.Set_X(0x41);
  rec.Set_Y(0x42434445);
  rec.Set_Z(0x4647);
  cout << "size of unsigned char = " << sizeof(unsigned char) << endl;
  cout << "size of unsigned short = " << sizeof(unsigned short) << endl;
  cout << "size of unsigned long = " << sizeof(unsigned long) << endl;
  cout << "size of ST = " << sizeof(ST) << endl;
  cout << hex << rec.Get_X() << endl;
  cout << hex << rec.Get_Y() << endl;
  cout << hex << rec.Get_Z() << endl;
  system("PAUSE");	
  return 0;
}
#11

ده بعض ما عندكم :D

#12
usama707 كتب:
ده بعض ما عندكم  :D

آسف يا أسامه , افتكرتك محمد حسام (باشمهندس) , أصل صورتك قريبة منه شوية :D

بس ملعوبة :P

#13

ولا يهمك كلنا مهندسين برضه :rolleyes:

#14
usama707 كتب:
ولا يهمك كلنا مهندسين برضه  :rolleyes:

ايوه يا عم واخد بالي :D "مهندسيييييييين" , لكن "bashmohandes" ده اسمه في البطاقة - أقصد بطاقته في المنتدى :lol: - فبلاش تزوييير :D

واجهزوا كده للعبة الجاية.....

هذا الموضوع مغلق.

مواضيع مشابهة