تبليغاتX
خط تکنولوژی
سلام دوستان عزیز. دوباره برگشتم. امروز دومین پستیه که می دم. امروز می خوام در مورد شکست و ترس از شکست بنویسم. شروع کردن کارهای بزرگ همیشه با شکست های بزرگ همراهه. برای خیلی از ماها موقعیتی پیش میاد که کاری شروع کردیم و بعدش تو یه موقعیتی قرار گرفتیم که تمام در ها به رومون بسته شده. احساس ناراحتی داریم! سرخورده شدیم. فکر می کنیم دنیا به آخر رسیده، انگار هیچ کسی نیست که بخواد کمکمون کنه. خیلی از ماها تو همچین موقعیتی دست از تلاش برای تموم کردن اون کار بزرگ یا رسیدن به هدفمون می کشیم و روی یه کار دیگه تمرکز می کنیم. برای خود منم پیش اومده همچین شرایطی. ولی باید شجاع بود مقاومت کرد. باید تلاشمون و چند برابر کنیم تا به هدفمون برسیم.

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

خدا گر ز حکمت ببندد دری ----- زرحمت گشاید در بهتری

همیشه یادمون باشه تو بدترین شرایط خدا هست که میشه بهش تکیه کرد.

در آخر مطلبی میزارم در همین مورد که به نظر من خیلی جالب بود (البته منبع رو نمی دونم که نذاشتم)

وقتی اوضاع خراب میشه،
وقتی راهی که داری میری انگار همش سر بالاییه،
وقتی دخل و خرجت با هم نمی خونه،
وقتی میخوای لبخند بزنی ولی بی اختیار آه می کشی،
وقتی داری زیر بار مسئولیت خم میشی،
اگه لازمه استراحت کن
ولی تسلیم نشو!

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

تسلیم نشو!
حتی اگه سرعتت خیلی کم باشه
شاید باید یه ضربه دیگه به هدف بزنی.

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

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

همون وقتیه که نباید تسلیم بشی!

 

موفق و پایدار و سربلند باشید.

+ نوشته شده توسط حسین احمدی در پنجشنبه چهاردهم آبان 1388 و ساعت 22:18 |
سلامی دوباره به دوستان عزیز.

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

لینک دانلود:

http://rapidshare.com/files/302687846/Presentation.rar.html

فعلا" به خدا میسپارمتون.

+ نوشته شده توسط حسین احمدی در پنجشنبه چهاردهم آبان 1388 و ساعت 14:31 |
سلام (سلام سلامتی میاره)

بعد از مدتی (البته یه خورده طولانی) به سرم زد بیام وبلاگ و آپدیت یا همون Update یا به قول معروف به روز رسانی کنم. البته خیلی سخته!!!!!!
ساعت ۱۲:۳۵ دقیقست. حسابی خستم، فردا دانشگاه ارائه دارم و تازه تونستم اسلاید و واسه فردا آماده کنم. خداییش اسلاید درست کردن کار سختیه، ولی عجب اسلایدی شد. خودم کلی با اسلاید خودم حال کردم! (خلی بده آدم از خودش اینقدر تعریف کنه! نه؟؟؟) موضوعی که باید در بارش ارائه بدم SOA یا همون معماری سرویس گرای خودمونه، مبحث خیلی پیچیده ولی شیرینیه. خلاصه که مطالب و آماده کردم و فردا باید برم وسط گود. شما هم واسم دعا بفرمائید.

بریم سر اصل مطلب. امروز داشتم با علی (منظورم همون دایی علیه دیگه، دایی بزرگوار بنده که البته 4 سال از خودم کوچیکتره) در مورد رفتن صحبت می کردم. شاید بپرسید کجا؟ منظورم اونور آبه. یه جا غیر از اینجا. به احتمال خیلی زیاد آمریکا یا کانادا. می خوام تو DV Lottery شرکت کنم. اگه زد و به اسممون در اومد که چه بهتر، کی بدش میاد!!!!!! ولی اگه تا چندین سال آینده به اسمم در نیومد، میرم کانادا که بعد از اونجا یه راهی پیدا کنم واسه بقیش. خیلی ها هم بهم القابی زیبایی مانند وطن فروش، غرب زده!!!!! و امثالهم نسبت میدند. (البته علی جون نه ها، خیلی پایست، شاید یه روز دوتایی، نه ببخشید 4 تایی (منظورم با همسران گرامی هست) زدیم به دیار غربت).  ولی اشکالی نداره، من پوستم کلفت تر از این حرفاست. البته دلایلی که دارم خیلی محکمه، مثلا":

1. جایی که مثل ایران اینقدر قانون مند نباشه! (شما از افعال معکوس استفاده کنید!)
2. جایی که مثل ایران مردمش واسه چندر غز پول سر همدیگه رو کلاه نزارن و به هم دروغ نگن.
3. جایی که بتونم رشد کنم. از نظر علمی مخصوصا" که خیلی واسم مهمه
4. جایی که به آزادی های اولیه یک انسان ارزش داده بشه.
5. جایی که بتونم تو یه دانشگاه درست حسابی درس بخونم (البته اگه بهتر از دانشگاه آزاد بتونم گیر بیارم!!!!!!!!!!خدا کنه مسئولین دانشگاه نخونن)

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

خلاصه این قدر مقدمه چینی کردم که بگم از این به بعد مطالبی در مورد آموزش زبان شیرین انگلیسی (البته به شیرینی زبان فارسی نمیشه ها، این و جدی میگم) تو وبلاگ خواهم گذاشت. اگه در مورد مهاجرت و مسائلی از این قبیل مطالبی داشتم هم واستون میزارم که اگه شما ها هم خدای نکرده، زبنوم لال، بلا به دور، قصد رفتن و دارید ازشون استفاده کنید.

راستی اسلاید ها رو هم بعد از ارائه تو دانشگاه واستون میزارم که به قول معروف استفاده کنید، بعلاوه سایر مطالب مربوطه. خوب ساعت ۱۲:۴۹ دقیقه شد. دیگه عرضی ندارم!!!!! تا مطلب بعدی همگی رو به خدای بزرگ میسپارم. (می سپارم). گود بای

+ نوشته شده توسط حسین احمدی در پنجشنبه هفتم آبان 1388 و ساعت 0:50 |

آموزش LINQ

حسین احمدی

 

تاپیک آموزشی LINQ در سایت دات نت سورس با مطالب جدید به روز رسانی شد. دوستان می تونند از طریق آدرس زیر مقاله رو مطالعه کنند.

http://p2p.dotnetsource.com/Default.aspx?g=posts&t=7098

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

 

+ نوشته شده توسط حسین احمدی در شنبه سیزدهم تیر 1388 و ساعت 19:35 |

Callback Interfaces

 

در این مقاله میخوام در مورد Callback Interface ها صحبت کنم. (واژه فارسی معادل callback پیدا نکردم دیگه کلمه اصلی رو نوشتم، اینجوری بهترم هست تازه)

 

در این مقاله فرض میکنم که شما با ویژگی های برنامه نویسی شئ گرا آشنایی دارید. سعی میکنم در آینده طی چند مقاله در مورد برنامه نویسی شئ گرا توی C# توضیحاتی رو بدم.

 

در ابتدا یه توضیح خیلی مختصر در مورد اینترفیس ها بدم و بعد برم سر اصل مطلب. اینترفیس ها چی هستند؟ در زبان C# یک اینترفیس شامل مجموعه ای از تعاریف متد ها یا خصوصیات می باشد. منظورم از تعریف اینه که این متد ها یا خصوصیات پیاده سازی نمی شن، فقط تعریف می شن. اگه با کلاس های Abstract کار کرده باشید منظورم رو متوجه می شید. وقتی یک کلاس اینترفیسی رو پیاده سازی میکنه، باید تمامی متد ها و خصوصیات تعریف شده داخل اون اینترفیس رو پیاده سازی کنه. برای اینکه مطلب روشن تر بشه یه مثال خیلی کوچیک میزنم:

 

C# 2008 Code

public interface IMyInterface

{

    void MethodA(int p1, int p2);

    string MethodB(string p);

}

 

public class MyClass : IMyInterface

{

    public void MethodA(int p1, int p2)

    {

        // MethodA implemention

    }

 

    public string MethodB(string p)

    {

        // MethodB implemention

    }

}

 

کلاس MyClass اینترفیس IMyInterface رو داخل خودش پیاده سازی کرده. یکی از مهمترین کاربرهای اینترفیس ها در برنامه نویسی Polymorphic هست، بدین معنی که شما میتونید با استفاده از اینترفیس، شئ جدیدی از روی هر کلاسی که اون اینترفیس رو پیاده سازی کرده ایجاد کنید و بعد متدهای مربوط به همون شئ رو صدا بزنید. مثال:

 

C# 2008 Code

class Program

{

    static void Main(string[] args)

    {

        IMyInterface obj = new MyClass();       

    }

}

 

اما هدف اصلی این مقاله آشنا شدن با Callback Interface ها هست. بوسیله این تکنیک اشیاء می توانند بوسیله یکسری متدها یا خواص به صورت دو طرفه با همدیگه ارتباط برقرار کنند. این کار چیزی معادل event ها هستند و البته راه استاندارد ساختن callback ها استفاده از event ها می باشد. اما این کار با interface ها هم امکان پذیره. برای آشنا شدن با نحوه استفاده از callback interface ها یک پروژه جدید کنسول ایجاد کنید و داخل این پروژه یک کلاس با نام Person که دارای دو خصوصیت FirstName و LastName است ایجاد کنید:

 

C# 2008 Code

// the person class

public class Person

{

    private string firstName;

    private string lastName;

 

    public string FirstName

    {

        get

        {

            return firstName;

        }

        set

        {

            this.firstName = value;

        }

    }

    public string LastName

    {

        get

        {

            return lastName;

        }

        set

        {

            this.lastName = value;

        }

    }

}

 

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

 

C# 2008 Code

// the callback interface

public interface INotification

{

    void OnChangeFirstName(string ofname, string nfname);

    void OnChangeLastName(string olname, string nlname);

}

 

حال باید کلاسی تعریف کنیم که اینترفیس INotification را پیاده سازی کند. به این کلاس ها معمولا" کلاس های sink میگویند. کلاسی با نام PersonSink ایجاد کرده و اینترفیس INotification را داخل آن پیاده سازی میکنیم:

 

C# 2008 Code

// the person sink class

public class PersonSink : INotification

{

    void INotification.OnChangeFirstName(string ofname, string nfname)

    {

        Console.WriteLine("persons firstname changed from {0} to {1}",

            ofname, nfname);

    }

 

    void INotification.OnChangeLastName(string olname, string nlname)

    {

        Console.WriteLine("persons lastname changed from {0} to {1}",

            olname, nlname);

    }

}

 

اگر با مفهوم event ها آشنایی داشته باشید کلاس PersonSink چیزی معادل پیاده سازی event ها است. حال باید داخل کلاس Person از این کلاس استفاده کنیم. برای ادامه باید لیستی از اشئیاء sink در داخل کلاس person داشته باشیم که برای این کار یک ArrayList داخل کلاس Person ایجاد میکنیم تا Sink های مورد نظر را داخل آن نگهداری کنیم، همچنین نیاز به دو متد با نام های AttachSink و DetachSink داریم تا Sink های مورد نظر را به لیست Sink های کلاس Person اضافه کنند و یا یک Sink را از لیست حذف کنند. همچنین داخل Property های FirstName و LastName متدهای مربوطه Sink های شئ را صدا می زنیم، بعد از اعمال تغییرات باید کلاس Person به صورت زیر تبدیل شود.

 

C# 2008 Code

// the person class

public class Person

{

    private ArrayList sinks = new ArrayList();

    public void AttachSink(INotification sink)

    {

        sinks.Add(sink);

    }

 

    public void DetachSink(INotification sink)

    {

        if (sinks.Contains(sink))

            sinks.Remove(sink);

    }

 

    private string firstName;

    private string lastName;

 

    public string FirstName

    {

        get

        {

            return firstName;

        }

        set

        {

            foreach (INotification sink in sinks)

                sink.OnChangeFirstName(firstName, value);

            this.firstName = value;

        }

    }

    public string LastName

    {

        get

        {

            return lastName;

        }

        set

        {

            foreach (INotification sink in sinks)

                sink.OnChangeLastName(lastName, value);

            this.lastName = value;

        }

    }

}

 

حال می توانیم شئ جدید از نوع Person ایجاد کرده، یک شئ از نوع PersonSink ایجاد کنیم و sink را به شئ ایجاد شده از نوع Person الصاق کنیم:

 

C# 2008 Code

class Program

{

    static void Main(string[] args)

    {

        Person p = new Person();

        PersonSink sink1 = new PersonSink();

        p.AttachSink(sink1);

        p.FirstName = "Hosein";

        Console.WriteLine(p.FirstName);

        p.DetachSink(sink1);

        p.FirstName = "Ali";

        Console.WriteLine(p.FirstName);

    }

}

 

با اجرای کد بالا خروجی به ترتیب به صورت زیر خواهد بود:

 

Output

persons firstname changed from  to Hosein

Hosein

Ali

Press any key to continue . . .

 

بار اول که شئ sink مورد نظر را به شئ p الصاق کردیم هنگام تغییر FirstName پیغامی بر روی صفحه ظاهر شد. اما بعد از اینکه اینکه شئ sink از لیست sink های شئ p حذف شد، هیچ پیغامی مشاهده نشد. بوسیله این روش می توان به دو یا چندین شئ در داخل حافظه ارتباط برقرار کرد. توجه کنید که میتوان چندین sink را به شئ p الصاق کرد، به شرطی که کلاس sink ما اینترفیس INotification را پیاده سازی کرده باشد:

 

C# 2008 Code

public class AnotherPersonSink : INotification

{

    void INotification.OnChangeFirstName(string ofname, string nfname)

    {

        Console.WriteLine("This is only for illustration (FirstName)");

    }

 

    void INotification.OnChangeLastName(string olname, string nlname)

    {

        Console.WriteLine("This is only for illustration (LastName)");

    }

}

 

در بالا یک کلاس sink جدید تعریف کردیم و حالا می توانیم شئ ای از نوع AnotherPersonSink را به شئ p ضمیمه کنیم:

 

C# 2008 Code

class Program

{

    static void Main(string[] args)

    {

        Person p = new Person();

        PersonSink sink1 = new PersonSink();

        AnotherPersonSink sink2 = new AnotherPersonSink();

        p.AttachSink(sink1);

        p.AttachSink(sink2);

        p.FirstName = "Hosein";

        Console.WriteLine(p.FirstName);

        p.DetachSink(sink1);

        p.FirstName = "Ali";

        Console.WriteLine(p.FirstName);

    }

}

 

پس از اجرای کد بالا خروجی کد به صورت زیر خواهد بود

 

Output

persons firstname changed from  to Hosein

This is only for illustration (FirstName(

Hosein

This is only for illustration (FirstName(

Ali

Press any key to continue . . .

 

امیدوارم با خواندن این مقاله با کاربرد Callback interface ها آشنا شده باشید. اما این نکته رو همیشه یادتون باشه، راه استاندارد برای پیاده سازی Callback ها استفاده از Event ها است.

 

تا پست بعدی همگی شما رو به خدا می سپارم.

 

موفق باشید.

 

+ نوشته شده توسط حسین احمدی در شنبه دوم آذر 1387 و ساعت 8:18 |

اختصاص حافظه داینامیک در C++

Dynamic Memory Allocation in C++

 

یکی از مباحث مهم و پرکاربرد در C++ تخصیص حافظه داینامیک برای متغیر ها می باشد. در حالت معمولی وقتی متغیری داخل برنامه تعریف می شود، آن متغیر داخل حافظه Stack قرار میگیرد. اما با اختصاص حافظه به صورت داینامیک برای یک متغیر آن متغیر داخل حافظه Heap قرار میگیرد. اختصاص حافظه داینامیک در زبان C++ کاربرد های زیادی دارد که در ادامه با برخی از آنها آشنا خواهیم شد. برای شروع بهتر است نگاهی به مفهوم حافظه های Stack و Heap داشته باشیم.

حافظه Stack: حافظه در داخل برنامه های C++ به دو بخش تقسیم می شود: حافظه Stack و حافظه Heap .حافظه Stack برای نگهداری متغیر های معمولی و نگهداری اطلاعات توابع در هنگام فراخوانی استفاده می شود. به طور کلی می توان گفت مهمترین کاربرد حافظه Stack در فراخوانی توابع و کنترل آنها می باشد. برای این که با طرز کار حافظه Stakc بیشتر آشنا شوید، می توان این بخش از حافظه را به ستونی از بشقاب های رو هم قرار گرفته تشبیه کرد. آخرین بشقابی که وارد شده، اول از همه از ستون بشقاب ها خارج می شود. این حالت به LIFO-Last In First Out معروف است. این مسئله در مورد توابع نیز سازگار است. زمانی که تابعی فراخوانی می شود این تابع به همراه تمامی متغیرهای محلی خودش در داخل حافظه Stack قرار می گیرد. با فراخوانی یک تابع جدید این تابع بر روی تابع قبلی قرار میگیرد و کار به همین صورت ادامه پیدا می کند. در حقیقت می توان گفت که بالاترین تابع در حافظه Stack تابعی است که هم اکنون در حال اجرا می باشد. زمانی که کار فراخوانی یک تابع تمام شد آن تابع به همراه تمام متغیرهای مربوطه از داخل حافظه Stack خارج می شود. برای روشن تر شدن موضوع حالت زیر را در نظر بگیرید. کلیه برنامه ها C++ با فراخوانی تابع main شروع میشوند. پس اولین تابعی که داخل Stack قرار میگیرد تابع main است. حال فرض کنید که بعد از تابع main تابع func1 و از داخل تابع func1 تابع func2 فراخوانی شود. در این حالت ابتدا تابع func1 در حافظه Stack روی تابع main و سپس تابع func2 بر روی تابع func1 میگیرد که حالت حافظه Stack به صورت زیر در می آید:

 

Stack Memory -> main() | func1 | fun2

 

پس از آنکه فراخوانی تابع func2 به پایان رسید این تابع از داخل حافظه Stack خارج شده و کنترل به تابع func1 باز می گردد و stack به صورت زیر در می آید:

 

Stack Memory -> main() | fun1

 

زمانی که فراخوانی تابع func1 به پایان برسد این تابع از حافظه stack خارج شده و کنترل به تابع main باز میگردد و این روند به همین صورت ادامه دارد تا زمانی که کار فراخوانی تابع main تمام شده و برنامه به اتمام رسد. با اتمام فراخوانی تابع main این تابع از از Stack خارج شده و کنترل به سیستم عامل باز می گردد. برای آشنایی بیشتر با ساختار Stack می توانید به یکی از کتابهای ساختمان داده ها مراجعه کنید.

 

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

 

با تعاریفی که بالا شد، می توانیم به مبحث اختصاص داینامیک حافظه در C++ بپردازیم. در حالت عادی ما متعیر ها را به صورت زیر تعریف می کنیم:

 

C++ Code

int myInt = 20;

 

با این تعریف متغیر myInt داخل حافظه Stack قرار میگیرد که در بالا خواص مربوط به حافظه Stack مطرح شدند. حال اگر ما بخواهیم این متغیر داخل حافظه Heap قرار بگیرد به چه صورت باید عمل کنیم؟ انجام این کار به راحتی و بوسیله دستور new امکان پذیر است.

برای اینکه بتوانیم متغییر myInt را که در بالا تعریف کردیم داخل حافظه Heap قرار دهیم از دستور زیر استفاده می کنیم:

 

C++ Code

int* myInt = new int(10);

 

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

 

C++ Code

int* myInt;

myInt = new int(10);

 

با نوشتن هر یک از دستورات بالا متغیر myInt به جای اینکه در حافظه Stack قرار بگیرد، در حافظه Heap فضایی برای آن اختصاص داده خواهد شد. اما نکته مهمی که باید به آن توجه شود این است که متغیر myInt در ابتدا به عنوان یک اشاره گر تعریف شده است. پس برای استفاده از مقدار آن باید از علامت * که به آن dereference  نیز می گویند استفاده کرد. فرض کنیم که بخواهیم مقدار myInt را بر روی صفحه چاپ کنیم. باید به صورت زیر بنویسیم:

 

C++ Code

cout << *myInt << endl;

 

اما همانطور که در بالا اشاره شد، بعد از اختصاص حافظه داینامیک برای یک متغیر، خود برنامه نویس باید به صورت دستی این متغیر را از حافظه پاک کند. این کار با دستور delete امکان پذیر است. برای مثال، برای حذف متغیر myInt به صورت زیر می نویسیم:

 

C++ Code

delete myInt;

 

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

 

C++ Code

int main()

{

      int arraySize;

      cout << "Enter array size: ";

      cin >> arraySize;

      int* myList = new int[arraySize];

      delete [] myList;

      return 0;

}

 

در قطعه کد بالا اندازه آرایه از کاربر پرسیده شده و آرایه ای با اندازه وارد شده ایجاد می شود. با هر بار اجرای برنامه کاربر می تواند یک سایز دلخواه را وارد کند و برنامه آرایه ای با اندازه وارد شده ایجاد کند. به دستوری که آرایه را از حافظه پاک می کند توجه کنید. در صورتی که متغیر تعریف شده آرایه باشد، برای پاک کردن آن از حافظه Heap حتما" باید بعد از دستور delete علامت [] قرار گیرد تا برنامه بداند که باید یک آرایه را از حافظه Heap پاک کند.

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

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

 

C++ Code

 

 

1

2

3

4

5

6

 

7

 

8

9

 

10

 

11

12

13

int main()

{

      int rows = 0;

      int cols = 0;

      cout << "rows: ";

      cin >> rows;

      cout << "cols: ";

      cin >> cols;

     

      int** myList = new int*[rows];

 

      for(int i = 0; i < rows; i++)

            myList[i] = new int[cols];

 

      myList[1][2] = 7;

 

      for( int i = 0 ; i < ROWS ; i++ )

            delete [] dynamicArray[i] ;

      delete [] dynamicArray;

 

      return 0;

}

 

در خط های 1 تا 6 متغیرهای rows و cols تعریف شده اند و داخل آنها مقادیر مربوط به سطر و ستون که توسط کاربر وارد می شود قرار میگیرد. تعریف خط 7 بسیار مهم است که در بالا نیز در مورد آن توضیح داده شد. در این خط از برنامه تعداد سطر های آرایه تعریف می شوند که هر یک خود از نوع اشاره گر اند. در خط 8 و 9 با یک حلقه ستون های مربوط به آرایه دو بعدی ایجاد می شوند. برای مثال اگر کاربر مقدار 4 برای تعداد سطرها و تعداد 5 برای تعداد ستون ها را وارد کند در خط هفتم آرایه ای با 4 خانه ایجاد می شود که هر یک از خانه های آن خود تعریف یک اشاره گر از نوع int هستند و با دستورات خط های 8 و 9 برای هر یک از خانه های آرایه حافظه ای با تعداد خانه های cols اختصاص داده میشود. دستور خطوط 11، 12 و 13 برای پاک سازی حافظه بسیار مهم است و نباید فراموش شود. ابتدا آرایه های مربوط به هر یک از خانه های myList پاک شده و سپس خود آرایه myList از داخل حافظه پاک می شود.

اختصاص حافظه برای آرایه های بیشتر از 2 بعد پیچیده تر هستند.

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

+ نوشته شده توسط حسین احمدی در شنبه یازدهم خرداد 1387 و ساعت 1:14 |

کتابی که میخوام معرفی کنم یکی از بهترین کتابهای زبان C++ در سطح حرفه ای است. کتاب Professional C++ از انتشارات Wrox کتابی است که شما را با شناخته شده ترین متدهای برنامه نویسی و همچنین مباحث پیشرفته برنامه نویسی C++ آشنا میکنه. قبل از خوندن این کتاب بهتره پیش زمینه ای تو زبان C++ داشته باشید. خواندن کتابی مثل C++ How To Program قبل از خوندن این کتاب توصیه میشه.

http://rapidshare.com/files/117770793/ProfessionalCPP.rar

کلمه عبور فایل فشرده: techline.blogfa.com

 

+ نوشته شده توسط حسین احمدی در دوشنبه ششم خرداد 1387 و ساعت 20:10 |

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

در ابتدا با نحوه تعریف این نوع اشاره گرها در ++C آشنا می شویم. سپس با یک مثال با کاربرد آنها آشنا خواهیم شد.

نحوه تعریف اشاره گر هایی که به توابع اشاره میکنند به صورت زیر است:

 

C++ Code

int (*ptrfun)(int, int);

 

مشاهده میکنید که نحوه تعریف اشاره گر مانند تعریف prototype برای یک تابع هست. با این تفاوت که نام اشاره گر به همراه علامت * داخل پرانتز قرار میگیرند. با این تعریف اشاره گر ptrfun میتواند آدرس هر تابعی با الگوی مشخص شده در تعریف را در خود نگه داری کند. (منظور از الگوی مشخص شده نوع داده برگشتی و نوع داده پارامتر های تابع است)

 

نکته: همیشه به خاطر داشته باشید که نام اشاره گر و علامت * باید داخل پرانتز قرار بگیرند. برای مثال تعریف زیر برای اشاره گر به یک تابع اشتباه است، زیرا تعریف زیر بیان گر تابعی است که مقدار برگشتی آن اشاره گر از نوع int است.

 

C++ Code

int *ptrfun(int, int)


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

 

C++ Code

#include < iostream >

using std::cout;

using std::cin;

using std::endl;

 

int Max(int num1, int num2)

{

      return (num1>num2) ? num1 : num2;

}

 

int main()

{

      int (*ptrMax)(int,int);

      ptrMax = Max;

      cout << ptrMax(8, 12); // Equals with Max(8, 12);

}

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

 

C++ Code

  cout << ptrMax(8, 12);

    cout << Max(8, 12);     

 

در C++ این امکان وجود دارد که برای توابع پارامترهایی از نوع اشاره گر به توابع تعریف کنیم. به این معنی که آدرس تابعی را به عنوان پارامتر به یک تابع دیگر بفرستیم. برای روشن شدن قضیه به مثال زیر توجه کنید. مثال زیر الگوریتم مرتب سازی انتخابی (Selection Sort) است. به تابع SortList دقت کنید، آخرین پارامتر آن (پارامتر compare) اشاره گر به یک تابع است، بوسیله این اشاره کر نوع مرتب سازی در تابع هنگام فراخوانی مشخص می شود که لیست به صورت صعودی مرتب شود یا نزولی. (هنگام فراخوانی تابع SortList میتوان آدرس تابع ascending جهت مرتب سازی به صورت صعودی و یا آدرس تابع descending جهت مرتب سازی به صورت نزولی را به تابع ارسال کرد)

 

C++ Code

#include < iostream >

using std::cout;

using std::cin;

using std::endl;

 

void SortList( int* list, int size, bool (*compare)(int,int))

{

    int tmp;

    for(int counter1 = 0; counter1 < size; counter1++)

        for(int counter2 = counter1+1; counter2 < size; counter2++)

            if(compare(list[counter1],list[counter2]))

            {

                tmp = list[counter2];

                list[counter2] = list[counter1];

                list[counter1] = tmp;

            }

}

 

bool ascending(int num1, int num2)

{

    if(num2

        return true;

    else

        return false;

}

bool descending(int num1, int num2)

{

    if(num2>num1)

        return true;

    else

        return false;

}

 

int main()

{

    int myList[] = {7, 8, 5, 9, 4, 2, 5, 1, 3};

    for(int x = 0; x < 9; x++)

        cout << myList[x] << " ";

    cout << endl;

    SortList(myList, 9, descending);

    // SortList(myList, 9, ascending);

    for(int x = 0; x < 9; x++)

        cout << myList[x] << " ";

 

    return 0;

}

 

تا پست بعدی همگی شاد و خرم باشید.

+ نوشته شده توسط حسین احمدی در دوشنبه ششم خرداد 1387 و ساعت 1:29 |
سلام دوستان، خیلی از شما شاید با محیط برنامه نویسی Code::Blocks آشنا باشید. این برنامه که به صورت رایگان و البته متن باز بر روی اینترنت وجود داره برای شما محیطی برای نوشتن کدهای ++C فراهم میکنه. اگر از کامپایلر MiniGW و البته ویندوز ویستا استفاده می کنید شاید مشکلاتی با کامپایل و اجرای برنامه هاتون داشته باشید. لینک زیر به شما میگه چجوری این مشکلات رو حل کنید.:

http://wiki.codeblocks.org/index.php?title=Installing_MinGW_with_Vista

اگر مراحل بالا رو انجام دادید و موقع کامپایل پیغامی دریافت کردید که فایل crt2.o رو پیدا نمکینه فایل های crt2.o و crtbegin.o و crtend.o رو از شاخه MiniGW به شاخه پروژه ای که ساختید اضافه کنید تا مشکلتون حل بشه.

البته این برنامه میتونه از کامپایلر ++Microsoft Visual C هم استفاده کنه که من مشکلی باهاش نداشتم.

موفق باشید.

+ نوشته شده توسط حسین احمدی در جمعه ششم اردیبهشت 1387 و ساعت 1:39 |
دیگه خداییش از عجایبه توی یک روز ۲ تا پست دارم میدم  حالا عجایب و ولش کنیم بریم سراغ اصل مطلب.

بعضی وقت ها پیش میاد لینک یه چیزی رو تو نت میبینید و میخواید دانلود کنید، اما فایل روی سرور های رپید ذخیره شده و شامل چندین پارت هم هست، بعد شروع میکنید به دانلود و مثلا" تا پارت ۸ دانلود میکنید، یکهو میبینید که پارت ۹ از روی سرورهای رپید پاک شده، عجب ضدحالی میخوره آدم ، حالا با این لینکی که زیر میزارم میتونید همه لینک ها رو چک کنید ببینید سالم هست یا نه، بعد شروع کنید به دانلود کردن تا یه وقت ضدحال نخورید. میتونید چندین لینک رو یک جا چک کنید.

آدرس سایت چک کننده لینک های Rapidshare:

http://www.rapid-hook.com/index.php

موفق باشید/

+ نوشته شده توسط حسین احمدی در پنجشنبه یکم فروردین 1387 و ساعت 18:25 |