• پایان فعالیت بخشهای انجمن: امکان ایجاد موضوع یا نوشته جدید برای عموم کاربران غیرفعال شده است

آموزش C++ سي پلاس پلاس از پايه

mohammad_110

کاربر فعال برنامه نویسی
کاربر فعال
تاریخ عضویت
22 ژانویه 2006
نوشته‌ها
60
لایک‌ها
0
در مورد malloc و calloc یک کد خیلی ساده رو فعلا از help خود TC رو نگاه کنید :
کد:
#include <stdio.h>
#include <string.h>
#include <alloc.h>
#include <process.h>

int main(void)
{
   char *str;

   /* allocate memory for string */
   if ((str = (char *) malloc(10)) == NULL)
   {
      printf("Not enough memory to allocate buffer\n");
      exit(1);  /* terminate program if out of memory */
   }

   /* copy "Hello" into string */
   strcpy(str, "Hello");

   /* display string */
   printf("String is %s\n", str);

   /* free memory */
   free(str);

   return 0;
}

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

در واقع توسط malloc حافظه ای به اندازه 10 کاراکتر از سیستم عامل درخواست می شه اگر حافظه پر باشه malloc مقدار NULL بر می گردونه و اگر سیستم عامل بتونه حافظه رو تخصیص بده malloc اشاره گری به ابتدای حافظه در خواست شده بر می گردونه .

توسط تابع free هم حافظه به سیستم عامل برگردونده می شه.

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

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

mohammad_110

کاربر فعال برنامه نویسی
کاربر فعال
تاریخ عضویت
22 ژانویه 2006
نوشته‌ها
60
لایک‌ها
0
حالا همون برنامه قبلی رو به اینصورت تغییر می دیم . این دفعه بجای اینکه برای یک آرایه کاراکتر حافظه بگیریم برای یک استراکت این کار رو انجام می دیم .
کد:
#include <stdio.h>
#include <conio.h>
#include <string.h>
#include <alloc.h>
#include <process.h>

struct test
{
 int a;
 char c;
 double f;
};

int main(void)
{
   clrscr();

   test *pt;

   /* allocate memory for string */
   if ((pt = [COLOR="Blue"](test *) [/COLOR]malloc([COLOR="Red"]sizeof(test)[/COLOR])) == NULL)
   {
      printf("Not enough memory to allocate buffer\n");
      exit(1);  /* terminate program if out of memory */
   }

   pt->a=1;
   pt->c='d';
   pt->f=3.5;

   printf("a=%d\n",pt->a);
   printf("c=%c\n",pt->c);
   printf("f=%f\n",pt->f);

   /* free memory */
   free(pt);

   getch();
   return 0;
}

به sizeof توجه کنید این یکی از کلمات کلیدی زبان C هست. این تابع مقدار حافظه ای رو که یک نوع متغییر اشغال می کنه رو بر می گردونه برای مثال می تونید این دستورات رو امتحان کنید و نتیجه اونرو ببینید .
کد:
a=sizeof(int);
b=sizeof(float);
printf("a= %d , b= %d ");
حالا اگر این تابع رو برای استراکت test که خودمون ایجاد کردیم استفاده کنیم مقدار حافظه ای رو که متغییرهای از این نوع لازم دارند رو برمیگردونه و توسط تابع malloc این حافظه از سیستم در خواست می شه .

اشاره گری که به این حافظه اشاره می کنه یک اشاره گر معمولی است و نه از نوع *test بنابراین برای اینکه این اشاره گر رو به نوع مورد نیاز تبدیل کنیم از (*test) که قبل از malloc آوردیم استفاده میشه . به اینکار casting گفته میشه . که برای تبدیل یک نوع به نوع دیگه است .

در پست قبل هم از (*char) استفاده شد. ولی از sizeof استفاده نکردیم برای اینکه میزان حافظه مورد نیاز هر char فقط یک کاراکتر هست. بنابراین برای درخواست حافظه برای 10 کاراکتر عدد 10 رو به تابع malloc دادیم . ولی ما میزان حافظه مورد نیاز malloc رو نمی دونستیم که از sizeof استفاده کردیم.

حالا اگر بخواهیم برای یک آرایه استراکت حافظه بگیریم باید مقداری که sizeof برمیگردونه رو ضرب در تعداد عناصر آرایه بکنیم .

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

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

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
محمد جان خدا خيرت بدهد. عالي بود.
در مورد آن كليدهاي كنترلي ، بله ، بايد كد دريافت شده را نگاه كنيم ، اگر صفر بود يعني كليد كنترلي است و بايد كد بعدي را دريافت كنيم.
برنامه هايي كه لطف كرديد گذاشتيد را هنوز مطالعه نكرده ام ولي من خيلي به اين موضوع علاقه مندم خواهشا باز هم ساپورت كنيد.
= == = == = == = == = == = ==
يك آموزش HTML از سايت w3schools.com تهيه كرده ام كه مصور هم هست و از پايه است .
در آدرس زير ملاحظه بفرماييد.

http://forum.persiantools.com/showthread.php?t=36468

درود.
.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
با سلام.
من يك هفته اي است كه دارم مطالبي كه تا حالا گفتيم را تمرين مي كنم. از محمد عزيز و ديگر اساتيد هم ممنونم كه تابحال ياريگر ما بودند.

اما غرض از صحبت:
از وقتي من توي كتاب sams خوندم كه نبايد متغير گلوبال داشت ، منم مي خواهم پرهيز كنم.
البته نمي دونم دليل ايشان چي بوده ولي براي تمرين مي خواهم اصلا متغير گلوبال نداشته باشم.
متغير گلوبال هم كه مي دانيد ، متغيري است كه بيرون همه توابع تعريف ميشه و در كل پروژه قابل دسترس و مقداردهي و مقدارگيري است.

حالا من يك طرحي درست كردم كه ابتكار خودمه و از جايي نخوندم. البته ممكنه جايگزين هاي بهتري داشته باشه ولي مي گم كه يك اختلاطي بكنيم.
=== من پيش خودم گفتم ، يك تابع بسازم كه درونش يكسري متغير static داشته باشه. و مي دانيد كه وقتي داخل تابعي متغير استاتيك تعريف مي كنيد ، (( هر بار كه تابع احضار ميشه ، مقدار قبلي درش محفوظ مي مونه.)) (( متغير استاتيك را يكبار مقدار مي دهيم static a1=3; ولي كنترل برنامه ، فقط بار اول كه اين كد را مي بينه ، آن را 3 مي كنه و بارهاي بعدي كارش نداره. ))
من آمدم 3 متغير استاتيك در يك تابع ساختم و تابع با 4 ورودي احضار ميشه. ورودي چهارم ،حكم راهنما داره. يعني وقتي يك باشه يعني منظور ما از احضار تابع مقدار دهي به متغير استاتيك اول است و اگر 2 باشه يعني مي خواهيم دومين استاتيك را مقدار بدهيم. و 3 هم براي استاتيك سومي.
به نوعي يك ديتابيس كوچك هم تابع دارد. ولي ،، اگر راهنما 4 باشه ، يعني مي خواهيم تابع را بكار بياندازيم و آنگاه در اين موقع است كه تابع كارش را انجام مي دهد.

منتظر نظر اساتيد هستم.
يك چيزي هم داره توي ذهنم تداعي ميشه. و اون اينه كه اين كار من چقدر شبيه يك ((كلاس)) است. البته من هيچ كلاس كار نكردم تابحال ولي از دور يه چيزايي مي دونم. مي گم انگار ((كلاس)) هم يكسري data در خودش داره و يكسري تابع.
خيلي برام جالبه كه كسي كه وارده به كلاس ، اين كار من را با كلاس مقايسه كنه و فرق هايش و شباهتهاش را بگه. شايد اين جوري من بتوانم زودتر تاپيك كلاس را راه بياندازم.

برنامه را در زير مي گذارم.

کد:
#include<iostream.h>
#include<conio.h>

[color=red]void my_function(int var1,int var2,int var3,int rahnama);[/color]

void main()
{
clrscr();int vorodi;

   cout<<"get a num for a1"<<endl;
   cin>>vorodi;
   my_function(vorodi,99,99,1);

      cout<<"get a num for a2"<<endl;
      cin>>vorodi;
      my_function(99,vorodi,99,2);

         cout<<"get a num for a3"<<endl;
         cin>>vorodi;
         my_function(99,99,vorodi,3);

 my_function(99,99,99,4); // ehzaar baraye kaare asli

   getch();
}
[color=blue]
void my_function(int var1,int var2,int var3,int rahnama)
     {
     static a1=0;   static a2=0;   static a3=0;
     
          if (rahnama==1) a1=var1; // set a1
          if (rahnama==2) a2=var2; // set a2
          if (rahnama==3) a3=var3; // set a3

if (rahnama==4) cout<<"sum="<<a1+a2+a3<<endl;

     }[/color]

البته ميشه با 5 و 6 و 7 .... گرفتن rahnama كارهاي مختلفي از تابع خواست كه روي ديتابيس كوچك خود انجام بدهد .
 

mohammad_110

کاربر فعال برنامه نویسی
کاربر فعال
تاریخ عضویت
22 ژانویه 2006
نوشته‌ها
60
لایک‌ها
0
به نقل از saalek :
اما غرض از صحبت:
از وقتي من توي كتاب sams خوندم كه نبايد متغير گلوبال داشت ، منم مي خواهم پرهيز كنم.
البته نمي دونم دليل ايشان چي بوده ولي براي تمرين مي خواهم اصلا متغير گلوبال نداشته باشم.
سلام :)
اگه برنامه کوچک باشه با متغییر Global هیچ مشکلی پیدا نمی کنید مشکل وقتی ایجاد میشه که:

برنامه ها مثلا به بالای 300 یا 500 خط می رسه :cool: . متغییر گلوبال در همه جای برنامه قابل تغییر هستش و خوب در یه همچین برنامه ای توابع زیادی وجود داره . و حتما برنامه ارور داره و اگه این ارور مربوط به متغییر گلوبال باشه از کجا میشه فهمید کجای برنامه درست عمل نمی کنه . اصلاح اینجور ارور ها وحشتناکه .
یا ممکنه که شما از توابع کتابخونه ای استفاده کنید که دارای متغییر های عمومی با نامهای مشابه با متغییر های شما باشه که ایجاد تداخل در نامگذاریها می کنه. ( برای همین هم هست که متغییر های عمومی مورد نیاز کتابخانه های استاندار یا مورد استفاده کامپایلر رو معمولا با _ یا __ و غیره شروع می کنند . برای همین بهتره اسم متغییر ها با این ها شروع نشه )
یه مشکل دیگه هم هست که مربوط به حوزه عملکرد متغییر ها هستش. شما می تونید متغییر global با اسم var1 داشته باشید . همچنین می تونید در تابعی به نام func هم متغییری باهمین اسم var1 داشته باشید . در اینصورت فکر می کنید چه مشکلی پیش بیاد:blink: (یه کم فکر کنید) !!!

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

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

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

mohammad_110

کاربر فعال برنامه نویسی
کاربر فعال
تاریخ عضویت
22 ژانویه 2006
نوشته‌ها
60
لایک‌ها
0
به نقل از saalek :
برنامه را در زير مي گذارم.
...
البته ميشه با 5 و 6 و 7 .... گرفتن rahnama كارهاي مختلفي از تابع خواست كه روي ديتابيس كوچك خود انجام بدهد .
همون برنامه رو یه خورده تغییر دادم :
کد:
#include<iostream.h>
#include<conio.h>

void my_function(int var1,int var2,int var3,int rahnama);

void main()
{
  clrscr(); 
  int vorodi;

   cout<<"get a num for a1"<<endl;
   cin>>vorodi;
   my_function(vorodi,1);

   cout<<"get a num for a2"<<endl;
   cin>>vorodi;
   my_function(vorodi,2);

   cout<<"get a num for a3"<<endl;
   cin>>vorodi;
   my_function(vorodi,3);

   my_function(99,4); // ehzaar baraye kaare asli

   getch();
}

void my_function[COLOR="Red"](int var,int rahnama)[/COLOR]{
   static a1=0 , a2=0 , a3=0;
   
   if (rahnama==1) a1=var; // set a1
   if (rahnama==2) a2=var; // set a2
   if (rahnama==3) a3=var; // set a3
   if (rahnama==4) cout<<"sum="<<a1+a2+a3<<endl;
}
 

mohammad_110

کاربر فعال برنامه نویسی
کاربر فعال
تاریخ عضویت
22 ژانویه 2006
نوشته‌ها
60
لایک‌ها
0
به نقل از saalek :
حالا من يك طرحي درست كردم كه ابتكار خودمه و از جايي نخوندم. البته ممكنه جايگزين هاي بهتري داشته باشه ولي مي گم كه يك اختلاطي بكنيم.
=== من پيش خودم گفتم ، يك تابع بسازم كه درونش يكسري متغير static داشته باشه. يك چيزي هم داره توي ذهنم تداعي ميشه. و اون اينه كه اين كار من چقدر شبيه يك ((كلاس)) است. البته من هيچ كلاس كار نكردم تابحال ولي از دور يه چيزايي مي دونم. مي گم انگار ((كلاس)) هم يكسري data در خودش داره و يكسري تابع.
منظور شما چیه ؟ یعنی می خوای به جای متغییر Global از static استفاده کنی ؟
اگه منظورت اینه که از static به عنوان حافظه پایدار استفاده کنی تا مقادیر قبلی رو نگه داره می تونه به روشهای مختلفی انجام بشه. بستگی به کاری که می خوای انجام بدی داره .
مثلا می تونی در main متغییر هایی رو تعریف کنی و این متغییر ها رو با اشاره گر به تابع ارسال کنی . یا می شه یک اشاره گر استاتیک تعریف کرد و توسط new هر قدر که لازمه حافظه گرفت ولی بهترین راه همون کلاسه .

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

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
سلام.
محمد جان واقعا عالي بود. كلي چيز ياد گرفتم. واضح هم گفتيد چون من كه خيلي مبتدي بودم همه را تقريبا فهميدم.

آن اصلاحي هم كه در برنامه من كرديد ، خيلي قشنگ بود و من بي جهت چهار ورودي ايجاد كرده بودم و با 2 ورودي هم قابل انجام بود.

من فعلا راجع به قسمتهايي كه مربوط به كلاس فرموديد ، بحث نمي كنم . اول مقدمه و معرفي كلاس را در تاپيك مربوطه اش بگيم بعد بحث كنيم.

اما اينكه چه مشكلاتي مي تواند با وجود داشتن متغير گلوبال وجود داشته ، مي تواند حادث بشه را خيلي عالي گفتيد.

اولي اينكه برنامه اي از كسي گرفته باشيم كه اسم متغير هاي آن با متغيرهاي گلوبال ما يكسان باشد.
من خودم هنوز نسبت به دانلود برنامه هاي موجود در اينترنت اقدام نكرده ام. و فعلا يا خودم تابع مي سازم و يا از توابع آماده توربو سي استفاده مي كنم . ولي بعدا بايد بروم اين نوع برنامه ها را پيدا كنم و اين مشكلي كه فرموديد پيش مياد.

دوم اينكه درون تابعي يك متغير موضعي همنام با متغير گلوبال وجود داشته باشد.

کد:
#include <iostream.h>
#include <conio.h>

int myvar;
void my_function();

void main()
{
clrscr();
cout<<" avale main                        myvar="<<myvar<<endl;
my_function();
cout<<" bade ehzare tabe=                 myvar="<<myvar<<endl;

int myvar;       myvar=3;

cout<<" bade sakhtane myvare mozeii       myvar="<<myvar<<endl;
my_function();
cout<<" bade ehzare mojadade taabe        myvar="<<myvar<<endl;

getch();
}

void my_function()
{
myvar=999;
}


258.gif


در برنامه بالا ، در تابع main ابتدا متغير گلوبال چاپ ميشده و بعد كه متغير موضعي ايجاد شده ، متغير موضعي چاپ ميشه. چون بعد احضار تابع ، 3 چاپ شده نه 999 .
.
==============================

سومين مشكلي كه فرموديد، وقتي است كه برنامه بزرگ باشه كه نمي دونيم متغير گلوبال ما را كجا تغيير داده اند.

من خودم به اين نتيجه رسيدم كه بايد برنامه طوري ساخته بشه كه هر تابع كار خاصي را انجام بدهد و هيچ تابعي در آن كار دخالت نكند. مثلا ترسيم را tarsim_function انجام بدهد و tabdil_function كارش تبديل داده ها به هم است.
بعد ((تابع تبديل)) ورودي ميدهد به (( تابع ترسيم)) .
و يك تابع هم براي ارتباط با كاربر مثلا به نام kaarbar_function .

اين 3 تابع هر كدام كار مخصوص خود را انجام مي دهد و هر كدام كار نكند ، مشكل معلومه كه مربوط به كدام است. مثلا اگر رسم صورت نگرفت مربوط به تابع ترسيم است و الي آخر.

تابع ها فقط با ورودي ها و خروجي ها به هم وصلند.
بعدا ميشه تابع هاي رابط ايجاد كرد كه بين تابع هاي ديگر قرار گيرد.
مثل كابلي كه از وسط قطع كنيم و يك واحد جديد به وسط كابل اضافه شود.
كابل همان ورودي ها و خروجي ها هستند.

چون وظيفه هر تابع مشخص است و معلوم است كه از كجا تغذيه(ورودي) مي شود و كجا را تغذيه(خروجي يا action ) مي كند، عيب يابي (error يابي) و ارتقا بسيار ساده است. ارتقا يعني افزودن يك واحد كاري(تابع جديد) به برنامه.
.
 

mohammad_110

کاربر فعال برنامه نویسی
کاربر فعال
تاریخ عضویت
22 ژانویه 2006
نوشته‌ها
60
لایک‌ها
0
به نقل از saalek :
من خودم هنوز نسبت به دانلود برنامه هاي موجود در اينترنت اقدام نكرده ام. و فعلا يا خودم تابع مي سازم و يا از توابع آماده توربو سي استفاده مي كنم . ولي بعدا بايد بروم اين نوع برنامه ها را پيدا كنم و اين مشكلي كه فرموديد پيش مياد.

سلام

منم استفاده نکردم ولی ممکنه بعدا لازم باشه از برنامه های خودتون استفاده کنید ، اینجوری احتمال تداخلش هم بیشتر میشه چون معمولا آدم به یه سری اسمها عادت داره . (البته این مشکلش با namespace حل میشه )

در مورد اون سئوال هم که برنامه قابل فهم خوبی نوشته بودید.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
من اصلا يادم نبود كه ممكنه فردا بخواهيم از برنامه نوشته شده خودمون استفاده كنيم. بله . اينجا هم مي تواند اسمها مشكل ايجاد كند. و اين كه ما عادت داريم از اسمهاي خاصي استفاده كنيم هم 10 برابر احتمال اشتباه را بيشتر مي كنه.

در مورد فرمايشات قبلي شما هم توضيحاتي دادم كه اميدوارم مفيد باشه.
و سئوالاتي در انتها كردم كه اگر كمي توضيح بدهيد ممنون ميشم.
= == = == = == = == = == = == == =
راجع به namespace گفتيد. در اين تاپيك هنوز اين مطلب گفته نشده ولي تا اونجا كه من ياد گرفتم ميشه چند تا namespace تعريف كرد و در namespace هاي متفاوت ميشه نامهاي يكسان داشت مثلا اسم myvar را در همه namespace ها داشت و با هم اشتباه نمي شوند.

چون فعلا سطح كار ما پايين است من ترجيح دادم وارد مقوله namespace نشويم ولي بعدا بايد گفته بشه چون ابزار مفيدي است.

كلا ميشه اين طور فرض كرد كه وقتي مثلا 4 تا namespace تعريف كرديم ، كامپايلر 4 فضا در نظر مي گيره و هر اسم را در فضاي مربوط به خود قرار مي دهد. البته اين را براي شرح مطلب گفتم و نمي دانم پشت پرده واقعا چه خبره.

=== = === = === === == = == == == =

منظور من از نوشتن آن برنامه كه شما اصلاح كرديد ، بله ، استفاده از متغير استاتيك به جاي گلوبال بود. بيشتر نظرم آموزش روش استفاده از متغير استاتيك بود البته.
ولي بهر حال متغير استاتيك هم ابزاري مفيد است و كاربردهاي مخصوص خود را دارد كه فعلا من نمي دانم كاربرداش چيه. يعني جايي به صورت كلاسه شده نخواندم كه كاربردهاي متغير استاتيك چيه.

اما راجع به اين كه متغير را به شكل اشاره گر بفرستيم به تابع
به نظر من اين ميشه همان متغير گلوبال .
چون باز هم چند تابع دارند يك متغير را تغيير مي دهند. زيرا مستقيما به محل نشستن متغير در حافظه دسترسي دارند.
و اين سئوال براي من پيش مياد كه اين نوع دسترسي چه فرقي داره با دسترسي به متغير گلوبال.
و تفاوتها و شباهتهايش چيست؟
براي من كه از اشاره گر هنوز مي ترسم(چون بهش مسلط نيستم) بهتر اينه كه از همون متغير گلوبال استفاده كنم. چون اگر قرار دسترسي وجود داشته باشه ، چه بهتر كه جلوي چشو تر باشه (يعني همون متغير گلوبال).

نكته جالبي گفتيد راجع به اين كه كلاس متغير را مخفي مي كنه. و من حواسم به اين خاصيت كلاس نبود. من كپسوله را به معني فشرده سازي معني مي كردم. ولي انگار بهتر اينه كه پوشش سازي معني بشه. انشا الله در تاپيك كلاس تمرين مي كنيم .

شما دو بار كلمه new را بكار برديد و خيلي مشتاقم يك بار استفاده از اين كلمه را ببينم. بعدش راحت تر مي توانم بروم دنبال يادگيري اش. احتمالا ابزار قدرتمندي هم هست.
و فكر كنم متعلق به سي ++ باشه نه سي.

يك توضيحي هم من نياز دارم و آن اينه كه آيا هر چي سي داره ، در سي++ هم قابل استفاده هست يا نه. اصلا فرق اين دو چيه؟ آيا همين كه پسوند فايل من cpp باشه ميشه سي ++ و اگر c باشه ميشه سي؟ مسلما نه. شما كه احاطه اتان از بالاتر است مي توانيد اين قضيه را كمي شرح بدهيد تا ما بفهميم كه داريم سي كار مي كنيم يا سي++.
توربو سي كه چه سي بنويسي ، چه سي++ چيزي به ما نمي گه. تنظيمات آن را هم من چيزي بلد نيستم. يه جايي در option يه تنظيمي براي c و cpp داره ولي من نمي دونم تغيير آن چه تاثيري داره.
.
 

saeedsmk

مدیر بازنشسته
تاریخ عضویت
6 سپتامبر 2003
نوشته‌ها
1,518
لایک‌ها
4
بزار با يك مثال تفاوت شون رو بگم فرض كن من x را بصورت گلوبال تعريف كردم برنامه اجرا شده و تا زماني كه به اتمام نرسه تو حافظه است و اگه توي تابع هاي مورد مصرفت متغيري با همين نام تعريف بشه ( بصورت لوكال ) ديگه مقدار متغير گلوبال رو نداره و بر اساس تابع تغيير ميكنه و بعد از خروج متغير عمومي همون مقدار رو داره كه قبل از فراخواني تابع داشته است .
اما هميشه مقداري از حافظه رو در بر گرفته . واگر تو تعريف تابع ازش استفاده بشه احتمال ايجادخطا در حالت اجرا زياد ميشه . و اگر در جايي همانطور كه دوست عزيزمون گفت اشكالي باشه به سختي ديباگ ميشه .
ولي فرض كن توي تابع رده يك چند تابع صدا زده ميشن كه بايد چندين متغيير رو تغيير بدن و در نهايت بعد از برگشت از اين توابع در تابع رده يك نتيجه درست و يا غلط برگداننده شود .( و ديگر از اين متغييرها استفاده نميشود)
( تابع اصلي رده صفر - تابع صدا زده شده از درون اين تابع رده يك - تابع صدا زده شده از درون توابع رده يك توابع رده دو و... است )
خوب براي اين كار دو راه حل موجود است
يكي استفاده از متغيير هاي عمومي
ديگري استفاده از اشاره گر ها
خوب در راه حل اول شما تعدادي متغير تعريف مكني در جايي ازش استفاده ميكن و بعد تا انتهاي برنامه توي حافظه اين متغيير ها در حافظه ميمانند ( توي برنامه هاي حجيم مثل بازي ها و يا برنامه هاي كاربردي و محاسباتي كه از اين نوع متغيير ها زياد لازم ميشه برنامه كند شده يا با كم بود حافظه مواجه ميشود)
اما در حالت دوم اين متغييرها بصورت لوكال در تابع رده يك تعريف شده و بعد از پاس شدن به توابع رده 2 يا رده 1 ديگر دوباره به تابع رده يك صدا كننده برگشت داده ميشوند و با خروج از اين تابع رده يك ، از حافظه خارج ميشوند . در نتيجه حافظه بصورت پويا و درست استفاده شده و مديريت حافظه و نحوه انتقال اطلاعات و جستجو براي حافظه خالي جهت ايجاد متغيير هاي لازم براي ديگر توابع توسط لودر يا سيستم عامل كاهش پيدا ميكند و برنامه سريع تر باحجم كمتري از حافظه اجرا ميشود .
در اين حالت برنامه سريع تر اجرا شده و احتمال كم آمدن حافظه در حالت اجرا، كاهش پيدا مينمايد.
همچنين تريسينگ و ديباگ بعدي برنامه راحت تر و سريع تر ميگردد.
در نتيجه تابع با در نظر گرفتن اين شرايط متغيير هاي لوكال مثل متغيير هاي گلوبال عمل نمي نمايند.
اما در صورتي كه متغيير بصورت لوكال رد تابع رده 0 تعريف گردد و بعد توسط اشاره گر به توابع ارسال گردد . بازهم تفاوت هاي بين اين متغيير با حالت عمومي وجود دارد.
مثلا اينكه اگه بصورت اشاره گر آنها را ارسال ننماييد. مقدار انها بعد از برگشت از توابع يا زير مجموعه ها تغيير نمي نمايد .
و يا اينكه اين متغيير ها درون تابع رده 0 معتبر هستند و درتوابع ديگر كه توسط هدر ها يا فايلهاي ديگر تعريف ميگردند ( در صورت عدم ارسال به آنها) تعريف شده نيستند.
و....:lol:
و اما در مورد اينكه پسوند معين ميكنه كه سي هست يا سي ++ اين بر اساس تعريف توي كامپايلره
من از tc++ 3.0 استفاده ميكنم توي قسمت options توي قسمت c++ options سه انتخاب است
1- c++ virtual tables كه در واقع مقدار فضاي مجازي كه شما هنگام ديباگينگ فانكشن هاي inline استفاده ميكنيد معين ميكنه
فانكشن هاي inline به توابع اي گفته ميشود كه در داخل كلاسها تعريف ميگردند
2- use c++ compiler در واقعه نحوه استفاده از كامپايلر c++ را مشخص منمايد . كه دو گزينه دارد
2-1- cpp extention only كه بر ميگرده به سئوال شما
2-2-c++ always كه انتخاب پيش فرضه و هميشه از سي ++ استفاده ميكنه
3- out-of-line inline function به شما توانايي اين را ميدهد كه بتوايند درون فانكشنهاي inline را ديباگ كرده و بريك پوينت ست كنيد كه پيش فرض ان انتخاب شده است
والا تا حالا هر چيزي كه توي c بوده رو من توي c++ استفاده كردم و مشكلي نداشتم . اما بعضي از چيز ها هست كه توي c نيست اما توي c++ موجوده .
اميدوارم كمك تون كنه
 

mostafa_gm

Registered User
تاریخ عضویت
4 آپریل 2005
نوشته‌ها
1,863
لایک‌ها
438
محل سکونت
My House
به نقل از saalek :
يك چيزي هم داره توي ذهنم تداعي ميشه. و اون اينه كه اين كار من چقدر شبيه يك ((كلاس)) است. البته من هيچ كلاس كار نكردم تابحال ولي از دور يه چيزايي مي دونم. مي گم انگار ((كلاس)) هم يكسري data در خودش داره و يكسري تابع.
خيلي برام جالبه كه كسي كه وارده به كلاس ، اين كار من را با كلاس مقايسه كنه و فرق هايش و شباهتهاش را بگه. شايد اين جوري من بتوانم زودتر تاپيك كلاس را راه بياندازم.
كلاس اصلي ترين مفهوم شي گرايي خصوصاً تو ++C يعني Encapsulation يا كپسوله كردن رو پياده سازي مي كنه.
بدون كلاس ++C هيچ فرقي با C نداره.
كلاس دقيقا يه ساختار مثل Structure هست با اين تفاوت كه متغيرها بصورت پيش فرض تو Structure، عمومي يا public هستن ولي تو Class اختصاصي يا private.
تو بحث كلاس ها يه مفهوم خيلي مهم به اسم ارث بري وجود داره كه اساس كار تمام برنامه هاي شي گرا هست.
به متغيرهاي كلاس هم شي ميگن.
نحوه دسترسي به توابع و متغير ها، سازنده ها و مخرب ها، توابع مجازي، توابع دوست و خيلي چيزاي ديگه تو كلاس ها هست كه اندازه يه كتاب ميشه!
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
با سلام.
اولا مطالب مربوط به متغير گلوبال و توابع تودرتو و تنظيمات توربو سي را خواندم ولي طول مي كشه كه بتوانم استفاده كنم.
دوما از آقا مصطفي ممنونم كه توضيح دادند راجع به كلاس.
من خواننده پستهاي شما و آقا سعيد در اين تالار و تالار وي بي هستم و دو جمله كه مي خوانم ، كلي ديدم باز ميشه و بيشتر علاقه مند مي شم. مخصوصا مطالب مربوط به كرك و ريسورس را كه امروز خواندم خيلي لذت بردم.

راجع به خودم بگم كه من به جز كتاب آموزش سي جناب جعفرنژاد هيچ كتابي ندارم. و تقريبا هيچ پستي را از اين كتاب نزده ام چون اكثرا اين كتاب را دارند و نيازي به نقل قول نيست.
و ثانيا اين كتابي كه من دارم سي است نه سي+ .
من تمامي مطالب را از سايتهاي خارجي و ebook هاي انگليسي نقل مي كنم و چون زبانم زياد خوب نيست ، وقتي به مفاهيم مي رسم دچار مشكل مي شم. الان هم يكي دو پست از كتاب sams آماده كرده ام ولي وقتي به مفاهيم سازنده و مخرب ها رسيدم ، باز به علت ضعف زبان انگليسي دچار مشكل شدم. به همين خاطر است كه حتي چند جمله از شما و ديگر دوستان برايم كلي ارزش داره و باعث ميشه كلي در كتاب جلو برم.
مي دانم كه مطالب اين تاپيك براي افرادي در سطح شما قابل توجه نيست ولي يك كم شارژ از سوي دوستان ، كلي كمك است . مخصوصا وقتي مفاهيم مطرح است.

راجع به كلاس ، همان طور كه شما فرموديد ، بله بسيار گسترده است . من تابحال يك كلاس هم در برنامه هايم نساخته ام ولي با مطالعه گذري كتابها مي دانم كه گستردگي بحث وراثت و ديگر مباحث چقدر است. شايد از خود مباحث سي هم شي گرايي بيشتر مطلب دارد.
و مي دانم كه تمامي مباحث در طول اين تاپيك ناقص گفته شده و هر فصل نياز به دهها پست دارد ولي هدف من يك مرور سريع است و باقي كار و تكميل بر عهده خواننده است. همچنين شامل طبقه بندي مطالب كه من فعلا قادر به اين كار نيستم . چون احاطه به موضوعات هنوز ندارم.
ولي در كل همين كه مباحث توسط اساتيد مورد بحث قرار بگيرد ، باعث باز شدن راه براي مطالعه بعدي است. خيلي ها كتاب دارند ولي چون با مباحث احساس غربت مي كنند ، رغبتي براي مطالعه ندارند. و اين بحث ها كمك به درك است براي حركتي با علاقه.

بهر شكل تجربه خوبي بود و هم من كلي چيز ياد گرفتم و هم افتخار آشنايي با شما را داشتم.
و در خود احساس تعهد مي كنم كه تا حد توانم ادامه دهم. و اين تلاش اولا براي گفتن مطالب گفته نشده است و ثانيا تعميق و مهارت يافتن در مباحث گفته شده.
من يك تاپيك وي بي هم دارم . البته در سطح مبتدي. كه 204 پست خورده و در چند روز اخير حداقل 4 نفر با پيام خصوصي يا پست خواسته اند ادامه دهم. ولي چون اينجا قرار بر ادامه تا آخر است ، قبول نكردم.
با وجود تمامي نواقص تاپيك ، من ادامه مي دهم و رفع نواقص را به عهده خواننده مي گذارم ولي هر وقت توانستم تاپيكهايي بر اساس فصول ايجاد مي كنم . ولي فعلا همه مباحث را به جز گرافيك در اين تاپيك ادامه مي دهم . و كلاس را هم همين جا پست مي زنم. و كمك دوستان حتما باز كننده راه است.
.
 

mohammad_110

کاربر فعال برنامه نویسی
کاربر فعال
تاریخ عضویت
22 ژانویه 2006
نوشته‌ها
60
لایک‌ها
0
یه مورد هم اینکه متغییرهای گلوبال توسط همه برنامه قابل تغییره و لی متغییری که به تابع ارسال میشه فقط در همون توابع قابل تغییره.
و در ضمن اینطوری حداقل ردیابی متغییر راحتتره چون معلومه که به کدوم توابع و کجای برنامه ارسال شده .

راجع به C و ++C هم که برای هر نرم افزاری که بخوان ورژن جدیدی ارائه کنند تا اونجایی که ممکنه سعی می کنند که سازگاری با ورژن قبلی رو حفظ کنند تا اولا برنامه ها و کارهای خودشون رو با ورژن جدید بتونن انجام بدند دوما که مشتریای قدیمی رو از دست ندن . در مورد C هم اینکار خیلی خوب انجام شده بجز مواردی خیلی جزئی که نمی دونم چیه C با ++C سازگاره.

تازه در ++C امکاناتی وجود داره که می تونه برنامه های زبانهای دیگه رو هم (مثل Basic ) کامپایل کنه ، می تونی فصل مفسرهای کتاب جعفر نژاد رو بخونی .
همین کتاب جعفر نژاد اشاره گر ها و توابع رو خوب گفته که مقدمات کار هستند . رفتن به سراغ کلاسها بدون دونستن خوب اشارگرها و توابع به مشکل برمی خوره.

در مورد توابع inline و new و namespace بهتره در بحث کلاسها باشه . ولی تا اونجایی که من می دونم توابع معمولی هم می تونند inline باشند
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
با سلام.
بله . متغير موضعي فقط در آن تابع ايجاد ميشه و تغيير مي كند ولي متغير گلوبال هر جاي پروژه مي تواند تغيير كند.
پس با نگاه به كدهاي يك تابع ، سريع ميشه فهميد كه متغير موضعي اون چه تغييراتي مي كند.
من خودم عادت به نوشتن برنامه هاي بزرگ دارم و از ابتداي اين تاپيك دارم يك بازي مي نويسم. و هر تابعي كه مي بينم به اين فكر مي كنم كه براي كجاي بازي من مفيده. و راستش الان بازي من آنقدر حجمش بزرگ شده كه به كلاس نياز داره چون خيلي بدون كلاس پيچيده شده و از عهده مديريتش به سختي برميام.
بازي simcity هم هست كه الان هم به خوبي كار مي كنه. و تاپيك گرافيك را براي همين زودتر از همه تاپيكهاي ديگر باز كردم.

به اين خاطر گفتم دارم بازي مي نويسم كه بگم كه در اين برنامه بزرگ من ، من هيچ مشكلي با متغيرهاي موضعي ندارم. چون همان طور كه گفتيد فقط در تابع خود تغيير مي كنه. ولي همين ديشب من يك متغير گلوبال بازي را تغيير دادم كه ديگه نفهميدم چي شد. همه چي به كل فلج شد و نتوانستم بفهمم اين تغيير متغير گلوبال ، چه طوري همه چيز را به هم ريخته . و كلا ديگه از تغيير آن متغير صرف نظر كردم و پروژه خود را متوقف كردم تا با كلاس از اول بنويسم.

به جز يك مورد از هيچ اشاره گري در بازي خود استفاده نكرده ام.
راجع به فهم دقيق اشاره گر و تابع هم حق با شماست ولي همان طور كه قبلا هم ما عقب گرد كرده ايم ، باز هم عقب گرد مي كنيم و باز به اشاره گر و انواع فراخواني تابع(باي رفرنس و ..) خواهيم پرداخت. فقط هم همين ها كم نيست . خيلي مباحث مهم حتي اسمي برده نشده. مثل پشته و صف . خود درايت به حافظه. ما هنوز نمي دانيم برنامه امان كجاي ram مي نشيند و قطعه داده و كد و غيره را نگفته ايم. مدلهاي برنامه small و large و ... را نگفته ايم.
به جز مثال شما ، تابحال حافظه درخواست نكرده ايم و حافظه آزاد نكرده ايم.
من همان طور كه مي دانيد اولين زباني كه كار كرده ام اسمبلي است و سي را بخاطر نزديكي به اسمبلي انتخاب كرده ام ولي اصلا در اين تاپيك به جنبه هاي اسمبلي سي پرداخته نشده. مثل درايت بيتي بر حافظه و دستكاري بيتها و كلا هر چيزي مربوط به اسمبلي در سي.
== == == == == == == == == === ==
راجع به پشتياني سي++ از سي هم ، اميدواري خوبي شما و ديگر اساتيد داديد و خيالم راحت شد.
= == == == == == == == == == == ==
قسمت مفسرهاي كتاب جعفرنژاد را من دهها بار خوانده ام. چون من كد نويسي را قبل اسمبلي با بيسيك قديمي ياد گرفته ام. حتي نه qbasic بلكه زبانهاي ابتدايي تر از آن.
= == = == = == = == = == = == = ==
راجع به مباحثي كه گفتيد بعد كلاس بحث بشه ، چشم ، من با وجودي كه برام كلاس الان غوله ولي شروعش مي كنم و كمك دوستان هم حلال موانع راه است.
= == = == = = == = == =
در مورد اون برنامه هم كه من نوشتم،
كه يك تابع بود كه 3 متغير استاتيك درش داشت.... مي خواهم يك چيزي بگم.

کد:
void my_function(int var,int rahnama){
   static a1=0 , a2=0 , a3=0 [color=red]a4=0[/color];
   
   if (rahnama==1) a1=var; // set a1
   if (rahnama==2) a2=var; // set a2
   if (rahnama==3) a3=var; // set a3
   if (rahnama==4) cout<<"sum="<<a1+a2+a3<<endl;
}

در برنامه بالا من يك a4 هم اضافه كردم كه ديگه rahnama هر چه تغيير كند نمي تواند آن را تغيير دهد . به نوعي ميشه a4 را يك متغير private اين تابع دانست.
هدفم اصرار بر خوبي برنامه خودم نيست ، مي خواهم بحث public و private قبل گفتن كلاس حل بشه.
همان طور كه استاد گرامي گفتند ، در struct هر چند تا متغير كه تعريف كنيم مسلمه كه مي توانيم تغيير بدهيم آن را . فقط كافيه اسمش را بگيم و مقدار جديد بدهيم. ولي در كلاس اگر هيچ اثري از كلمات public و private نباشه ، به طور ديفالت(پايه) همگي private هستند . يعني نميشه تغييرشون داد. البته اگر يك كلمه

کد:
public:

قبل همه متغيرها و توابع بگذاريد ، همه عمومي ميشوند و ميشه مثل struct . البته استراكت تابع نداره.
در برنامه ساده اي كه من نوشتم ، ميشه چند تابع ديگه اضافه كرد . مثلا براي تفاضل و حاصل ضرب . اينها توابع ميشوند و a1 تا a4 هم مي شوند متغيرها.

ديگه دست از سر اين برنامه خود برمي دارم و باقي مطالب را با تعريف كلاس مي گم.
فقط اين برنامه را ساختم تا بگم كه كلاس چيزي جز چند متغير و تابع كه كنار هم جمع شده اند نيست. (البته اساتيد ممكنه اعتراض كنند به اين حرف من ولي فعلا بگذاريد همه چيز را ساده ببينيم و راحت فرض كنيم ، بعدا علمي تر كلاس را تعريف مي كنيم.)

تعريف كلاس:

کد:
class Cat
{
int Age;
int Weight;
Meow();
};

در كد بالا يك كلاس ايجاد شده .
دو متغير دارد و يك تابع. كه بايستي حتما تابع اش هم تعريف شود.
تعريف تابع هم دقيقا مثل تعريف ديگر توابع است . فقط با علاماتي بايد فهمانده شود كه تابع تعريف شده مال اين كلاس است كه علامت :): ) را بكار مي برند.
يعني اول اسم كلاس ، بعد اين علامت و بعد اسم تابع .

مي توانيم با قرار دادن كلمه public قبل همه متغيرها و توابع ، همه را عمومي و قابل دسترس كنيم . شبيه struct .

در پست بعد اول يك كد كلاس را مي نويسم
بعد تابع هاي آن را تعريف مي كنيم .
بعد آبجكت مي سازيم.

با تعريف كلاس و تعريف تابع هايش چيزي هنوز بوجود نمي آيد . ولي از لحاظ زحمت كدنويسي كار تمام شده.

ما با تعريف كلاس يك type ايجاد كرده ايم . مثل int و char و long .
و بعدش مي توانيم از type خود استفاده كنيم.
مثلا اگر بخواهيم دو cat به نامهاي loosi و nazii خلق كنيم مي نويسيم.

کد:
cat loosi
cat nazi

حالا اگر تابع متغيرهايش عمومي بود مي توانستيم ((سن)) و ((وزن)) اين دو گربه را تعيين كنيم و يا تابع ((ميو)) را احضار كنيم. كه در كتاب sams اين تابع فقط مي نويسه ميو. با cout .

پس در پست بعدي اول كلاس را تعريف مي كنيم كه همونه كه بالا گفته شده . البته فعلا public مي كنيم تا بتوانيم حسابي همه را تغيير دهيم . و تابع ميو هم بايد بنويسه ميو و بعد
با همين دو خط كد ، دو گربه تعريف مي كنيم و بعد ((وزن لوسي)) را تغيير مي دهيم.
.
کد:
loosi.Weight =50;

ديگه همشو گفتم كه!
ديگه خودتان هم مي توانيد سوار كنيد. تعريف كلاس و تابع ها بيرون
main
و ايجاد لوسي و نازي و تغيير مشخصات آنها داخل
main
.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
کد:
#include <iostream.h>
#include <conio.h>

[color=red][size=4]class Cat 
{
public:
int Age;
int Weight;
void Meow();
};[/size]
[size=2]
void Cat::Meow()
{
cout <<"Meow"<<endl;
}[/color]
[/size]
void[size=5] main()[/size]
{
[color=blue][size=4]Cat loosi;
Cat nazi;[/size][/color]
[color=green][size=2]loosi.Weight =50;[/size][/color]
cout<<[color=green][size=2]loosi.Weight[/size][/color]<<endl;

[color=green][size=2]nazi.Meow();[/size][/color]


getch();
}


266.gif

.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
يك كم راجع به پشته بگيم. بعدا مشروح تر بحث ميشه.(وقتي كه خواستيم برويم ساختار حافظه را بررسي كنيم.)

کد:
When you begin your program the compiler creates a stack.

وقتي برنامه شروع مي شود يك پشته ساخته مي شود.
پشته آدرس دارد و انتهاي پشته هم آدرس دارد. كه همه جايي در Ram است. ما تابحال كاري با پشته نداشتيم چون اتوماتيك ساخته ميشه. و چون دستي چيزي به پشته نفرستاديم ، لازم نبود بلد باشيم كه پشته چطور پر و خالي مي شود.
اول بگم چرا ميگن پشته. البته stack اسم انگليسي اش است. چون كه وقتي واحدها را روي هم مي ريزي ، جديد تر ها ، بالاتر قرار مي گيرند و قديمي ها مي روند زير. مثل كاميوني كه ماسه خالي مي كند. اولين ماسه اي كه خالي مي شود ، كارگرها وقتي همه ماسه ها تمام شد مي توانند به آن دسترسي پيدا كنند. كه لفظ پشته مصداق داره. چرا حالا پشته اين جوري ساخته شده؟ به نظر من به اين علته كه براي كنترل آن فقط 2 آدرس لازمه . اولش و آدرس تا جايي كه پر شده. البته ((صف)) برعكس است يعني اولي ، اول خارج ميشه و آخري ، آخر. مثل صف نانوايي كه هر كس زودتر آمده ، نان اش را زودتر ميگيره. حالا من نمي دانم كه صفي هم به محض شروع برنامه ساخته ميشه ، يا اينكه نه، فقط صف با ساختن دستي درست ميشه.
اما راجع به پشته ، چيزي كه براي من جالب بود ، اول اين كه به محض شروع برنامه پشته ايجاد ميشه و دوم اينكه هر تابعي كه احضار بشه ، كلي خرت و پرت به پشته منتقل ميشه. كه يكي از آنها كه به بحث ما مي خوره ، متغير هاي موضعي آن تابع است. و چون ما اكثرا متغير موضعي مي سازيم ، انگار بايد در پشته دنبالش بگرديم.
البته زياد لزومي ندارد كه بدانيم متغير ما كجا ميره مي شينه ولي شايد كمي كه به سمت حرفه اي تر شدن برويم لازم باشه. اي كاش قطعه داده و قطعه هاي ديگر را گفته بوديم كه الان مي گفتيم كه پشته در كدام قطعه است.قطعه پشته آيا داريم يا نه. هنوز مطالعه درستي ندارم. فكر كنم در مدلهاي مختلف حافظه ، مثل tiny و small و large و huge اين قطعه ها فرق مي كنند . يعني در مدلهاي كوچكتر دو قطعه ، مثلا قطعه داده و پشته يكي بشوند.
بعدا روي اينها فوكوس مي كنيم . فعلا چيزايي كه راجع به انواع قطعه ها گفتم نشنيده بگيريد . شايد اصلا اين قطعه ها را نداشته باشيم . اگر من مقاله خوبي پيدا كردم در اين مورد مي زنم . اگر دوستان نظر دادند اين ها را اديت مي كنم.
فعلا داشتيم پشته را مي گفتيم. يك عكس كتاب sams براي تشبيه پشته زده كه براي قشنگ شدن تاپيك مي زنم اينجا. به نظر من كه همان تپه با مسما تر بود.


267a1.gif


267a2.gif


در مورد توابع اولين چيزي كه به پشته موقع احضار توابع فرستاده ميشه ، آدرس برگشت تابع است.

کد:
1. The return address of the function is put on the stack. When your function returns,
it will resume executing at this address.
چون فعلا بقيه چيزا برايم اهميتي ندارد ، بي ترجمه مي زنم اينجا .
چون در سطح كار پايين ما اين اطلاعات فعلا ضرورتي ندارد و بعدا انشاالله بحث كامل تر مي كنيم.

کد:
2. Room is made on the stack for the return type you’ve declared.
3. All the arguments to the function are placed on the stack.
4. The program branches to your function.
5. Local variables are pushed onto the stack as they are defined.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
فرهنگ اصطلاحات كلاس:


A class is a collection of variables—
often of different types—combined with a set of related functions.

كلاس: كلاس مجموعه اي از متغيرهاست كه معمولا از انواع مختلف هستند كه با توابع مربوطه تركيب مي شود.


Encapsulation is bundling together all the information, capabilities, and respon-sibilities
of an entity into a single object.

كپسوله كردن: يعني اينكه مجموعه اي از اطلاعات ، قابليتهاي عمل كردن و پاسخ دادن را در يك آبجكت جمع كنيم.
برداشت من: منظور توابعي است كه كارهاي مختلف مي كنند و متغيرهايي كه براي انجام اين كارها لازمه.
در ادامه توضيح داده كه اين جمع كردن به برنامه نويس اين قدرت و راحتي را مي دهد كه هر چيزي در جاي مناسبي قرار بگيره و ارجاع به آنها راحت بشه و copy و دستكاري ديتاها هم راحت بشه.


Clients of your class are other classes or functions that make use of your class.
Encapsulation allows the clients of your class to use it without knowing or caring
about how it works.

كلاينت هاي كلاس شما ، كلاسها و توابعي هستند كه كلاس شما را مورد استفاده قرار مي دهند. كلاينتها لازم نيست بدانند كه ((كلاس چطور كار مي كند ، بلكه فقط لازمه بدانند كه چه كاري را انجام مي دهد.))
مثال خوبي كه زده شده در اين كتاب اينه كه شما وقتي مي خواهيد اتومبيلي را برانيد ، لازم نيست بدانيد كه اجزاي موتور چطور كار مي كند ، بلكه فقط رانندگي بايد بلد باشيد. يعني درون كلاس چي داريم مهم نيست ، مهم اينه كه بدانيم كلاس چه دستاويزهايي به ما مي دهد. مثلا كلاژ و ترمز . كه ميشه يكسري تابع . در ادامه يك نوع از توابع كلاس كه كار دسترسي به متغيرها را انجام مي دهند را تعريف كرده.


Member variables, also known as data members, are the variables in your class.
Member variables are part of your class, NEW TERM

اصطلاح member variable يا data member ، همان متغيرهاي كلاس شما هستند كه قسمتي از كلاس را تشكيل مي دهند.


The functions in the class typically manipulate the member variables. They are
referred to as member functions or methods of the class.

توابع كلاس ، معمولا متغيرهاي كلاس را دستكاري مي كنند(تغيير مي دهند) .
به آنها ، member function يا متدهاي كلاس(methods ) مي گويند.

جمع بندي من: پس دو چيز داريم . متغيرهاي عضو كلاس و تابعهاي عضو كلاس . كه به تابع ها متد هم مي گويند. در وي بي و دلفي هم هر ابزار روي جعبه ابزار يكسري پراپرتي داره و يكسري method . ميشه آن ابزارها را كلاسهاي تعريف شده توسط طراح كامپايلر دانست . و چقدر هم راحت است كار كردن با آن ابزارها. و لذت استفاده از كلاس ها آنجا آشكار ميشه. در ويژوال سي هم اساسش بر كلاسهاي آماده است. مثل كلاس cPen و غيره. من هدفم از اينكه زود آمدم سراغ كلاس يك علتش اينه كه مي خواهم بزودي ويژوال سي را هم به موازات اين تاپيك شروع كنم. البته اولش فقط آشنايي با محيط برنامه را ميگيم تا اين آموزش سي++ به جاي مناسبي برسه. مباحثي را هم كه جا مي اندازم يك دليلش اينه كه مي گم شايد در ويژوال سي به كار نياد يا اگر لازم بود بعدا به سراغش بريم.
.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها
توجه داشته باشيد كه با تعريف كلاس هيچ حافظه اي اختصاص نمي يابد چون چيزي خلق نشده.
كلاس را مثل نقشه ساختمان در نظر بگيريد كه مهدس از روي آن ساختمان را مي سازد. در نقشه يك ساختمان كسي نمي تونه سكونت كند. بلكه از روي نقشه بايد آبجكت ساخته بشه. و هر تعداد آبجكت ميشه از روي نقشه(كلاس) ساخت. با كلاس cat ميشه بي نهايت گربه خلق كرد.

===========================
در نامگذاري متغيرهاي كلاس بعضي برنامه نوس ها كلمات itsAge و itsWeight را بكار مي برند. اين جوري معلوم ميشه كه كدام متغيرها از اعضاي كلاس هستند و كدام ها نيستند. يعني آنهايي كه its دارند از اعضاي كلاس هستند.

در نام گذاري اسم خود كلاس ، بعضي حرف اول را به نشانه اينكه اسم كلاس است بزرگ مي نويسند و بعضي كل كلمه را بزرگ مي نويسند. من خودم از اسمي كه تمام حروفش بزرگ باشه مي ترسم چون كنستانتهاي header را كه خيلي زياد است را ديده ام كه همه با حرف بزرگ است و ممكنه با آنها اشتباه بشه. البته اين حرفم مستند نيست و يك ترس بيهوده شايد باشه. ولي من وقتي از اسمهاي رايج انگليسي مثل start استفاده كردم در 5 مورد خطا دريافت كردم و از آن به بعد از اسمهاي فينگليش استفاده مي كنم. البته mystart استفاده مي كنم و اشكالي پيش نمي آيد. ولي بايد در اين مورد با تجربه ها نظر بدهند و محمد عزيز در چند پست قبل به يك نكته در اين مورد اشاره كرد.
با آندرلاين هم اگر در وسط كلمه باشه ، فكر نكنم مشكلي پيش بياد.

در اين كتاب تاكيد كرده كه شما بايد از يك استيل ثابت استفاده كنيد. مثلا هميشه با آندرلاين يا حرف اول بزرگ يا تمام حروف بزرگ. و استيل نامگذاري را مرتب عوض نكنيد. البته در يك برنامه منظوره نه هميشه.
 

saalek

مدیر بازنشسته
تاریخ عضویت
24 می 2005
نوشته‌ها
654
لایک‌ها
53
محل سکونت
در پاي كوهپايه ها

These accessor methods are the member functions
that other parts of your program call to get and set your private member variables.

وقتي يك متغير كلاس private باشه ميشه توابعي در كلاس ايجاد كرد كه با استفاده از آن توابع ، آن متغير را خواند يا تغيير داد. به اين توابع accessor مي گويند. Access هم كه به معني دسترسي است ، معادلش را بسازيد. دسترسان خوبه؟! فكر نكنم. همان accessor بهتره بگيم.

فوائدش را هم گفته كه اين جوري راه ذخيره از راه استفاده جدا ميشه. و اين خيلي خوبه.چون مي توانيد راه تغذيه متغير را تغيير بدهيد بدون اينكه نياز باشه راه استفاده (use) را دوباره نويسي كنيد.
 
بالا