ISOCPP مسئول تدوین استاندارد های C++


C++ زبان بزرگ و مهمی در دنیای کامپیوتر است. همه ما این را می دانیم و به آن معترف هستیم و می دانیم بدون آن شاید دنیای کامپیوتر به شکل امروزی نبود. اکثر قریب به اتفاق زبان های برنامه نویسی جدید از C و C++ تاثیر گرفته اند و دنیای کامپیوتر بر این دو زبان بنا شده است. پس همینگونه که واضح است یکپارچه سازی و ارتقای C++ امری بسیار مهم و بزرگ است، چون هنوز هم بسیاری از شرکت ها به این زبان وابسته اند و روی آن سرمایه گذاری می کنند. امروزه زبان C++ تحت تسلط هیچ شرکتی نیست و استاندارد سازی آن توسط ISO صورت می گیرد. ISOCPP موسسه ای نا سودبر است که جهت تدوین استاندارد های این زبان و ارتقای آن تشکیل شده است و در راس افراد حاضر در آن، خالق این زبان، آقای بیارنه استراستروپ قرار دارد. تا قبل از سال 2011 آخرین استاندارد کلی C++ در سال 1998 به تصویب رسید و از آن موقع به بعد استاندارد دیگری برای این زبان تدوین نگردید، تا در سال 2011 که استاندارد کلی دیگری برای C++ به تصویب رسید و آن را به نام C++11 می شناسیم. به همت ISOCPP دو استاندارد جدید این زبان برای سال 2014 و 2017 برنامه زیری شده اند، که از این دو، استاندارد 2017 ، استاندارد کلی بعدی برای C++ خواهد بود.



از دیگر اهدف ISOCPP ، شفاف سازی و امکان مشارکت علاقه مندان در پروسه تدوین استاندارد است. در سایت ISOCPP.org میتوانید به اطلاعات بسیاری در مورد C++ استاندارد دسترسی داشته باشید شامل آموزش ها، اخبار، ویدئو ها و لینک های مرتبط می شود. بد نیست این را هم بدانید که این بنیان توسط شرکت های بزرگی همچون ماکروسافت، گوگل، اینتل و ... حمایت مالی می شود ولی این شرکت ها حق رای در استاندارد سازی ندارند و صرفا از این بنیان حمایت می کنند، چون منافعشان به زبان C++ وابسته و مرتبط است.  

Delegate چیست ؟ (C++)  


در زبان برنامه نویسی سی پلاس پلاس، Event یک عضو از کلاس است که به یک شی اجازه اطلاع رسانی هنگام رخ دادن اتفاق خاص را می دهد، و علمیات اطلاع رسانی یا سیگنالینگ شامل یک Delegate (نماینده) می شود که امکان عکس العمل به Event را فراهم می آورد. برای مثال یک کلیک موس یک event به حساب می آید و شیئی که از این event سرچشمه می گیرد می تواند با فراخوانی یک یا چند تابع، رخ دادن این event را اطلاع رسانی کند؛ یک delegate میتواند ابزار دسترسی به توابعی که مسئول این event هستند را ارائه کند. 
ایده delegate بسیار ساده است - یک شی که یک یا چند اشاره گر به تابعی که دارای یک لیست پارامتر و نوع خروجی است، را در بر می گیرد. این تابع که delegate به آن اشاره می کند، Event را مدیریت می کند. پس delegate در C++/CLI تقریبا عملکرد مشابهی نسبت به "اشاره گر به تابع" در C++ استاندراد دارد.

تعریف delegate :

تعریف delegate ، مشابه تعریف تابع است که در ابتدای آن از کلمه delegate استفاده شده باشد. اما در اصل دو چیز در آن تعریف می شود: نام نوع ارجاع برای شی delegate و لیست پارامتر ها و نوع خروجی تابعی که می تواند همراه با delegate به کار رود. نوع ارجاع یک delegate ، کلاس System::Delegate را به عنوان کلاس پایه در اختیار دارد، پس همیشه از این کلاس مشتق خواهد شد. در زیر نمونه ای از تعریف delegate آمده است.

public delegate void HANDLER(int value);

این خط یک HANDLER از نوع ارجاع delegate تعریف می کند که نوعش از System::Delegate مشتق شده است و یک شی از آن می تواند حاوی اشاره گری به یک یا چند تابع با یک پارامتر ورودی int و نوع خروجی void (بدون نوع خروجی) داشته باشد. تابعی که delegate به آن اشاره می کند میتواند Static یا Instance باشد.

ایجاد delegate :

حالا که delegate را تعریف کردیم میتوانیم اشیاء delegate از این نوع ایجاد کنیم. ما میتوانیم دو تابع سازنده داشته باشیم که اولی، یک و دیگری، دو پارامتر را می پذیرد. پارامتری که برای سازنده delegate با یک پارامتر استفاده می شود باید یک تابع static عضو کلاس یا یک تابع عمومی باشد. تابعی که به عنوان پارامتر تعریف می کنید باید دارای پارامتر ها و نوع خروجی یکسان با انواع تعریف شده در delegate باشد. برای مثال کلاس زیر را در نظر بگیرید.


class HandlerClass
{public:
static void Sample(int num)
{
  Console::WriteLine(L"Function called with value {0}", num);
}

};

تابع Sample از کلاس بالا را به عنوان تابع مدیریت کننده ی Event به کار می بریم. این تابع دارای یک پارامتر ار نوع int و نوع خروجی void است درست مانند آنچه در delegate تعریف کرده ایم. البته نیازی نیست این تابع در کلاس باشد و هر تابعی متواند این مسئولیت را قبول کند. در زیر از این تابع برای ایجاد delegate استفاده می کنیم.


HANDLER^ handler = gcnew HANDLER (HandlerClass::Sample);


شی handler ، آدرس تابع استاتیک Sample در کلاس HandlerClass را در بردارد. اگر شما delegate را فراخوانی کنید، این تابع را فراخوانی کرده اید. این فراخوانی را می توان به صورت زیر انجام داد.


handler - > Invoke("parameter");

یا به صورت  :

handler ("parameter");

این دستور باعث فراخوانی توابعی می شود که در لیست فراخوانی delegate قرار دارند که در این مثال تنها تابع Sample می باشد. پس خروجی به صورت زیر خواهد بود. (فرض کنید مقدار 100 را به عنوان پارامتر به delegate ارسال کرده ایم)


(عبارت زیر در خروجی چاپ می شود)
Function called with value 100

در پست های بعدی به سراغ ادامه ی بحث delegate در C++ می رویم.
   style=

تغییر حالت Sata از IDE به AHCI پس از نصب ویندوز

 
اگر می خواهید مد پورت Sata مادربورد را از حالت IDE به حالت AHCI تغییر دهید، خوب است بدانید که نیازی نیست دوباره ویندوز کامپیوتر را نصب کنید! خیلی راحت با تنظیماتی ساده در رجیستری ویندوز (که احتمالا به صورت پیشفرض نیز صورت دلخواه ما قرار داده شده است) می توانید حالت پورت ساتا را در تنظیمات بایوس کامپیوتر خود تغییر دهید. برای این کار وارد رجیستری ویندوز شوید و کلید زیر را پیدا کنید. 
(برای وارد شدن به رجیستری ویندوز کلمه regedit را در قسمت Run ویندوز تایپ کنید و Ok را کلیک کنید)


HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\msahci

یا در ویندوز 8 :

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\storahci

پس از اینکه کلید بالا را پیدا کردید کافی است مقدار (ارزش) گزینه ی Start را برابر 0 قرار دهید. برای اینکار بر روی گزینه Start کلیک راست کرده و گزینه ی Modify را انتخاب کنید. سپس در قسمت Value data مقدار 0 را وارد کنید. (همانطور که گفته شد به احتمال زیاد این مقدار، به صورت پیشفرض نیز برابر 0 خواهد بود). کار ما در بخش رجیستری ویندوز تمام است حالا می توانید در قسمت BIOS حالت AHCI را برای پورت ساتا انتخاب کنید. (توجه داشته باشید، شاید ممکن باشد پس از این کار، هارد دیسک یا SSD خود را به عنوان اولین وسیله بوت کامپیوتر انتخاب کنید تا همه چیز به درستی کار کند).

برنامه ماتریس همسازه (C#)


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


private float[,] Kehad (float[,] matrix, int ROW, int COL)
{
int Size = (int) Math.Sqrt(matrix.Length);
float[,] result = new float[Size - 1, Size - 1];
int x = -1, y = 0;
for (int i = 0; i < Size; i++)
{
   if (i == ROW)
   continue;
   x++;
   y = 0;
   for (int j = 0; j < Size; j++)
    {
         if (j == COL)
           continue;

        result[x, y++] = matrix[i, j];
    }
}
return result;
}

نوع خروجی تابع بالا یک ماتریس (آرایه) از نوع float است و ROW و COL سطر و ستونی هستند که قرار است از ماتریس حذف شوند. این تابع تنها ماتریس داده شده را در ماتریس خروجی کپی می کند؛ ولی هنگامی که به سطر و ستون مشخص شده برسد آن سطر یا ستون را نادیده می گیرد. این کار با دستور continue انجام می شود.
فرمول محاسبه هسازه ماتریس به صورت زیر است :


A i, j = (-1) ᴵ + ᴶ x | M i ,j |

پیاده سازی این فرمول در زبان سی شارپ می تواند به صورت زیر باشد :



private float[,] Hamsaze (float[,] matrix)
{
int Size = (int)Math.Sqrt(matrix.Length);
float[,] result = new float[Size, Size];
for (int i = 0; i < Size; i++)
{
   for (int j = 0; j < Size; j++)
   {
     result[i, j] = (float) Math.Pow(-1, (i+1 + j+1)) * Determinant(Kehad(matrix, i, j));
   }
}
return result;
}

خروجی تابع بالا نیز یک ماتریس از نوع float است و ورودی آن، ماتریس اصلی است. در تابع بالا برای تک تک درایه های ماتریس اصلی همسازه محاسبه می شود و تابع Determinant دتر مینان ماتریس (های) ارسال شده را محاسبه می کند که قبلا در موردش توضیح داده بودیم. برای آزمایش می توانید از برنامه زیر استفاده کنید، البته برای اجرای آن نیاز به فریمورک .Net نسخه 4.5 دارید.




با "کلاس درس" آشنا شوید...

"کلاس درس" (kelasedars.org) سایتی دوست داشتنی و مفید است که توسط چند دبیر، مدیریت می شود و در آن می توانید به ویدئوهای آمورشی مطالب درسی (بیشتر دوره ی دبیرستان) دسترسی داشته باشید که به گفته ی سایت به بیش از 350 عدد می رسد و در حال افزایش است. پس دست در دست هم دهیم به مهر میهن خویش را کنیم آباد...

« مدرسه ای برای همه
آرمان «کلاس درس» که شریک آموزشی «آکادمی خان» در زبان فارسی است، فراهم کردن آموزش رایگان و باکیفیت تمامی یافته‌های علم برای همه‌ی فارسی‌زبانان است. ما قصد داریم به وسیله ویدیوهای کوتاه‌مدت آموزش در بالاترین سطح ممکن را برای همه و به طور یکسان فراهم کنیم. »

پدر زبان سی شارپ، Anders Hejlsberg

Anders Hejlsberg یک برنامه نویس و مهندس نرم افزار برجسته دانمارکی است که در طراحی و توسعه چند زبان برنامه نویسی محبوب و موفق شرکت داشته است. او طراح و خالق زبان توربو پاسکال و طراح ارشد زبان دلفی بوده است و هم اکنون در شرکت ماکروسافت به عنوان طراح ارشد زبان سی شارپ و توسعه دهنده ی زبان TypeScript فعالیت می کند. در سال 2001 جایزه "ممتازی در برنامه نویسی" از مجله Dr. Dobb's به وی اهدا شد. او را به عنوان پدر زبان C# می شناسند.

ماتریس همسازه


در این پست به یادآوری ماتریس همسازه (یا همسازه ماتریس) می پردازیم. همسازه که تنها برای "ماتریس های مربعی" موجود و قابل محاسبه است، به صورت زیر تعریف می شود : (فرض کنید A نام ماتریس ما باشد)


A i, j = (-1) ᴵ + ᴶ x | M i ,j |


منظور از A i, j ، همسازه درایه ی سطر i و ستون j از ماتریس اصلی است که برابر است با -1 به توان i+j ضربدر دترمینان ماتریس کهاد حاصل از حذف سطر i و ستون j از ماتریس اصلی. (البته قبل از آن باید می گفتم که ماتریس کهاد را هم با M نشان می دهیم و M i ,j یعنی ماتریس کهاد حاصل از حذف سطر i ام و ستون j ام ماتریس اصلی).
دقت کنید که از فرمول بالا یک عدد به دست می آید نه یک ماتریس، و آن عدد، i و j اومین همسازه ماتریس A می باشد. پس برای تعیین ماتریس همسازه یک ماتریس مربعی باید برای هر یک از درایه های ماتریس اصلی، فرمول بالا را به کار ببریم و همسازه هر درایه را تعیین کنیم و در جای متناظر قرار دهیم تا ماتریس همسازه به دست آید.

برنامه ی ضرب بولی ماتریس به زبان C++


در پست های قبل برنامه ای برای ضرب دو ماتریس بولی (ماتریس هایی که درایه های آنها تنها 0 و 1 هستند) به زبان C# (سی شارپ) قرار داده بودم که مثل اینکه خیلی مورد علاقه دوستان قرار گرفته بود. در این پست تقریبا برنامه مشابهی به زبان C++/CLI رو در برای شما قرار دادم که می توانید برای "ضرب معمولی ماتریس" و "ضرب بولین ماتریس" به کار ببرید. البته برای استفاده از این برنامه باید فریمورک .Net نسخه ی 4.5 را در کامپیوترتان داشته باشد.

تبدیل صریح یا cast در C++


از دستورات "تبدیل صریح" (explicit conversion) که cast نیز نامیده می شود، برای مجبور کردن کامپایلر به تبدیل انواع در زبان C++ استفاده می شود. انواع مختلفی بز دستور cast وجود دارند که یک به یک به انها می پردازیم. برای شکل دادن مقدار یک عبارت به یک نوع دلخواه به صورت زیر عمل می کنیم.


static_cast < "new type" > ("old type" or "expression");

کلمه ی static_cast در بیان می کند که cast به صورت ایستا یا static بررسی خواهد شد. به این معنی که هنگامی که برنامه ی شما کامپایل شد، دیگر در هنگام اجرا، بررسی نخواهد شد که آیا این دستور cast برای اعمال مطمئن هست یا خیر. نتیجه این دستور، تبدیل متغیر یا نتیجه ی یک عبارت (عبارت کوتاه و ساده یا عبارت پیچیده) به نوع اعلام شده در داخل علامت < > می باشد. 
در هنگام کار با کلاس ها با dynamic_cast کار خواهید کرد، که در آن تبدیلات به صورت پویا یا dynamic (در حال اجرای برنامه) بررسی و چک خواهند شد.
نوع بعدی تبدیل صریح، const_cast نام دارد که برای از بین بردن "ثابت بودن" یک ثابت یا یک عبارت به کار می رود.
reinterpret_cast و safe_cast نیز انواع دیگری از این دستورات هستند که در پست های بعدی به سراغ آنها می رویم.

وراثت در C++ (مقدمات)


در زبان برنامه نویسی C++ هنگامی که کلاسی را بر اساس کلاس موجود دیگری تعریف می کنید، به کلاس جدید، "کلاس وارث" یا به انگلیسی Derived Class و به کلاس اولیه، "کلاس پایه" یا Base Class گفته می شود. کلاس های وارث به طور خودکار داری تمام داده ها و (با کمی محدودیت) تمام توابع عضو کلاس پایه هستند و به قول معروف این اعضا را به ارث می برند. البته کلاس پایه نیز همچنان دارای این اعضا خواهد بود و کلاس پایه هم می تواند علاوه بر این اعضا دارای اعضای اختصاصی خود باشد.
توابعی که از کلاس پایه برای کلاس وارث، اختصاص نمیابد، "توابع سازنده"، "تابع نابودگر" و توابعی هستند که عملگر جایگزینی ( = ) را سربارگذاری می کنند. دلیل آن هم این است که هر کلاس دارای توابع سازنده و نابودگر خاص خود است. برای مثال تمامی کلاس هایی که در محیط دات نت (تحت CLR ) تعریف می کنید به طور خودکار وارثی از کلاس Base Object Class هستند حال انکه بخواهید اینطور باشد یا نه؛ و البته همین کلاس ها نیز می توانند کلاس پایه برای کلاس های دیگر باشند.
نحوه ی تعریف یک کلاس وارث مشابه کلاس های دیگر است و تنها تفاوت ان با یک پلاس معمولی مجزا در این است که پس از نام آن، نام کلاس پایه ذکر می شود. در زیر مثالی ساده برای این مورد آورد شده است.


کلاس پایه :

class parent
{public:
  bool flag;
  string str;
}

کلاس وارث :

class child : parent
{public:
  float f;
  short int si;
}

در بالا، parent یک کلاس پایه و child یک کلاس وارث می باشد. به این معنی که داده های عضو کلاس parent (که شامل str و flag هستند) برای کلاس child نیز قابل استفاده هستند. برای مثال می توان به صورت زیر به متغیر عضو flag در کلاس دسترسی پیدا کرد.


child obj;
obj.flag = true;

البته نه به همین سرعت ! باید دقت داشته باشید "وراثت" به طور پیشفرض به صورت "خصوصی" یا private صورت میگیرد و هنگامی که وراثت به صورت خصوصی تعریف شود نمی توان به داده های عضو به ارث گذاشته شده، در خارج از کلاس دسترسی پیدا کرد و اگر بخواهید دستور بالا را به کار ببرید با خطای کامپایلر موجه خواهید شد که جمله ی بالا را به شما می گوید! برای تعریف وراثت کلاس به صورت "عمومی" یا public تنها کافی است قبل از نام کلاس پایه، کلمه ی public را اضافه کنید تا بتونید به اعضای داده ی به ارث گذاشته شده، در خارج از کلاس دسترسی داشته باشید.


class child : public parent;