# برنامه نویسی سطح پایین > توسعه‌ی هسته‌ی سیستم عامل >  توسعه یک زبان برنامه نویسی

## yasser_sajjadi

سلام دوستان
در حال ساخت یک زبان جدید هستم که برای استفاده در سیستم عاملی که مینوشتم ازش استفاده کنم
کدها رو خیلی روان و ساده و قابل فهم نوشتم حجم کمی داره و جای کار داره
دوستانی که مایل به همکاری هستند و در این زمینه کار کردند برای توسعه زبان ایجاد شده بیام بدن تا با هم همکاری کنیم و توسعش بدیم
زبان به صورت متن باز هست و میتونید از آدرس زیر دریافتش کنید

https://github.com/Yasser-Sajjadi/pedar

----------


## farhad_shiri_ex

> سلام دوستان در حال ساخت یک زبان جدید هستم که برای استفاده در سیستم عاملی که مینوشتم ازش استفاده کنم کدها رو خیلی روان و ساده و قابل فهم نوشتم حجم کمی داره و جای کار داره دوستانی که مایل به همکاری هستند و در این زمینه کار کردند برای توسعه زبان ایجاد شده بیام بدن تا با هم همکاری کنیم و توسعش بدیم زبان به صورت متن باز هست و میتونید از آدرس زیر دریافتش کنید  https://github.com/Yasser-Sajjadi/pedar


  با سلام تبریک میگم دوست عزیز کار جالبی انجام دادید امیدوارم موفق باشید. ولی به نظرم بیشتر شبیه یک Evaluator هست تا یک زبان جدید، به این علت که تا جایی که من دقت کردم شما از کلمات کلیدی زبان سی شارپ و نحو و شی گرایی جاوا و تا یک حدی هم از جاوا اسکریپت الگوبرداری کردید. حالا سوال این هست - که اصولا این زبان جدید به گفته شما چه بازدهی داره؟ این که شما نحو استفاده از دستورات را تغییر بدید وبعد در زبان سی آنها را مجددا به نحو اصلیشون تفسیر کنید که بازدهی را به شدت فدای این نحو جدید کردید. بیشتر شبیه زبان کاتلین ویا اسکالا هست که براساس پلت فورم جاوا در حال گسترش هستند البته به نظر من هیچ ایرادی هم نداره که الگوبرداری میکنید. ولی به شرط اینکه صرفا یک پروژه دانشجویی نباشه و انشاالله که در آینده قابل استفاده عموم باشه. و نکته آخر هم اینکه همانطور که می دانید.... برای ساخت یک کامپایلر جدید چند چالش اساسی و اصلی جود داره. 1- مدیریت حافظه  2- مدیریت پردازش ها سطح سیستم عامل 3- مدیریت پردازشگر 4-نحو و صرف دستورات  5- مدیریت وابستگی های کتابخانه ای 6- تولید کد اسمبلی مناسب برای معماری های مختلف 7- تولید کد ماشین مناسب معماری پردازندده 8- تولید کد executable and linkable formt ELF  9- انتخاب پلت فورم ویندور ویا لینوکس ویا مک ویا کراس پلت فورم بودن  .... البته قصد من از گفتن این مطالب این نیست که شما دلسرد شوید ولی بهتره وقتی بیان میکنیم که یک زبان جدید کمی هم درباره اش توضیح بدیم که این موارد را چگونه رفع میکنید؟ ولی اگر هم که مثل خیلی از تکنولوژی های جدید الضهور مانند کاتلین بخواهید براساس یک پلت فورم معتبر مانند جاوا کار کنید که خوب قطعا زبان جدیدی خلق نخواهد شد.

----------


## yasser_sajjadi

> با سلام تبریک میگم دوست عزیز کار جالبی  انجام دادید امیدوارم موفق باشید. ولی به نظرم بیشتر شبیه یک Evaluator هست  تا یک زبان جدید، به این علت که تا جایی که من دقت کردم شما از کلمات  کلیدی زبان سی شارپ و نحو و شی گرایی جاوا و تا یک حدی هم از جاوا اسکریپت  الگوبرداری کردید. حالا سوال این هست - که اصولا این زبان جدید به گفته شما  چه بازدهی داره؟ این که شما نحو استفاده از دستورات را تغییر بدید وبعد در  زبان سی آنها را مجددا به نحو اصلیشون تفسیر کنید که بازدهی را به شدت  فدای این نحو جدید کردید. بیشتر شبیه زبان کاتلین ویا اسکالا هست که براساس  پلت فورم جاوا در حال گسترش هستند البته به نظر من هیچ ایرادی هم نداره که  الگوبرداری میکنید. ولی به شرط اینکه صرفا یک پروژه دانشجویی نباشه و  انشاالله که در آینده قابل استفاده عموم باشه. و نکته آخر هم اینکه همانطور  که می دانید.... برای ساخت یک کامپایلر جدید چند چالش اساسی و اصلی جود  داره. 1- مدیریت حافظه  2- مدیریت پردازش ها سطح سیستم عامل 3- مدیریت  پردازشگر 4-نحو و صرف دستورات  5- مدیریت وابستگی های کتابخانه ای 6- تولید  کد اسمبلی مناسب برای معماری های مختلف 7- تولید کد ماشین مناسب معماری  پردازندده 8- تولید کد executable and linkable formt ELF  9- انتخاب پلت  فورم ویندور ویا لینوکس ویا مک ویا کراس پلت فورم بودن  .... البته قصد من  از گفتن این مطالب این نیست که شما دلسرد شوید ولی بهتره وقتی بیان میکنیم  که یک زبان جدید کمی هم درباره اش توضیح بدیم که این موارد را چگونه رفع  میکنید؟ ولی اگر هم که مثل خیلی از تکنولوژی های جدید الضهور مانند کاتلین  بخواهید براساس یک پلت فورم معتبر مانند جاوا کار کنید که خوب قطعا زبان  جدیدی خلق نخواهد شد.


سلام متشکرم
خب میبخشید که توضیحی ندادم و باید اینکارو میکردم. این زبان به صورت مفسر  هست و یک کامپایلر نیست برای همین قواعدی که فرمودید متفاوت هست. از این رو  کد به صورت کد سطح پردازشگر در نمیاد و به نوع پردازنده بستگی نخواهد داشت  و در پلتفرمهای متفاوت هم بسته به ادرس دهی ها و اختلافات جزءی متفاوت هست  که به سادگی قابل پیاده سازی هست. زبان پایتون هم تا حدودی به همین صورت  هست. برام جالب بود با یک نگاه تونستید یک نمای کلی از اونچه انجام شده  حالا  درست یا غلطش بدست بیارید معلومه مطالعه خوبی در این زمینه  کامپایلرها  داشته اید. از ایده های شما استقبال میکنیم.

خب یک زبان باید قواعد صرفی و نحوی خودش رو داشته باشه:
 این کد هم از این رو که صرف و نحوش متفاوت هست یک زبان متفاوت هست. تقریبا  این زبان کلمه کلیدیش خیلی کم هست و نمیشه اونو از این نظر مشابه بقیه  زبان ها دونست و اونها هم کلمات کلیدی ضروری هستند که نیاز به متفاوت  بودنشون نیست. مثلا کلمات کلیدی  this super print format count if else  while return
خب اینها نیاز به تفسیر متفاوتی ندارند. در زبان هایی که نام بردید شما  باید تعریف کنید که یک کلاس الان باید یک شیء جدید باشه یا نه و از اپراتور  new استفاده میکنید ولی در اینجا خود زبان این رو تشخیص میده و اونو ایجاد  میکنه و همچنین قابلیت هایی داره که در کد نوشته شده که در صفحه ذکر شده  موجود بود نیست و توان برنامه نویس رو افزایش میده. اینکه کلمات مشابهی  استفاده شده دلیل به مشابه بودنش نیست. به عنوان مثال یک حلقه در همه زبان  ها نیاز هست و نیازی نیست تفسیر متفاوتی ازش ارائه بشه. یا مثلا به صورت  خودکار این زبان هوشمند هست. در سی پلاس پلاس برای این کار از تمپلیت  استفاده میکنید در اینجا تمام مقادیر به صورت هوشمند هستند. دقیقا نمیدونم  شما چه انتظاری دارید از یک زبان جدید. هر چند حجمش کم هست ولی خب از یک  پروژه دانشجویی خیلی بیشتر هست و در فکر گسترشش هستم منتها کاری نیست که یک نفر انجامش بده دلچسب باشه هر چند یک نفر هم میتونه. فعلا هم توابع کتاب خوانه ای زیادی  نداره.

 زبان باید مدیریت حافظه مخصوص خودش رو داشته باشه:
مدیریت حافظه به صورت پویا هست به این معنا که بتونه فریم های حافظه و پشته  ها رو به حداقل برسونه.که یک متغیر هر نوع داده ای رو میپیره و حافظه خاصش  رو خودش کنترل میکنه و اینکه به عنوان مثال یه رشته یا یک نوشته نیاز به  یک حافظه یکپارچه نداره بلکه هر کاراکترش میتونه مقدار متفاوتی از حافظه و  از جای متفاوتی از حافظه باشه که این کنترل حافظه رو خیلی باز و راحت کرده.  در زبان هایی که نام بردید خب حافظه هر چند تخصیصش دینامیک هست اما مقدار  تخصیص شده به صورت پشت سر هم هست مثلا اگه یک ساختار ایجاد کردید در این  زبان ها یک قسمت ثابت از حافظه به اون ساختار اختصاص داده میشه یعنی اگر  اون ساختار شامل ده متغیر هست این متغیر ها یک قسمت متناوب از حافظه رو  اشغال میکنند برای همین شما میتونید  اونها رو با ارزش دهی کردن به یک نوع  متفاوت تبدیل کنید. در اینجا به صورت متناوب حافظه اختصاص داده نمیشه. با  اینکه مدیریت حافظه دینامیک داره یعنی برای هر داده ای مقادیر متغیر ها  متفاوت هست در عین حال سرعت خوبی داره و جای کار داره.میشه قابلیتی در مفسر  ایجاد کرد که داده هایی که مدتی استفاده نمیشه با دستگاه ذخیره ساز منتقل  بشه و در عین حال کاهش سرعتی ایجاد نشه

مدیریت کتابخانه ها:
مدیریت کتابخانه ها به صورت مدولار هست - البته هنوز تکمیل نشده و کل کتابخانه رو وارد میکنه - ولی هدف این هست تنها بخش مورد نظر رو وارد کنه و حافظه کمتری اشغال کنه هر چند در این مفسر زبان حافظه زیادی رو اشغال نمیکنه

مدیریت پردازشگر:
اولین هدف این بوده که زبان قوانین دست و پا گیر نداشته باشه. گسترش دهنده  بتونه ایده خودشو به راحتی روش پیاده سازی کنه. فعلا قابلیت همزمانی پردازش  ها و یا چند نخی نداره ولی سعی به توسعه به سمت همزمانی پردازش علاوه بر  چند نخی هست. 

حقیقت امر این هست که دنبال الگوبرداری نبودم هر چند برخی الگوها از زبان  پایتون و wren و سی گرفتم که اون هم به باطن زبان برمیگرده. خب اینکه بخوای توابع با  نامهای متفاوت باشه صرفا کار جدیدی تعریف نمیشه برای همین من توابع رو  مشابه بقیه زبان ها نام گذاری کردم که همین باعث میشه فکر کنید الگو برداری  هست. اون روش هایی که در برنامه نویسی راحتی برنامه نویس رو در پی داشته  سعی کردم در این زبان باشه و شامل نقاط قوت اونها باشه و در عین حال قوانین  خاص اونها رو نداشته باشه تا برنامه نویس نیازی به مطالعه زیاد برای  یادگیری زبان نداشته باشه بلکه بیشتر روی باطن زبان متمرکز بودم. یا مثلا  مقادیر بازگشتی تابع میتونه در یک تابع میتونه از هر نوعی باشه میتونه کلاس  یاشه یا یک عدد باشه یا یک مقدار کاراکتری خاص ویا یک رشته و ارایه و  همینطور مقادیر ورودی هم تعریف محدودیت خاصی نداره

----------


## yasser_sajjadi

یا مثلا در وراثت اینکه کد به صورت

class parent {
parent(){

}
}

class child : public parent {
child(){

}
}


باشه یا به صورت کد پایتون

class Person:
  def __init__(self):

class Student(Person):
  def __init__(self):
   

خب اینها فرقی نداره فقط نحوه نگارشش متفاوت هست همین کارو میشه برای همین زبان هم انجام داد. در پایتون از : به جای { استفاده شده و تابع با def تعریف میشه
خب اینها روی عملکرد زبان تاثیری نداره فقط نگارش متفاوت هست. برای همین من جوری که قابل فهم تره قواعد نگارشی زبان رو تعریف کردم


parent {
this() {

}
}

child : parent {
this() {

}
}


حتی به کلمات کلیدی class یا def نیازی نبوده و ازش استفاده نکردم
استفاده از هر چیزی در صورت ضرورت - ضروری نبود نیاز به تعریفش نیست

----------


## yasser_sajjadi

یا مثلا در وراثت اینکه کد به صورت

class parent {
     parent(){

     }
}

class child : public parent {
     child(){

     }
}


باشه یا به صورت کد پایتون

class Person:
  def __init__(self):

class Student(Person):
  def __init__(self):
   

خب اینها فرقی نداره فقط نحوه نگارشش متفاوت هست همین کارو میشه برای همین زبان هم انجام داد. در پایتون از : به جای { استفاده شده و تابع با def تعریف میشه
خب اینها روی عملکرد زبان تاثیری نداره فقط نگارش متفاوت هست. برای همین من جوری که قابل فهم تره قواعد نگارشی زبان رو تعریف کردم


parent {
     this() {

     }
}

child : parent {
     this() {

     }
}


حتی به کلمات کلیدی class یا def نیازی نبوده و ازش استفاده نکردم
استفاده از هر چیزی در صورت ضرورت - ضروری نبود نیاز به تعریفش نیست

----------


## farhad_shiri_ex

> خب میبخشید که توضیحی ندادم و باید اینکارو میکردم. این زبان به صورت مفسر   هست و یک کامپایلر نیست برای همین قواعدی که فرمودید متفاوت هست. از این  رو  کد به صورت کد سطح پردازشگر در نمیاد و به نوع پردازنده بستگی نخواهد  داشت  و در پلتفرمهای متفاوت هم بسته به ادرس دهی ها و اختلافات جزءی  متفاوت هست  که به سادگی قابل پیاده سازی هست. زبان پایتون هم تا حدودی به  همین صورت  هست. برام جالب بود با یک نگاه تونستید یک نمای کلی از اونچه  انجام شده  حالا  درست یا غلطش بدست بیارید معلومه مطالعه خوبی در این  زمینه  کامپایلرها  داشته اید. از ایده های شما استقبال میکنیم.


تشکر از توضیحاتی که دادید.




> خب یک زبان باید قواعد صرفی و نحوی خودش رو داشته باشه:
>  این کد هم از این رو که صرف و نحوش متفاوت هست یک زبان متفاوت هست. تقریبا   این زبان کلمه کلیدیش خیلی کم هست و نمیشه اونو از این نظر مشابه بقیه   زبان ها دونست و اونها هم کلمات کلیدی ضروری هستند که نیاز به متفاوت   بودنشون نیست. مثلا کلمات کلیدی  this super print format count if else   while return
> خب اینها نیاز به تفسیر متفاوتی ندارند. در زبان هایی که نام بردید شما   باید تعریف کنید که یک کلاس الان باید یک شیء جدید باشه یا نه و از اپراتور   new استفاده میکنید ولی در اینجا خود زبان این رو تشخیص میده و اونو  ایجاد  میکنه و همچنین قابلیت هایی داره که در کد نوشته شده که در صفحه ذکر  شده  موجود بود نیست و توان برنامه نویس رو افزایش میده. اینکه کلمات  مشابهی  استفاده شده دلیل به مشابه بودنش نیست. به عنوان مثال یک حلقه در  همه زبان  ها نیاز هست و نیازی نیست تفسیر متفاوتی ازش ارائه بشه. یا مثلا  به صورت  خودکار این زبان هوشمند هست. در سی پلاس پلاس برای این کار از  تمپلیت  استفاده میکنید در اینجا تمام مقادیر به صورت هوشمند هستند. دقیقا  نمیدونم  شما چه انتظاری دارید از یک زبان جدید. هر چند حجمش کم هست ولی خب  از یک  پروژه دانشجویی خیلی بیشتر هست و در فکر گسترشش هستم منتها کاری  نیست که یک نفر انجامش بده دلچسب باشه هر چند یک نفر هم میتونه. فعلا هم  توابع کتاب خوانه ای زیادی  نداره.


دقیقا منهم موافقم که  تفسیر مجدد رویه  های برنامه نویسی که در زبانهای استاندارد وجود دارد به  یک فرم جدید به هیچ وجه کار عاقلانه ای نیست مگر که زبان کاربرد خاصی داشته  باشه که نحو و صرف رویه های استاندارد در آن متفاوت باشه مثل زبان ruby ,  haskell 
و اگر هم در تاپیک قبلی اشاره نداشتم تصور من این بود که شما در حال طراحی یک زبان جدید و کامپایلر هستید.




> زبان باید مدیریت حافظه مخصوص خودش رو داشته باشه:
> مدیریت حافظه به صورت پویا هست به این معنا که بتونه فریم های حافظه و پشته   ها رو به حداقل برسونه.که یک متغیر هر نوع داده ای رو میپیره و حافظه  خاصش  رو خودش کنترل میکنه و اینکه به عنوان مثال یه رشته یا یک نوشته نیاز  به  یک حافظه یکپارچه نداره بلکه هر کاراکترش میتونه مقدار متفاوتی از  حافظه و  از جای متفاوتی از حافظه باشه که این کنترل حافظه رو خیلی باز و  راحت کرده.  در زبان هایی که نام بردید خب حافظه هر چند تخصیصش دینامیک هست  اما مقدار  تخصیص شده به صورت پشت سر هم هست مثلا اگه یک ساختار ایجاد  کردید در این  زبان ها یک قسمت ثابت از حافظه به اون ساختار اختصاص داده  میشه یعنی اگر  اون ساختار شامل ده متغیر هست این متغیر ها یک قسمت متناوب  از حافظه رو  اشغال میکنند برای همین شما میتونید  اونها رو با ارزش دهی  کردن به یک نوع  متفاوت تبدیل کنید. در اینجا به صورت متناوب حافظه اختصاص  داده نمیشه. با  اینکه مدیریت حافظه دینامیک داره یعنی برای هر داده ای  مقادیر متغیر ها  متفاوت هست در عین حال سرعت خوبی داره و جای کار  داره.میشه قابلیتی در مفسر  ایجاد کرد که داده هایی که مدتی استفاده نمیشه  با دستگاه ذخیره ساز منتقل  بشه و در عین حال کاهش سرعتی ایجاد نشه


خوب  حالا سوال این هست! تخصیص حافظه متغیرهای اتوماتیک یا محلی در stack هست؟  اگر اینطور هست زمانی که بر فرض مثال شما هر کدام از بایت های یک رشته را  دریک خانه از حافظه ذخیره میکنید قطعا باید یک مدیر کنترل حافظه ای هم  داشته باشید که دائما در حال جایگشت گذاری های مناسب در آدرس های حافظه هست  که خوب این کار به بازدهی صدمه میزنه.
ویا اصولا چه نیازی به چنین آدرس دهی بوده؟ 
خوب همانطور که می دانید استک در پلت فورمهای مختلف ظرفیت های مختلفی هم داره! پس یک چالش مدیر حافظه کنترل این ظرفیت است.
حالا  حافظه heap که تقریبا حافظه ای بزرگ هست و بستگی به مقدار حافظه ماشین و  توان آدرس دهی سیستم عامل هست. را چطور کنترل میکنه ؟ مباحثی مثل padding  byte هایی که کامپایلر  C++‎ , C در حافظه ایجاد میکنند جهت آدرس دهی های  معتبر را چگونه پیش بینی کرده اید؟ بله متوجه هستم که شما در حال تولید یک  زبان مفسری هستید ولی به هرحال وقتی میگید که آدرس دهی های شما در آدرس های  مختلف ذخیره میشه این مسائل پیش خواهد آمد.و البته خیلی مسائل دیگر در  آدرس دهی ها که سالهاست دانشمندان کامپیوتر را با چالش مواجه کرده است به  همین علت آدرس دهی هایی که در حال حاضر در کامپایلرها وجود دارد بی شک  کمترین اشکال را دارد و بیشترین سازگاری را با حافظه داخلی ماشین و همچنین  حافظه های کش پردازنده و همچنین ثبات های پردازشگر را دارا می باشند.




> حقیقت امر این هست که دنبال الگوبرداری نبودم هر چند برخی الگوها از زبان   پایتون و wren و سی گرفتم که اون هم به باطن زبان برمیگرده. خب اینکه بخوای  توابع با  نامهای متفاوت باشه صرفا کار جدیدی تعریف نمیشه برای همین من  توابع رو  مشابه بقیه زبان ها نام گذاری کردم که همین باعث میشه فکر کنید  الگو برداری  هست. اون روش هایی که در برنامه نویسی راحتی برنامه نویس رو  در پی داشته  سعی کردم در این زبان باشه و شامل نقاط قوت اونها باشه و در  عین حال قوانین  خاص اونها رو نداشته باشه تا برنامه نویس نیازی به مطالعه  زیاد برای  یادگیری زبان نداشته باشه بلکه بیشتر روی باطن زبان متمرکز  بودم. یا مثلا  مقادیر بازگشتی تابع میتونه در یک تابع میتونه از هر نوعی  باشه میتونه کلاس  یاشه یا یک عدد باشه یا یک مقدار کاراکتری خاص ویا یک  رشته و ارایه و  همینطور مقادیر ورودی هم تعریف محدودیت خاصی نداره


منهم  با این حرف شما موافقم و اینکه زبانهای برنامه نویسی خیلی پیچیده و سخت  مثل C,C++‎,Ruby را بتوان به یک زبان ساده تر تبدیل کرد کار ارزشمندی ولی  همیشه این نکته را باید توجه کنید که بازدهی نباید خیلی فدای راحتی کد  نویسی بشه البته که خواه ناخواه کمی از بازدهی را از دست میدید ولی به  هرحال اگر میزان بازدهی خوب نباشه قطعا استقبال خوبی نمیشه از این زبان.

----------


## farhad_shiri_ex

> یا مثلا در وراثت اینکه کد به صورت
> 
> class parent {
>      parent(){
> 
>      }
> }
> 
> class child : public parent {
> ...


خوب منهم تا بخشی موافقم !
اما  شما باید مصرف کننده هدف تون را مشخص کنید؟ آیا کسانی که به برنامه نویسی  مسلط هستند در زبانهای دیگر با زبان شما می خواهند کار کنند ویا کسانی که  هیچ تجربه ای ندارند؟
به نظرم تفاوتهای زیادی دراین دو گروه می تونه  وجود داشته باشه حالا که قصد طراحی یک مفسر را دارید پیشنهاد میکنم که توجه  بیشتری به مسئله بازخورد زبان برنامه نویسی در میان برنامه نویسان داشته  باشید و به نظرم بی مهبا یک طیفی از کلمات کلیدی را که تقریبا ستون فقرات  یک زبان هستند را حذف نکنید.

----------


## yasser_sajjadi

> دقیقا منهم موافقم که  تفسیر مجدد رویه  های برنامه نویسی که در زبانهای استاندارد وجود دارد به  یک فرم جدید به هیچ وجه کار عاقلانه ای نیست مگر که زبان کاربرد خاصی داشته  باشه که نحو و صرف رویه های استاندارد در آن متفاوت باشه مثل زبان ruby ,  haskell


خب به هر حال ما محکوم به باز نویسی بخشی از زبان خواهیم بود و هدف گسترش کاربرد زبان هایی مثل سی هست. همچنین ایده پردازی برای زبانی که شناختی ازش نداری کاری سخت هست پس نیاز به زبانی هست که بشه براش ایده پردازی کرد.




> خوب  حالا سوال این هست! تخصیص حافظه متغیرهای اتوماتیک یا محلی در stack هست؟  اگر اینطور هست زمانی که بر فرض مثال شما هر کدام از بایت های یک رشته را  دریک خانه از حافظه ذخیره میکنید قطعا باید یک مدیر کنترل حافظه ای هم  داشته باشید که دائما در حال جایگشت گذاری های مناسب در آدرس های حافظه هست  که خوب این کار به بازدهی صدمه میزنه.
> ویا اصولا چه نیازی به چنین آدرس دهی بوده؟ 
> خوب همانطور که می دانید استک در پلت فورمهای مختلف ظرفیت های مختلفی هم داره! پس یک چالش مدیر حافظه کنترل این ظرفیت است.
> حالا  حافظه heap که تقریبا حافظه ای بزرگ هست و بستگی به مقدار حافظه ماشین و  توان آدرس دهی سیستم عامل هست. را چطور کنترل میکنه ؟ مباحثی مثل padding  byte هایی که کامپایلر  C++‎‎ , C در حافظه ایجاد میکنند جهت آدرس دهی های  معتبر را چگونه پیش بینی کرده اید؟ بله متوجه هستم که شما در حال تولید یک  زبان مفسری هستید ولی به هرحال وقتی میگید که آدرس دهی های شما در آدرس های  مختلف ذخیره میشه این مسائل پیش خواهد آمد.و البته خیلی مسائل دیگر در  آدرس دهی ها که سالهاست دانشمندان کامپیوتر را با چالش مواجه کرده است به  همین علت آدرس دهی هایی که در حال حاضر در کامپایلرها وجود دارد بی شک  کمترین اشکال را دارد و بیشترین سازگاری را با حافظه داخلی ماشین و همچنین  حافظه های کش پردازنده و همچنین ثبات های پردازشگر را دارا می باشند.


خب پشته ها در معمولا به صورت استاتیکی و ثبات یافته تعریف می شوند تا فرایند بازیابی را ساده سازی کنند و بازده را بالا ببرند
چند موضوع هست که باید مورد توجه قرار داد:
اول - پشته میشه به صورت linked-list باشه این سبب میشه هر رشته رو بتونی هر مقداری که نیاز داری ارزش دهی کنی و در عین حال فرایند جایگشتی نیاز نداره و دستری به حافظه رو بسیار سرعت میبخشه.
دوم - بخشی از عملکرد به عملکرد سیستم و پلتفرم برمیگرده که این خارج از حوزه کاری زبان های مفسری و پویا هست.
سوم - با افزایش فرکانس کاری پردازشگر ها زیاد فرایند ها قابل توجه نخواهد بود و بازدهی زبان اهمیت کمی خواهد داشت هر چند مهم هست و این برای من اهمیت دارد.

فرض کنید شما یک رشته نیاز دارید و میخواهید یک عبارت را به قسمتی از ان اضافه یا از ان را حذف کنید. برای این کار شما باید مقدار حافظه کل مورد نیاز را تخمین بزنید- بخش ها تک تک به درون ان کپی کنید - حالا اگر شما بتوانید بدون کپی کردن یک کاراکتر را به درون این بخش اضافه کنید یا از ان کم کنید هم فرایند برای شما ساده سازی میشود و هم سرعت بیشتری خواهد داشت.

به عنوان مثال در زبان سی


char *data = malloc(100);
*data = 'a';
data += sizeof(char);
*data = 100;
data+=sizeof(int);


خب شما این پشته را ارزش دهی کردید- و مقادیر عددی و کاراکتری را به آن اختصاص دادید- چگونه نوع ارزش دهی را در هنگام بازیابی و استفاده مشخص میکنید- مثلا از کجا میتوانید تشخیص بدهید خانه بعدی از حافظه پشته یک عدد است و یک کاراکتر نیست. و حالا اگر بخواهید مقدار عددی را به مقدار کاراکتری تبدیل کنید- این عدد به کاراکتر خاص تبدیل میشود اما حافطه مورد استفاده ان به اندازه یک مقدار عددی خواهد بود و در نتیجه مقدار از حافظه بی مورد از دست میرود - این علت نیاز به چنین اختصاص حافظه ای است. شما هر قسمت از پشته را میتوانید کاهش یا گسترش دهید.
یعنی در این زبان خانه nام از حافظه میتواند از هر نوعی باشد و به هر نوعی تبدیل شود و یا به کل حذف شود.



> منهم  با این حرف شما موافقم و اینکه زبانهای برنامه نویسی خیلی پیچیده و سخت  مثل C,C++‎‎,Ruby را بتوان به یک زبان ساده تر تبدیل کرد کار ارزشمندی ولی  همیشه این نکته را باید توجه کنید که بازدهی نباید خیلی فدای راحتی کد  نویسی بشه البته که خواه ناخواه کمی از بازدهی را از دست میدید ولی به  هرحال اگر میزان بازدهی خوب نباشه قطعا استقبال خوبی نمیشه از این زبان.


سعی در افزایش بازدهی هست - الان بیشتر برنامه نویسان مبتدی از زبان سی شارپ استفاده میکنند - با اینکه بازدهی ان در برابر بازدهی سی و سی پلاس پلاس به مراتب کمتر است. اما به دلیل سهولت استفاده و یادگیری و قابل فهم بودن ترجیح به استفاده از این زبان دارند. اما زبان سی شارپ به شدت مقید و کنترل شده عمل میکند -  هدف من افزایش بازده و در عین حال سادگی زبان هست حالا چقدر موفق باشیم تا حدودی به ابتکار دوستان و نظرات مخاطبان و راهنمایی آنها بستگی دارد.
اگر نقاط ضعف مشخص باشد میشود چاره انیشی کرد.

----------


## farhad_shiri_ex

> اول - پشته میشه به صورت linked-list باشه این سبب میشه هر رشته رو بتونی  هر مقداری که نیاز داری ارزش دهی کنی و در عین حال فرایند جایگشتی نیاز  نداره و دستری به حافظه رو بسیار سرعت میبخشه.


این که با  گفته شما مبنی بر آدرس دهی های متفاوت در تناقض هست! در لیست پیوندی هر  عضوی آدرس عضو بعدی را داره که قطعا هم به صورت ترتیبی آدرس دهی شده اند




> دوم - بخشی از عملکرد به عملکرد سیستم و پلتفرم برمیگرده که این خارج از حوزه کاری زبان های مفسری و پویا هست.
> سوم - با افزایش فرکانس کاری پردازشگر ها زیاد فرایند ها قابل توجه نخواهد  بود و بازدهی زبان اهمیت کمی خواهد داشت هر چند مهم هست و این برای من  اهمیت دارد.


در مورد دوم بله تاقسمتی بر عملکرد سیستم هست ولی قطعا نحوه تفسیر دستورات شما هم در این عملکرد نقش زیادی خواهند داشت.
درباره  فرکانس کاری پردازش ها تقریبا در چند سال گذشته به علت تولید گرما و انرژی  زیاد خیلی فرکانس پردازشگر را تغییر نمیدهند و از تکنولوژی های NUMA حافظه  کش اشتراکی استفاده میکنند ویا هسته های فیزیکی ویا هسته های منطقی را  افزایش میدهند که خوب با این تفاسیر برنامه های ترتیبی سود چندانی از این  تکنولوژی ها نخواهند برد و کماکان سیستم عامل برای اجرای شبه موازی پردازه  ها باید به زمان بند و تعویض متن تکیه داشته باشد که توضیح بیشتر درباره  این مقوله از حوصله تاپیک خارج است.



> خب شما این پشته را ارزش دهی کردید- و مقادیر عددی و کاراکتری را به آن  اختصاص دادید- چگونه نوع ارزش دهی را در هنگام بازیابی و استفاده مشخص  میکنید- مثلا از کجا میتوانید تشخیص بدهید خانه بعدی از حافظه پشته یک عدد  است و یک کاراکتر نیست. و حالا اگر بخواهید مقدار عددی را به مقدار  کاراکتری تبدیل کنید- این عدد به کاراکتر خاص تبدیل میشود اما حافطه مورد  استفاده ان به اندازه یک مقدار عددی خواهد بود و در نتیجه مقدار از حافظه  بی مورد از دست میرود - این علت نیاز به چنین اختصاص حافظه ای است. شما هر  قسمت از پشته را میتوانید کاهش یا گسترش دهید.
> یعنی در این زبان خانه nام از حافظه میتواند از هر نوعی باشد و به هر نوعی تبدیل شود و یا به کل حذف شود.


الان  در مثالی که قرار دادید شما در subscript -0 آرایه حرف a را مقدار دهی  کردید و بعد به آفست بعدی آرایه یعنی subscript -1 اشاره کردید و مقدار  لیترال ثابت عددی 100 را قرار دادید که خوب بازهم یک بایت هست بعد هم که  آفست را 4 عدد گسترش دادید وبه داریه 6 اشاره کردید حالا کجا حافظه از دست  رفته؟
یعنی می فرمایید که اگر درایه 2 را که عدد 100 را نگه داشته با یک  char کست صریح انجام بدیم مقدار بلوک های حافظه برای نگه داری این 100  چهار بلوک هست؟ اگر اینطور که قطعا اشتباه میکنید وقتی شما یک آرایه با 100  بلوک یک بایتی تعریف میکنید یعنی در هر درایه از آرایه می توانید 127+ /  128- را ذخیره کنید البته چون بدون علامت تعریف کردید و اگر هم که با علامت  باشه تا 255 عدد را می توان ذخیره کرد که همه در یک بایت ذخیره می شوند.  البته من تا بحال ندیدم که تغییر افست روی مقدار بلاک های آدرس دهی شده  آرایه تاثیری داشته باشه!
اتلاف حافظه معمولا زمانی رخ میده که آرایه با  طول ثابت تعریف بشه ولی همیشه مقدارهای کمتری از حد آرایه در آن ذخیره بشه  که خوب در اینطور مواقع هم که از آرایه های کانتینری استفاده میشه.
ویا  اتلاف حافظه دیگری که معمولا رخ میده در padding بایت هایی هست که  کامپایلر در ساختارها قرار میده که این مشکل را هم معمولا با تعریف یک فیلد  padding در ساختار مرتفع میکنند و حالا حداقل برنامه نویس به اون بایت های  padding دسترسی داره!



> سعی در افزایش بازدهی هست - الان بیشتر برنامه نویسان مبتدی از زبان سی  شارپ استفاده میکنند - با اینکه بازدهی ان در برابر بازدهی سی و سی پلاس  پلاس به مراتب کمتر است. اما به دلیل سهولت استفاده و یادگیری و قابل فهم  بودن ترجیح به استفاده از این زبان دارند. اما زبان سی شارپ به شدت مقید و  کنترل شده عمل میکند -  هدف من افزایش بازده و در عین حال سادگی زبان هست  حالا چقدر موفق باشیم تا حدودی به ابتکار دوستان و نظرات مخاطبان و  راهنمایی آنها بستگی دارد.
> اگر نقاط ضعف مشخص باشد میشود چاره انیشی کرد.


تا یک بخشی موافقم ولی دوست گرامی! البته من خودم زمینه اصلی کارم سی شارپ نیست ولی  CLI سی شارپ خارق العاده هوشمند هست ویا زبان اسمبلی IL فوق العاده طراحی شده ویا ماشین زمان JIT واقعا هوشمند هست. البته این را هم عرض کردم که بگم یادگیری سی شارپ به صورت حرفه ای هم کار ساده ای نیست! البته منظور شما را از مقید متوجه نشدم ولی در هر حال در زبانهای نوع گرا کلمات کلیدی زیادی استفاده میشه که خوب این هم جای بحث داره و بحث بازدهی هم خوب وقتی بحث استفاده از یک ماشین زمان و زبان اسمبلی خاص میشه و وقتی همه اشیا در این زبان به یک والد ختم میشوند اینجا بحث تبدیل هایی پیش میاد که در بازدهی تاثیر گذار هستند ولی انقدر فواید دارند که به برخی از این اشکالات نمیشه خرده گرفت.
به هر حال هدف من کمک بود دوست عزیز امیدوارم موفق و پیروز باشید.

----------


## yasser_sajjadi

> این که با  گفته شما مبنی بر آدرس دهی های متفاوت در تناقض هست! در لیست پیوندی هر  عضوی آدرس عضو بعدی را داره که قطعا هم به صورت ترتیبی آدرس دهی شده اند


خب همین که ادرس عضو رو داره کمک میکنه دیگه- شما عضو رو دارید و وقتی عضو بعد رو میخواید کافی هست ادرس بعدی رو بدست بیارید و به این معنی نیست که هر بار از اولین ارایه تا اون ارایه شمارش کنید. و یا اگر میخواید حذفش کنید لینک قبل و بعدش رو به هم متصل میکنید - از طرفی اون ارایه هر مقداری رو میشه براش ارزش دهی کرد مثلا ۴ بایت میتونه باشه یا ۸ یا ۱۶ ... تناقض نداره که ! شما یه پشته بدون پیوند که داشته باشید باید یک مقدار ثابت برای هر ارایه در نظر بگیرید و با حذف اون مقدار برای یافتن دوباره مقادیر آزاد نیاز به جستجو هست ولی در این روش مقدار رو ارزش دهی میکنید و به اول یا اخر لیست متصل میکنید. بنابراین نیاز به جستجو نداره و همین تسریع میکنه روند رو. یه نگاهی به فرایند ادرس دهی در کد ها بندازید متوجه میشید.




> در مورد دوم بله تاقسمتی بر عملکرد سیستم هست ولی قطعا نحوه تفسیر دستورات شما هم در این عملکرد نقش زیادی خواهند داشت.
> درباره  فرکانس کاری پردازش ها تقریبا در چند سال گذشته به علت تولید گرما و انرژی  زیاد خیلی فرکانس پردازشگر را تغییر نمیدهند و از تکنولوژی های NUMA حافظه  کش اشتراکی استفاده میکنند ویا هسته های فیزیکی ویا هسته های منطقی را  افزایش میدهند که خوب با این تفاسیر برنامه های ترتیبی سود چندانی از این  تکنولوژی ها نخواهند برد و کماکان سیستم عامل برای اجرای شبه موازی پردازه  ها باید به زمان بند و تعویض متن تکیه داشته باشد که توضیح بیشتر درباره  این مقوله از حوصله تاپیک خارج است.


فرایند همزمانی برای همین موضوع هست البته هنوز شروعش نکردم. قطعا اخر راه تکنولوژی نیست.




> الان  در مثالی که قرار دادید شما در subscript -0 آرایه حرف a را مقدار دهی  کردید و بعد به آفست بعدی آرایه یعنی subscript -1 اشاره کردید و مقدار  لیترال ثابت عددی 100 را قرار دادید که خوب بازهم یک بایت هست بعد هم که  آفست را 4 عدد گسترش دادید وبه داریه 6 اشاره کردید حالا کجا حافظه از دست  رفته؟


اول متوجه باشید که در ارایه اول یک متغیر از نوع char  تعریف شده و در ارایه دوم ادرس یک متغیر از نوع int  - حالا شما میخواهید نوع int را تا int_max مقدار دهی کنید - و بعد از آن در فرایندی این متغیر یک مقدار کراکتری را ذخیره خواهد کرد - در این صورت حافظه بی مورد اشغال شده و از دست رفته است - اگر شما در متغیری که به آن ۴ بایت برای یک عدد ۳۲ بیتی اختصاص داده شده و این عدد ثابت نیست یعنی میتواند ۱۰۰ باشد یا بیشتر یعنی میتواند تا چهار بایت بزرک شود و پس از فرایندی بخواهید آن را به یک کارکتر مثل 'b' اختصاص دهید قطعا بخشی از حافظه از دست رفته است و یا شما باید یک فرایند پیچیده برای تقسیم و جدا سازی حافظه داشته باشید! پس چطور حافظه از دست نمی رود!



> یعنی می فرمایید که اگر درایه 2 را که عدد 100 را نگه داشته با یک  char کست صریح انجام بدیم مقدار بلوک های حافظه برای نگه داری این 100  چهار بلوک هست؟ اگر اینطور که قطعا اشتباه میکنید وقتی شما یک آرایه با 100  بلوک یک بایتی تعریف میکنید یعنی در هر درایه از آرایه می توانید 127+ /  128- را ذخیره کنید البته چون بدون علامت تعریف کردید و اگر هم که با علامت  باشه تا 255 عدد را می توان ذخیره کرد که همه در یک بایت ذخیره می شوند.  البته من تا بحال ندیدم که تغییر افست روی مقدار بلاک های آدرس دهی شده  آرایه تاثیری داشته باشه!
> اتلاف حافظه معمولا زمانی رخ میده که آرایه با  طول ثابت تعریف بشه ولی همیشه مقدارهای کمتری از حد آرایه در آن ذخیره بشه  که خوب در اینطور مواقع هم که از آرایه های کانتینری استفاده میشه.
> ویا  اتلاف حافظه دیگری که معمولا رخ میده در padding بایت هایی هست که  کامپایلر در ساختارها قرار میده که این مشکل را هم معمولا با تعریف یک فیلد  padding در ساختار مرتفع میکنند و حالا حداقل برنامه نویس به اون بایت های  padding دسترسی داره!


عزیز جان - بله ۴ بلوک برای یک مقدار عددی ۳۲ بیتی نیاز هست. چرا ؟ چون شما اون متغییر که این قسمت از حافظه رو بهش اختصاص دادید ممکنه به یک عدد بزرگتر ارزش دهی بشه- مثلا شما میخواید جمع ۱ تا n را محاسبه کنید- عدد ۱۰۰ ام ۱۰۰ هست ولی عدد اخر n هست- در این ادرس دهی شما مجبورید که برای این عدد بیشترین حد لازم رو تعریف کنید- حالا عدد میخواد صفر باشه یا بیشتر و یا باید یک خانه دیگر از حافظه رو بهش اختصاص بدید که با این کار مقدار زیادی از حافظه بی مورد از دست میره- این هم یک مثال بود
حالا فرض کنید همون متغیر بخواد یک مقدار رشته ای رو در خودش ذخیره کنه- ایا اون ۴ بایت کفایت میکنه؟ بسته به طول رشته خیر - خب همین باعث اتلاف حافظه میشه و مثال بنده هم گویای همین هست- یعنی یک عدد مثل ۱۰۰باید ۴ بایت اختصاص داد و یا در ۱ یا ۲ بایت هم نمیشود یک عدد بزرگ ذخیره کرد به ناچار حافظه یا از دست میرود یا نیاز به جستجو برای تخصیص حافظه در پشته هست. مطمعن باشید از این اصول پایه خیلی بیشتر متوجه و بلدم.




> تا یک بخشی موافقم ولی دوست گرامی! البته من خودم زمینه اصلی کارم سی شارپ نیست ولی  CLI سی شارپ خارق العاده هوشمند هست ویا زبان اسمبلی IL فوق العاده طراحی شده ویا ماشین زمان JIT واقعا هوشمند هست. البته این را هم عرض کردم که بگم یادگیری سی شارپ به صورت حرفه ای هم کار ساده ای نیست! البته منظور شما را از مقید متوجه نشدم ولی در هر حال در زبانهای نوع گرا کلمات کلیدی زیادی استفاده میشه که خوب این هم جای بحث داره و بحث بازدهی هم خوب وقتی بحث استفاده از یک ماشین زمان و زبان اسمبلی خاص میشه و وقتی همه اشیا در این زبان به یک والد ختم میشوند اینجا بحث تبدیل هایی پیش میاد که در بازدهی تاثیر گذار هستند ولی انقدر فواید دارند که به برخی از این اشکالات نمیشه خرده گرفت.


نگفتم سی شارپ بدرد نخوره که! اما یادگیری پایه اون قابل فهم تر هست برای  همین بیشتر به سمت این زبان رو میاورند - البته خب دلایل دیگری هم هست ولی  یک مبتدی ازش سر در نمیاره که بخواد جذب سی شارپ بشه. در هر صورت وقتی  طراحی کامل تر شد میشه بخشی از برنامه رو با اسمبلی نوشت. مقید بودن به این معناست که برای هر فرایند قیدی تعیین شده- یعنی هر نوع عددی مقداری ثابت از حافظه رو داره-در صورت تبدیل ممکنه مقداری از عدد از دست بره- سطوح مختلفی از حافظت شده - عمومی - خصوصی تعریف شده و ...




> به هر حال هدف من کمک بود دوست عزیز امیدوارم موفق و پیروز باشید.


بله متوجهم - تشکر از نظرات شما

----------


## farhad_shiri_ex

> خب همین که ادرس عضو رو داره کمک میکنه دیگه- شما عضو رو دارید و وقتی عضو بعد رو میخواید کافی هست ادرس بعدی رو بدست بیارید و به این معنی نیست که هر بار از اولین ارایه تا اون ارایه شمارش کنید. و یا اگر میخواید حذفش کنید لینک قبل و بعدش رو به هم متصل میکنید - از طرفی اون ارایه هر مقداری رو میشه براش ارزش دهی کرد مثلا ۴ بایت میتونه باشه یا ۸ یا ۱۶ ... تناقض نداره که ! شما یه پشته بدون پیوند که داشته باشید باید یک مقدار ثابت برای هر ارایه در نظر بگیرید و با حذف اون مقدار برای یافتن دوباره مقادیر آزاد نیاز به جستجو هست ولی در این روش مقدار رو ارزش دهی میکنید و به اول یا اخر لیست متصل میکنید. بنابراین نیاز به جستجو نداره و همین تسریع میکنه روند رو. یه نگاهی به فرایند ادرس دهی در کد ها بندازید متوجه میشید.


بله من هم به همین مطلب اشاره کردم که لیست پیوندی چه مکانیزمی داره ! منتهی چه ربطی به آدرس دهی متغیرها در حافظه استک یا هیپ داره! اگرهم منظورتون این هست که با مکانیزم لیست پیوندی آدرس دهی کنید که کلی چالش داره بحث سرعت و بازدهی و اتلاف حافظه ...




> اول متوجه باشید که در ارایه اول یک متغیر از نوع char تعریف شده و در ارایه دوم ادرس یک متغیر از نوع int - حالا شما میخواهید نوع int را تا int_max مقدار دهی کنید - و بعد از آن در فرایندی این متغیر یک مقدار کراکتری را ذخیره خواهد کرد - در این صورت حافظه بی مورد اشغال شده و از دست رفته است - اگر شما در متغیری که به آن ۴ بایت برای یک عدد ۳۲ بیتی اختصاص داده شده و این عدد ثابت نیست یعنی میتواند ۱۰۰ باشد یا بیشتر یعنی میتواند تا چهار بایت بزرک شود و پس از فرایندی بخواهید آن را به یک کارکتر مثل 'b' اختصاص دهید قطعا بخشی از حافظه از دست رفته است و یا شما باید یک فرایند پیچیده برای تقسیم و جدا سازی حافظه داشته باشید! پس چطور حافظه از دست نمی رود!


اول که من متوجه شدم! اگر منظورتون از آرایه اول و آرایه دوم اندیس های آرایه data هست(چون من که فقط یک آرایه در مثال شما مبینم) در اندیس دوم آرایه data آدرس یک متغیر از نوع int کجا تعریف شده چون من که همچنین متغیری نمیبینم فقط یک Rvalue literal int مقدار دهی شده نه آدرسش اصولا یک temp var که نمیتونه آدرس معتبر داشته باشه و در ضمن وقتی که همچنین آرایه ای تعریف میکنید کامپایلر همه عضوها را به signed int8_t تفسیر میکنه حالا چه یک char باشه چه عدد 100 باشه اگر هم که عدد بزرگتر از int8_t max باشه بایتهای با ارزش ازدست میره و تنها علامت منفی باقی خواهد ماند.
و بخش دوم صحبت شما که هیچ ربطی به تعریف آرایه نداره! بله اگر یک متغیر از نوع int داشته باشیم وعدد 100 را درون آن ذخیره کرده باشیم و بعد از اینکه با یک explicit cast به یک کاراکتر تبدیل کنیم بله 3 بایت متغیر int بلا استفاده میشه ولی اتلافی اتفاق نخواهد افتاد چون اگر در استک تعریف شده باشه که کامپایلر بلافاصله بعد از اتمام حوزه عملکرد متغیر حافظه را مجددا به سیستم عامل بر میگردونه اگر هم که در هیپ باشه و اگر هوشمند تعریف نشده باشه برنامه نویس موظف به باز پس گیری خواهد بود.




> عزیز جان - بله ۴ بلوک برای یک مقدار عددی ۳۲ بیتی نیاز هست. چرا ؟ چون شما اون متغییر که این قسمت از حافظه رو بهش اختصاص دادید ممکنه به یک عدد بزرگتر ارزش دهی بشه- مثلا شما میخواید جمع ۱ تا n را محاسبه کنید- عدد ۱۰۰ ام ۱۰۰ هست ولی عدد اخر n هست- در این ادرس دهی شما مجبورید که برای این عدد بیشترین حد لازم رو تعریف کنید- حالا عدد میخواد صفر باشه یا بیشتر و یا باید یک خانه دیگر از حافظه رو بهش اختصاص بدید که با این کار مقدار زیادی از حافظه بی مورد از دست میره- این هم یک مثال بود
> حالا فرض کنید همون متغیر بخواد یک مقدار رشته ای رو در خودش ذخیره کنه- ایا اون ۴ بایت کفایت میکنه؟ بسته به طول رشته خیر - خب همین باعث اتلاف حافظه میشه و مثال بنده هم گویای همین هست- یعنی یک عدد مثل ۱۰۰باید ۴ بایت اختصاص داد و یا در ۱ یا ۲ بایت هم نمیشود یک عدد بزرگ ذخیره کرد به ناچار حافظه یا از دست میرود یا نیاز به جستجو برای تخصیص حافظه در پشته هست. مطمعن باشید از این اصول پایه خیلی بیشتر متوجه و بلدم.


در هر حال دوست گرامی با این تحلیل ها واستدلال های شما ما باید کلا در حال اتلاف حافظه باشیم و با اجرای هر برنامه کلی از بلوک های حافظه غیر قابل آدرس دهی باشه!  :متعجب:  :متفکر: که چنین چیزی اصلا امکان نداره بی زحمت اگر به لیست پردازش ها و نخ های در حال اجرا سیستم عامل خودتون مراجعه کنید خواهید دید که این حجم از پردازه و ها نخ ها با کمترین میزان اشغال حافظه در حال کار هستند.
واینکه چه کسی گفته که برای یک عدد 100 باید چهار بایت اختصاص داد یک بایت هم کافی حتی 7 بیت هم کافی هست نیازی به 32 بیت نیست و خوب اینهم بدیهی است که در یک 1 یا 2 بایت نتوان یک عدد بزرگ ذخیره کرد حالا چه ربطی به اتلاف حافظه داره.
و نکته آخر انشاالله که همانطور که می فرمایید اصول پایه را درست بلد باشید.

----------


## yasser_sajjadi

> بله من هم به همین مطلب اشاره کردم که لیست پیوندی چه مکانیزمی داره ! منتهی چه ربطی به آدرس دهی متغیرها در حافظه استک یا هیپ داره! اگرهم منظورتون این هست که با مکانیزم لیست پیوندی آدرس دهی کنید که کلی چالش داره بحث سرعت و بازدهی و اتلاف حافظه ...


خب پایینتر خودتون جواب خودتون رو دادید - باید با سازو کار مفسر بیشتر اشنا بشید- متوجه میشید - متوجه حرف شما هستم - ولی خب شما ساز و کاری که در نظر گرفته شده رو در نظر نگرفتید شایدم کلا ندید که متوجه نشدید. باید مفسر را بررسی کنید.




> اول که من متوجه شدم! اگر منظورتون از آرایه اول و آرایه دوم اندیس های آرایه data هست(چون من که فقط یک آرایه در مثال شما مبینم) در اندیس دوم آرایه data آدرس یک متغیر از نوع int کجا تعریف شده چون من که همچنین متغیری نمیبینم فقط یک Rvalue literal int مقدار دهی شده نه آدرسش اصولا یک temp var که نمیتونه آدرس معتبر داشته باشه و در ضمن وقتی که همچنین آرایه ای تعریف میکنید کامپایلر همه عضوها را به signed int8_t تفسیر میکنه حالا چه یک char باشه چه عدد 100 باشه اگر هم که عدد بزرگتر از int8_t max باشه بایتهای با ارزش ازدست میره و تنها علامت منفی باقی خواهد ماند.


بله منظورم درایه بوده نوشتم ارایه-  به اندازه int بهش اختصاص داده شده- قبلا هم توضیح دادم که عدد متغیر هست و ثابت نیست- خود شما هم میگید ۱۰۰ توی یک بایت جا میشه اگر بخوای عدد بیشتری مقدار دهی کنی اون خونه رو به intتبدیل میکنی اون موقع

*(int *)data = 5000;


الان مشخصه که داده از نوع ۳۲ بیت هست ؟ برادر این متغیر هست- متغیر - متغیر
ثابت نیست- چکار دارید توش ۱۰۰ هست - اون یک مثال هست  - مثال - مثال




> و بخش دوم صحبت شما که هیچ ربطی به تعریف آرایه نداره! بله اگر یک متغیر از نوع int داشته باشیم وعدد 100 را درون آن ذخیره کرده باشیم و بعد از اینکه با یک explicit cast به یک کاراکتر تبدیل کنیم بله 3 بایت متغیر int بلا استفاده میشه ولی اتلافی اتفاق نخواهد افتاد چون اگر در استک تعریف شده باشه که کامپایلر بلافاصله بعد از اتمام حوزه عملکرد متغیر حافظه را مجددا به سیستم عامل بر میگردونه اگر هم که در هیپ باشه و اگر هوشمند تعریف نشده باشه برنامه نویس موظف به باز پس گیری خواهد بود.


خب اگر معتقدید که اینطوری اون سه بایت اتلاف نشده پس چطور معتقدید که حافظه در لیست پیوندی به خاطر ادرس دهی ها اتلاف میشه! به قول خود شما به حافظه برمیگیرده پس از هر فرایند  :متفکر:  یا معتقدید اینجا باید اتلاف حساب کرد اونجا نه!!!  :تشویق: 





> در هر حال دوست گرامی با این تحلیل ها واستدلال های شما ما باید کلا در حال اتلاف حافظه باشیم و با اجرای هر برنامه کلی از بلوک های حافظه غیر قابل آدرس دهی باشه! که چنین چیزی اصلا امکان نداره بی زحمت اگر به لیست پردازش ها و نخ های در حال اجرا سیستم عامل خودتون مراجعه کنید خواهید دید که این حجم از پردازه و ها نخ ها با کمترین میزان اشغال حافظه در حال کار هستند.
> واینکه چه کسی گفته که برای یک عدد 100 باید چهار بایت اختصاص داد یک بایت هم کافی حتی 7 بیت هم کافی هست نیازی به 32 بیت نیست و خوب اینهم بدیهی است که در یک 1 یا 2 بایت نتوان یک عدد بزرگ ذخیره کرد حالا چه ربطی به اتلاف حافظه داره.
> و نکته آخر انشاالله که همانطور که می فرمایید اصول پایه را درست بلد باشید.


باید روی مفهوم متغیر بیشتر کار کنید متوجه خواهید شد چرا برای ۱۰۰ چهار بایت لازم است.
یک مفسر هم بنویسید به جواب بقیه سوالاتتان خواهید رسید.

و نکته اخر اینکه متن ها رو درست بخونید که سوالات رو تکرار نکنید - تقریبا چندین بار گفتم نوع متغیر ها ثابت نیست - اولین اشتباه شما این هست که شما فکر میکنید من یک زبان رو باز نویسی کردم - از این رو انتظار دارید همان کلید واژه ها در این زبان هم باشند - بعد متوجه نیستید که برای هر متغیر مقدار ثابتی تعریف نمیشود برای همین هر چند توضیح دادم باز هم متوجه نمیشوید چرا اتلاف رخ میدهد - یک مفسر بنویسید که داده ها متغیر باشند  متوجه می شوید.

حتما در هنگام نوشتن کد متوجه اتلاف حافظه و سرعت بودم و چاره اندیشی کردم حالا موثر بوده تا حدودی هر چند بهترین حالت ممکن نبوده و بنده هم همچین ادعایی نداشتم و در نظر داشته باشید کد ها رو به تکامل هستند - نه رو به عقب - پس وقتی نوشته میشوند از بهترین حالت برخوردار نخواهند بود- برای همین هم دوستان رو به همکاری دعوت کردم - خب هر کس یه ایده داره - نگفتم بیاین ببینین عجب چیزی نوشتم که  :قهقهه:  - گفتم بیاین ببینین چطور کاستی هاشو رفع کنیم. این یعنی کد در بهترین حالت نیست. فعلا فقط یک سازو کار اولیه هست که مشکل عموم نوشتن همین ساز و کار اولیس بعدش میشه ایده پردازی کرد و اینکه یک سری مزایا داره و یک سری معایب




> سلام دوستان
> در حال ساخت یک زبان جدید هستم که برای استفاده در سیستم عاملی که مینوشتم ازش استفاده کنم
> کدها رو خیلی روان و ساده و قابل فهم نوشتم حجم کمی داره و جای کار داره
> دوستانی که مایل به همکاری هستند و در این زمینه کار کردند برای توسعه زبان ایجاد شده بیام بدن تا با هم همکاری کنیم و توسعش بدیم
> زبان به صورت متن باز هست و میتونید از آدرس زیر دریافتش کنید
> 
> https://github.com/Yasser-Sajjadi/pedar


من لیست پیوندی به ذهنم رسید - اگر میتونید خب تخصیص حافظه پویا درست کنید براش- که پیوندی هم نباشه و محدودیت حافظه هم نداشته باشه - بسم الله

----------


## farhad_shiri_ex

> بله منظورم درایه بوده نوشتم ارایه- به اندازه int بهش اختصاص داده شده- قبلا هم توضیح دادم که عدد متغیر هست و ثابت نیست- خود شما هم میگید ۱۰۰ توی یک بایت جا میشه اگر بخوای عدد بیشتری مقدار دهی کنی اون خونه رو به intتبدیل میکنی اون موقع
> 1
> 2
> *(int *)data = 5000;
> 
> 
> 
> 
> 
> ...


آقا چی میگی من که سوادم به علم شما قد نمیده استاد! بله البته که عبارت lvalue در اینجا قابل تغییر هست و میتواند متغییر باشد ولی مقدار rvalues یک ثابت عددی هست منظورم این بود.
خوب حالا که چی شما به یک اشاره گر int کست کردید بعد 5000 مقداردهی کردید خوب که چی ؟؟ :تشویق: 
دوست گرامی وقتی که تحمل نقد ندارید چطور توقع دارید همکار جذب کنید؟ بهتر بود که سوالات من را به دقت مطالعه میکردید و جواب های درست و منطقی ارائه میکردید مثلا برای اثبات ادعا قسمتی از سورسها را که می فرمایید مدیریت حافظه را انجام میده را قرار میدادید نه یک مثال که کلا اشتباه هست بهتر بود خودتون یکبار کامپایل میکردید بعد تفسیر میکردید.
در ضمن من که ادعا نکردم زبان مینویسم که بخوام مدیریت حافظه را هم انجام بدم در هر حال مهم نیست دوست عزیز امیدوارم موفق باشید ویک زبان جدید خلق کنید.

----------


## yasser_sajjadi

> آقا چی میگی من که سوادم به علم شما قد نمیده استاد! بله البته که عبارت lvalue در اینجا قابل تغییر هست و میتواند متغییر باشد ولی مقدار rvalues یک ثابت عددی هست منظورم این بود.
> خوب حالا که چی شما به یک اشاره گر int کست کردید بعد 5000 مقداردهی کردید خوب که چی ؟؟
> دوست گرامی وقتی که تحمل نقد ندارید چطور توقع دارید همکار جذب کنید؟ بهتر بود که سوالات من را به دقت مطالعه میکردید و جواب های درست و منطقی ارائه میکردید مثلا برای اثبات ادعا قسمتی از سورسها را که می فرمایید مدیریت حافظه را انجام میده را قرار میدادید نه یک مثال که کلا اشتباه هست بهتر بود خودتون یکبار کامپایل میکردید بعد تفسیر میکردید.
> در ضمن من که ادعا نکردم زبان مینویسم که بخوام مدیریت حافظه را هم انجام بدم در هر حال مهم نیست دوست عزیز امیدوارم موفق باشید ویک زبان جدید خلق کنید.


تحمل نقد ندارم ! چی گفتم مگه! خب شما یه حرفی مطرح کردید جوابشو نوشتم.
جواب ها کاملا منطقی هست!!! عجیبه !!!
 lvalue که نمیشه تغییر کنه - تغییر کنه که دیگه متغیر اون متغیر نیست!
خوبه که میدونید چکار کردم. شما میگید چهار بایت برای یک عدد لازم نیست-و اون چون از نوع char هست دیگه نمیشه یه عدد بزرگتر بهش اختصاص داد. خب من اختصاص دادم ببینید که میشه.
مثال کاملا درست هست! شما اشتباه میبینید! برادر گرامی من این مفسر رو نوشتم داره کار میکنه! سرعتش خوب نیست ولی زیادم بد نیست! بعد شما ادعا میکنید متوجه نشدم چی نوشتم ؟! و حتی نمیدونم یک بایت چقدر هست چهار بایت چقدر هست ؟! اول اینکه این که نقد نیست! دوم نقدم باشه منصفانه نیست! سوم منطقی هم نیست! با این حال بازم مهم نیست. ادعای عجیبی میکنید. این یک ادعا هست. وقتی خب ادعا میکنید من هم میگم خب بیاید شما بنویسید یک بهترش رو من حرفی ندارم! اخه یک چیزی میگید تو ذهن شما درست هست ولی در عمل که فکر میکنید نمیشه انجامش داد. میگم بنویسید متوجه بشید دارم چی میگم به شما. 
باز ادعا میکنید نقدپذیر نیستم! بازم ادعای عجیبی میکنید! این یعنی نقد پذیری تا جایی میدونم. 
خب ادعا میکنید عمل کنید.
 ادرس کد رو نوشتم که وقتی در دسترس هست که دیگه کپی کردن نمیخواد!

----------

