close
تبلیغات در اینترنت
خرید دامنه
اموزش تكنولوژي

آموزش تابع و توابع دوست کلاس در برنامه نویسی C++ توابع دوست کلاس در برنامه نویسی C++ (Class Friend functions) :

قبلا یادآوری شد که اعضای یک کلاس اعم از داده ها یا توابع دارای 3 نوع سطح دسترسی می باشند که شامل دسترسی خصوصی private و دسترسی عمومی public و دسترسی حفاظت شده protected است .

اگر داده ها و توابع عضو یک کلاس از نوع private تعریف شوند فقط داده ها و توابع درونی آن کلاس در داخل همان کلاس می توانند به آنها دسترسی داشته باشند و هیچ جزء دیگری در بیرون از کلاس حتی شی ساخته شده از همان کلاس هم اجازه و توانایی دسترسی و کار با آنها را ندارند مگر تابعی را تعریف نماییم که در اصطلاح دوست(Friend) کلاس مورد بحث باشد .

آموزش تابع و توابع دوست کلاس در برنامه نویسی C++ پس تابع دوست یک کلاس، تابع ویژه ای است که می تواند به تمامی اعضای کلاس حتی اعضای private نیز دسترسی داشته باشد. تفاوتی نمی کند که تابع دوست کلاس را عمومی یا خصوصی تعریف نماییم. یک تابع دوست کلاس طبق الگوی زیر تعریف می شود که باید از کلمه کلیدی friend در ابتدای آن استفاده نمود :

friend type FunctionName(Parameters List...)
{
    Function Body...
}

آموزش تابع دوست کلاس و کلاس دوست کلاس و تعریف آنها در برنامه نویسی C++ مثال) به اتفاق یکدیگر مثالی ابتدایی از تعریف تابع دوست کلاس و نحوه بکارگیری آن در کلاس را بررسی می نماییم :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
class Accumulator
{
private:
    int m_nValue;
public:
    Accumulator() { m_nValue = 0; }
    void Add(int nValue) { m_nValue += nValue; }
 
    // Make the Reset() function a friend of this class
    friend void Reset(Accumulator &cAccumulator);
};
 
// Reset() is now a friend of the Accumulator class
void Reset(Accumulator &cAccumulator)
{
    // And can access the private data of Accumulator objects
    cAccumulator.m_nValue = 0;
}

همانگونه که در کد برنامه نویسی C++ بالا ملاحظه می فرمایید در سطر 9 برای کلاس Accumulator، تابع دوستی بنام Reset تعریف شده که دارای پارامتری ورودی که یک شی از خود کلاس است می باشد .

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

آموزش نحوه تعریف تابع دوست کلاس friend function و استفاده از آن در برنامه نویسی C++ دقت کنید که برای تعریف بدنه و عملکرد یک تابع دوست کلاس دیگر نیازی به استفاده از عملگر :: به همراه نام کلاس نمی باشد در صورتیکه قبلا توضیح داده شد برای تعریف تابع عضو کلاس در بیرون از آن کلاس باید نام کلاس بهمراه عملگر :: ذکر شود .

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

آموزش تعریف تابع دوست کلاس و استفاده از آن در برنامه نویسی C++ مثال) در زیر به برنامه ای برای بکارگیری تابع دوست کلاس در C++ می پردازیم :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
#include <iostream.h>
#include <conio.h>

class  base
{
    int val1,val2;
   public:
    void get()
    {
       cout << "Enter two values:";
       cin >> val1 >> val2;
    }
    friend float mean(base ob);
};

float mean(base ob)
{
   return float(ob.val1+ob.val2)/2;
}

void main()
{
    clrscr();
    base obj;
    obj.get();
    cout << "n Mean value is : " << mean(obj);
    getch();
}
Enter two values: 10  20
Mean Value is: 15

در برنامه C++ بالا کلاسی بنام base وجود دارد که دارای 2 متغیر عضو private از نوع int و تابعی بنام get که دارای پارامتر ورودی نیست و دسترسی public برایش تعریف شده و یک تابع دوست کلاس بنام mean که نوع دسترسی آن مهم نیست و نوع بازگشتی float را برمیگرداند و دارای یک پارامتر ورودی است که شیئی از همان کلاس base میباشد .

بدنه تابع دوست کلاس از سطر 16 تا 19 در خارج از کلاس تعریف شده و براحتی و با ساخت یک شی بنام ob به متغیرهای عضو private کلاس base دسترسی دارد که میانگین دو عدد ورودی را محاسبه می نماید. در سطر 18 ما از اصل تبدیل نوع (Type Casting) برای جلوگیری از بروز خطای محاسباتی در نتایج برنامه استفاده کردیم. در واقع ما با استفاده از اصل تبدیل نوع به کامپایلر اعلام می کنیم که هرچند متغیرهای اولیه از نوع int هستند اما حاصل نتیجه را به صورت float و بدون گرد کردن و با قسمت اعشارش می خواهیم .

در نهایت و در تابع اصلی برنامه نیز یک شی از کلاس را ساخته و از آن استفاده می کنیم. نکته ای که عزیزان باید توجه کنند تابع clrscr است که در فایل سرآیند conio.h تعریف شده و موجب می شود که محتویات صفحه نمایش یا همان خروجی را پاک نماید و حافظه خروجی برنامه را clear کند که اسن دستور را هم در سطر 23 از برنامه C++ بالا مشاهده می کنیم .

آموزش کلاس دوست کلاس در برنامه نویسی C++ کلاس دوست کلاس در برنامه نویسی C++ (Class Friend class) :

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

آموزش تعریف کلاس دوست کلاس و استفاده از آن در برنامه نویسی C++ مثال) در زیر به برنامه ای برای بکارگیری کلاس دوست کلاس در C++ می پردازیم :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
 
// friend class
#include <iostream>
#include <conio.h>
using namespace std;

class CSquare;

class CRectangle
{
    int width, height;
  public:
    int area (){return (width * height);}
    void convert (CSquare a);
};

class CSquare
{
  private:
    int side;
  public:
    void set_side (int a){side=a;}
    friend class CRectangle;
};

void CRectangle::convert (CSquare a)
{
  width = a.side;
  height = a.side;
}
  
int main ()
{
  CSquare sqr;
  CRectangle rect;
  sqr.set_side(4);
  rect.convert(sqr);
  cout << rect.area();
  getch();
  return 0;
}
16

آموزش نحوه تعریف کلاس دوست کلاس friend class و استفاده از آن در برنامه نویسی C++ دوستان عزیز می خواهیم که کد بالا را بررسی یا Trace نماییم و کاملا مانند کامپایلر رفتار می کنیم، پس به مراحل این عمل دقت فرمایید که از کجا شروع، بررسی کرده و آنرا به پایان می رسانیم :

از تابع main شروع می کنیم پس وارد این تابع می شویم. در سطر 33 از برنامه می بینیم که شیئی بنام sqr از کلاسی بنام CSquare ایجاد شده است پس در مرحله بعدی به سراغ کلاس CSquare می رویم تا بررسی کنیم که چه اعضایی دارد و این اعضا چه کار یا کارهایی را انجام می دهند .

تعریف کلاس CSquare از سطر 16 شروع شده و تا سطر 23 ادامه میابد که دارای یک عضو خصوصی بنام side از نوع داده int و یک تابع عضو عمومی بنام set_side و کلاس دوست کلاس CRectangle است. تابع عضو set_side یک نوع داده ای int را بعنوان پارامتر ورودی دریافت می کند و مقدار آنرا در متغیر side قرار می دهد .

به ادامه بررسی یا trace برنامه از سطر 34 می پردازیم. در این سطر هم یک شی بنام rect از کلاس CRectangle ایجاد شده است، لذا به بررسی این کلاس در ادامه می پردازیم .

تعریف کلاس CRectangle از سطر 8 از برنامه شروع شده و تا سطر 14 ادامه میابد. این کلاس شامل دو متغیر عضو خصوصی بنامهای width و height از نوع داده ای int و دو تابع عضو عمومی بنامهای area و convert می باشد که وظیفه تابع اول حاصلضرب دو متغیر عضو خصوصی و وظیفه تابع دوم از سطر 25 تا 29 تعریف شده است که این تابع ورودی از نوع شی از کلاس CSquare را دارد .

در سطر 35 از برنامه با استفاده از شی ایجاد شده از کلاس CSquare به تابع عضو set_side با پارامتری با مقدار 4 دسترسی پیدا می کنیم لذا مقدار متغیر side به 4 تبدیل می شود .

در سطر 36 نیز با استفاده از شی ایجاد شده از کلاس CRectangle به تابع عضو convert با ورودی شی sqr دسترسی پیدا می کنیم. پس مقدار 4 در دو متغیر width و height قرار گرفته و در ادامه و در سطر 37 با دسترسی به تابع convert این دو مقدار در هم ضرب شده و حاصلضرب آن دو به عنوان خروجی بر میگردد و چاپ می شود که همان مقدار 16 است .

چون در سطر 22 از برنامه C++ بالا کلاس CSquare دوست کلاس CRectangle تعریف شده پس براحتی در سطرهای 27 و 28 به متغیرهای عضو خصوصی این کلاس دسترسی پیدا کرده و بر روی آنها کار می کند و در صورتیکه اگر دوست کلاس مورد نظر نبود این اجازه را نداشته و برنامه با خطایی روبرو میشد .

امیدوارم که مراحل بررسی یا trace یک برنامه را درک کرده و متوجه شده باشید که چگونه می شود ساختار هر برنامه ای را بادقت و بدرستی چک نمود که مهارت در این شیوه کمک شایانی به دید برنامه نویسی و نهایتا نوشتن یک برنامه صحیح در زبان برنامه نویسی C++ خواهد نمود .

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:36 توسط مهدی مترجمی | | تعداد بازدید : 31

مشکل کار با String یا رشته ها در برنامه Borland C++ و رفع این مورد با جهش به برنامه Visual C++ :

همانطور که در ابتدای مجموعه آموزش برنامه نویسی C++ خدمت شما عزیزان عرض شد ما برنامه های خود را در محیط نرم افزار Borland C++ آموزش دادیم. متاسفانه این نسخه از کامپایلر C++ رشته ها را پشتیبانی نمی کند و برای کار با رشته ها مثل اسامی، جملات و ... ما مجبور به نوشتن کدهای فراوانی خواهیم بود و بدلیل اینکه از این به بعد مطالب سنگین تر و مفهومی خواهد شد لذا تصمیم گرفتم که این مشکل را با استفاده از تابع کتابخانه ای std که در دیگر نسخه های C++ پشتیبانی می شود را رفع نمایم .

در اینجا من 2 مثال را مورد بررسی قرار می دهم تا عزیزان بتوانند در مواردی که نمی توانند از کتابخانه std استفاده کنند از آرایه ای از کاراکترها برای دسترسی و کار با رشته ها و برنامه نویسی در محیط Borland C++ استفاده نمایند .

آموزش رشته ها و آرایه های کاراکتری با استفاده از کتابخانه std و بدون آن در برنامه نویسی C++ مثال1) کار با رشته ها بدون استفاده از فایل سرآیند یا کتابخانه std، به کمک آرایه ای از کاراکترها در برنامه نویسی C++ :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
 
#include <iostream.h>
#include <conio.h>

class Employee
{
  public:
  	char m_strName[25];
	int m_nID;
	double m_dWage;
	
	void SetInfo(char *strName, int nID, double dWage)
	{
            strncpy(m_strName, strName, 25);
	    m_nID = nID;
	    m_dWage = dWage;
	}
	
	void Print()
	{
            cout << "Name: " ;
            for(int i=0;m_strName[i];i++)
            {
		cout << m_strName[i];
            }
            cout << " Id: " << m_nID << " Wage: $" << m_dWage << endl;
	}
};

int main()
{
    Employee cAlex;
    cAlex.SetInfo("Alex", 1, 25.00);

    Employee cJoe;
    cJoe.SetInfo("Joe", 2, 22.25);
	
    cAlex.Print();
    cJoe.Print();
    getch();
    return 0;
}
Name: Alex  Id: 1  Wage: $25.00
Name: Joe   Id: 2  Wage: $2.25

آموزش رشته ها و آرایه های کاراکتری با استفاده از کتابخانه std و بدون آن در برنامه نویسی C++ مثال2) کار با رشته ها با استفاده از فایل سرآیند یا کتابخانه std، برای راحتی و سهولت در برنامه نویسی C++ :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
35
 
#include <iostream.h>
#include <conio.h>
using namespace std;

class Employee
{
  public:
	char m_strName[25];
	int m_nID;
	double m_dWage;

	void SetInfo(char *strName, int nID, double dWage)
	{
            strncpy(m_strName, strName, 25);
            m_nID = nID;
            m_dWage = dWage;
	}       

	void Print()     
	{
            cout << "Name: " << m_strName << " Id: " <<  m_nID << " Wage: $" << m_dWage << endl;
	}
};

int main()
{
    Employee cAlex;
    cAlex.SetInfo("Alex", 1, 25.00);
    Employee cJoe;
    cJoe.SetInfo("Joe", 2, 22.25);

    cAlex.Print();
    cJoe.Print();
    getch();
    return 0;
}
Name: Alex  Id: 1  Wage: $25.00
Name: Joe   Id: 2  Wage: $2.25

همانطور که ملاحظه می فرمایید هر دو کد برنامه نویسی C++ بالا یک عمل را انجام می دهند با این تفاوت که در کد اول از فایل سرآیند std در برنامه استفاده نشده است لذا برای کار با رشته ها چند خط کد به تابع print در سطر 18 اضافه می شود، ولی در کد دوم ما از فایل سرآیند استفاده نمودیم که کتابخانه ای است برای شناسایی و سهولت کار با رشته ها در برنامه نویسی C++ .

چنانچه می بینید برای کار با رشته ها در محیط نرم افزار Borland C++ ما مجبور می شویم که با استفاده از تعریف آرایه ای از کاراکترها با متغیرهای رشته ای کار کنیم اما در نرم افزار Visual C++ بدلیل پشتیبانی از کتابخانه از پیش تعریف شده std، دیگر نیازی به آرایه نیست و مستقیما می توان با رشته ها کار کرد .

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

آموزش رشته ها و آرایه های کاراکتری با استفاده از کتابخانه std و بدون آن در برنامه نویسی C++ پس از این به بعد برای سهولت کار با زبان برنامه نویسی C++ و تمرکز بیشتر بر روی آموزش مطالب و دستورات مهمتر و جدید ما از فضای کاری std بهره می بریم تا حجم کدها کاهش پیدا نماید و شرایط جهت آنالیز و آموزش بهتر فراهم گردد، که در صورت نیاز عزیزان به کدنویسی در نرم افزار Borland C++، این مطلب کمکی باشد برای رفع این جابجایی فقط کافیست که این دو مثال را با یکدیگر مقایسه نمایید .

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:35 توسط مهدی مترجمی | | تعداد بازدید : 16

آموزش برنامه نویسی C++ تعریف کلاس و تابع سازنده و اشاره گر به کلاس و اشیاء کلاس ها (Classes) و اشیا (Objects) در برنامه نویسی C++ :

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

  • کلاس ها (Classes) :

کلاس ها همان نوع داده تجریدی یا انتزاعی (Abstract) هستند. به عبارتی یک نوع داده هستند که توسط برنامه نویس برای کار با داده ها و توابع و رویدادهای مختلفی تعریف می شوند. برای تعریف کلاس از الگوی زیر پیروی می کنیم :


1
2
3
4
5
6
7
8
9
10
 
class className
{
    // Define private variables & functions
    public:
        // Define public variables & functions
    private:
        // Define private variables & functions
    protected:
        // Define protected variables & functions
} objectsame;   // Declare Objects

همانطور که در بالا آمد، برای تعریف یک کلاس از کلمه کلیدی class استفاده می کنیم و نامی را در ادامه برای آن تعیین می کنیم .

متغیرها و توابع مربوط به class در درون بلوک آکولاد قرار خواهند گرفت. فرض بر این است که دسترسی داده ها و توابع private است مگر اینکه نوع دسترسی صراحتا اعلام شود .

داده ها و توابعی که طبق سطر 3 تعریف شوند بطور پیش فرض از سطح دسترسی private برخوردار خواهند بود زیرا چیزی برای آنها تعریف نشده است کما اینکه در سطر 6 این سطح دسترسی کاملا بیان شده است .

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

در سطر 4 می توان داده ها و توابعی را که دارای سطح دسترسی public یا عمومی هستند را تعریف نمود و این بدین معناست که داده ها و توابع با این سطح دسترسی هم در داخل و هم در خارج از class قابل دسترسی هستند .

در سطر 8 نیز نوع دسترسی protected ذکر شده، یعنی کلاس هایی که از این کلاس به ارث برده می شنود می توانند به این قسم از داده ها و توابع دسترسی داشته باشند .

در سطر 10 و در خارج از محدوده کلاس نیز باید اشیائی را برای دسترسی به اعضای class خود ایجاد نماییم که به ذکر نام یا نام هایی که با کاما از هم جدا می شوند بسنده می کنیم. دقت داشته باشید که ایجاد شی از کلاس را می توان در درون تابع main نیز انجام داد .

در ادامه شاهد تعریفی از یک کلاس خواهیم بود :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
#include <iostream.h>
#include <conio.h>

class CRectangle
{
        int x,y;
    public:
        void set_Values(int, int);
        int area() { return (x*y);}
} obj_1;

void CRectangle :: set_Values(int a, int b)
{
    x = a;
    y = b;
}

void main()
{
    obj_1.set_Values(3,4);
    CRectangle obj_2;
    obj_2.set_Values(5,6);
    cout << "area = " << obj_1.area() << "n";
    cout << "area = " << obj_2.area();
    getch();
}
area = 12
area = 30

در کد C++ بالا شاهد تعریف جامعی از یک class هستیم .

کلاس CRectangle در سطر 4 از برنامه تعریف شده و بدنه تعریف آن تا انتهای سطر 10 ادامه میابد. دو متغیر به نامهای x,y برای این کلاس تعریف شده است. چون هیچ سطح دسترسی برای آن دو مشخص نگردیده کامپایلر آنها را پیش فرض private تعیین می نماید یعنی فقط اعضای این class می توانند به آن دو دسترسی داشته باشند .

دو تابع با نامهای set_Values() و area() برای این class تعریف شده که یکی وظیفه دریافت مقادیر و دیگری محاسبه مساحت را بر عهده دارند .

عملکرد تابع set_Values() در بیرون از class و از سطر 12 الی 16 تعریف شده است، اما دستورات تایع area() در درون خود class بیان شده است که از هر یک از این دو روش برای تعریف دستورات و عملکرد توابع می شود استفاده نمود .

آموزش برنامه نویسی C++ تعریف کلاس و تابع سازنده و اشاره گر به کلاس و شی و اشیاء نکته) در سطر 12 به نحوه تعریف تابع در خارج از class دقت کنید که ابتدا نوع بازگشتی تابع وسپس نام class و بعد از آن از علامت :: و در نهایت نام تابع و آرگومانهای آن را بیان می کنیم .

در سطر 9 هم چنانچه مشاهده می کنید در همان محل تعریف تابع area() ، دستورات را هم برای تابع نوشته ایم .

برای کلاس CRectangle دو شی یا object ایجاد شده که یکی در سطر 10 و دقیقا بعد از تعریف class، و دیگری در تابع main در سطر 21. دقت کنید که برای ایجاد شی از کلاس در درون بدنه برنامه باید ابتدا نام کلاس و سپس نام شی را بیان نمایید .

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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
class CRectangle
{
     
        int x;
    public:
        void f1();
        void f2() ;
        int y;
    private:
        void f3();
        int z;
        
} obj_1;

void main()
{
    obj_1.x;  // ERROR - x is private
    obj_1.y;  // OK - y is public
    obj_1.f1();  // OK - f1 is public
    obj_1.f2();  // OK - f2 is public
    obj_1.f3();  // ERROR - f3 is private
    obj_1.z;  // ERROR - z is private
}

فکر کنم که توضیحات در کد گویای همه چیز باشد .

آموزش برنامه نویسی C++ تعریف کلاس و تابع سازنده و اشاره گر به کلاس و اشیاء تابع سازنده کلاس (Constructor) :

همانطور که مشاهده کردید در کلاس بالا تابع set_Values() وظیفه مقدار دادن به متغیر ها که همان عرض و طول یک چهار ضلعی هستند را بر عهده داشت. اما در کلاس تابعی بنام سازنده کلاس وجود دارد که کار مقداردهی اولیه به متغیرهای لازم را انجام می دهد .

تابع سازنده، تابع عضو ویژه ای است هم نام با نام کلاس که نوع بازگشتی ندارد و حتی از نوع void هم نیست اما می تواند پارامتر ورودی داشته باشد و دارای دسترسی public می باشد .

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

آموزش برنامه نویسی C++ تعریف کلاس و تابع مخرب و اشاره گر به کلاس و اشیاء تابع مخرب کلاس (Destructor) :

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

در ادامه به نحوه تعریف و استفاده از توابع عضو سازنده و مخرب در کلاس می پردازیم :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
#include <iostream.h>
#include <conio.h>

class CRectangle
{
        int *width, *heigth;
    public:
        CRectangle(int, int);
        ~CRectangle();
        int area() { return (*width * *heigth);}
};

CRectangle :: CRectangle(int a, int b)
{
    width = new int;
    heigth = new int;
    *width = a;
    *heigth = b;
}

CRectangle :: ~CRectangle()
{
    delete width;
    delete heigth;
}

void main()
{
    CRectangle rect1(3,4), rect2(5,6);
    cout << "rect1 area = " << rect1.area() << "n";
    cout << "rect2 area = " << rect2.area();
    getch();
}
rect1 area = 12
rect2 area = 30

خوب، تابع مولد (سازنده) کلاس در سطر 8 از برنامه و تابع مخرب کلاس هم در سطر بعدی تعریف شده اند. سطرهای 13 تا 25 نحوه رفتار این دو تابع عضو کلاس را بیان می کنند. دقت فرمایید که دو متغیر عضو کلاس از نوع اشاره گر تعریف شده اند، پس برای کار با آنها در تابع سازنده کلاس باید متغیرهایی از نوع اشاره گر داشته باشیم که این کار را در سطرهای 15و16 انجام داده ایم .

با استفاده از کلمه کلیدی new می توان یک object یا همان شی را تعریف نماییم. یک شی این قابلیت را دارد که هر نوعی را بگیرد (این را از مفهوم شی گرایی درک کردیم!). پس بعد از تعریف شی های width, height آنها را اشاره گر در نظر میگیریم (سطرهای 17و18) .

کلمه کلیدی delete که در سطرهای 23و24 بکار رفته است دستوری است برای آزادسازی حافظه اشغالی توسط هر شی یا متغیر ، ... در برنامه .

ادامه برنامه کاملا واضح است .

آموزش برنامه نویسی C++ تعریف کلاس و تابع سازنده و مخرب اشاره گر به کلاس و اشیاء و سربارگزاری توابع عضو کلاس سربارگذاری توابع عضو کلاس در برنامه نویسی C++ (Overloading Constructors) :

مانند سربارگذاری توابع، سازنده های کلاس را نیز میتوان با نامهای مشابه ولی با آرگومانهای متفاوت سربار نمود که در زیر نمونه ای را به همراه هم خواهیم دید :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
#include <iostream.h>
#include <conio.h>

class CRectangle
{
        int width,heigth;
    public:
        CRectangle();
        CRectangle(int, int);
        int area(void) { return (width*heigth);}
};

CRectangle :: CRectangle()
{
    width = 5;
    heigth = 5;
}

CRectangle :: CRectangle(int a, int b)
{
    width = a;
    heigth = b;
}

void main()
{
    CRectangle rect1(3,4);
    CRectangle rect2;
    cout << "rect1 area = " << rect1.area() << "n";
    cout << "rect2 area = " << rect2.area();
    getch();
}
rect1 area = 12
rect2 area = 25

نکته) به سطر 28 توجه نمایید که دیگر از پرانتز باز و بسته استفاده نمی کنیم و در صورت استفاده، کامپایلر از برنامه خطا خواهد گرفت (برخلاف سربارگذاری در توابع) .

آموزش برنامه نویسی C++ تعریف کلاس و تابع سازنده و اشاره گر به کلاس و اشیاء تابع سازنده پیش فرض (Default constructor) :

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


1
2
3
4
5
6
7
8
 
class CExample
{
    public:
        int a, b, c;
        void multiply (int n, int m) { a=n; b=m; c=a*b; }
};

CExample ex;

همانطور که در کد برنامه نویسی C++ بالا می بینیم برای کلاس هیچگونه تابع سازنده ای تعریف نشده اما میتوان از کلاس CExample یک شی بنام ex ایجاد نمود و در طول برنامه از آن استفاده کرد و تنها دلیل این موضوع فرض کامپایلر بر وجود یک تابع سازنده بدون پارامتر در کلاس است .

اما اگر خود برای کلاس تابع سازنده ای را تعریف کنیم دیگر کامپایلر فرضی را در نظر نگرفته و بر مبنای تابع سازنده تعریفی ما عمل خواهد کرد مانند کد زیر :


1
2
3
4
5
6
7
8
9
10
 
class CExample
{
    public:
        int a, b, c;
        CExample (int n, int m) { a=n; b=m; };
        void multiply () { c=a*b; };
};

CExample ex;         //نادرست
CExample ex(2,8);    //درست

در کد برنامه نویسی C++ بالا ما برای کلاس CExample که دارای یک تابع سازنده تعریفی توسط ما با 2 پارامتر ورودی است 2 شی تعریف کرده ایم. دستور ایجاد شی در سطر 9 نادرست است زیرا تابع سازنده این کلاس دارای 2 پارامتر است که در سطر 5 تعریف شده و در حین ایجاد شی از کلاس باید مقداردهی شوند و دیگر کامپایلر مبنا را فرض خود در نظر نمی گیرد و بر اساس کد ما عمل می نماید .

آموزش برنامه نویسی C++ تعریف کلاس و تابع سازنده و اشاره گر به کلاس و اشیاء اشاره گر به کلاس (Pointers to Classes) :

اشاره گرها همانطور که می توانند به متغیرها اشاره کنند، می توانند به اشیاء یک کلاس نیز اشاره کنند و چون شی نمونه ای از کلاس است پس به کلاس اشاره می کنند .

در حالت ساده برای دسترسی به اعضای کلاس توسط شی تعریفی، از نقطه (.) استفاده کردیم. اما در اشاره گر به شی باید از ترکیب 2 کاراکتر خط و بزرگتر (<-) استفاده کنیم. با هم مثالی کامل از اشاره گر به شی یا همان کلاس را بررسی می کنیم :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
 
#include <iostream.h>
#include <conio.h>

class CRectangle
{
    int width, height;
  public:
    void set_values (int, int);
    int area (void) {return (width * height);}
};

void CRectangle::set_values (int a, int b)
{
  width = a;
  height = b;
}

int main()
{
  CRectangle a, *b, *c;
  CRectangle * d = new CRectangle[2];
  b= new CRectangle;
  c= &a;
  a.set_values (1,2);
  b->set_values (3,4);
  d->set_values (5,6);
  d[1].set_values (7,8);
  cout << "a area: " << a.area() << endl;
  cout << "*b area: " << b->area() << endl;
  cout << "*c area: " << c->area() << endl;
  cout << "d[0] area: " << d[0].area() << endl;
  cout << "d[1] area: " << d[1].area() << endl;
  delete[] d;
  delete b;
  return 0;
}
a area: 2
*b area: 12
*c area: 2
d[0] area: 30
d[1] area: 56

همانطور که می بینید در قطعه کد برنامه نویسی C++ در خطوط 4 الی 10 تابعی با نام CRectangle بهمراه متغیرها و توابع عضوش تعریف شده است. تعریف تابع عضو کلاس در خطوط 12 الی 16 صورت گرفته و بدنه اصلی برنامه از سطر 18 شروع می شود .

در سطر 20 ما 3 شی از کلاس ایجاد کرده ایم که شی a معمولی و اشیاء b,c از نوع اشاره گر میباشند. در سطر 21 شیئی از نوع اشاره گر بنام d تعریف شده که به دو شی از کلاس CRectangle که بصورت آرایه در نظر گرفته اشاره می نماید. در واقع d شی اشاره گری است که به محل قرارگیری دو شی از کلاس اشاره می کند. و در سطر 22 نیز از کلاس یک شی ایجاد کردیم که به آن با استفاده از کلمه کلیدی new فضایی در حافظه اختصاص داده شده است .

در سطر 23 شی c حاوی آدرس شی a است پس می توان گفت که هر تغییری در a در c هم اعمال خواهد شد. در سطر 24 شی a از تابع عضو کلاس بنام set_values استفاده می کند و پارامترهای 1و2 را به آن می دهد. چون a یک شی معمولی از کلاس است پس برای بکارگیری آن از نقطه استفاده کردیم. اما در سطرهای 25 و26 چون از اشیائی که اشاره گر هستند استفاده کرده ایم پس با استفاده از عملگر مخصوص (->) آنها را به تابع عضو کلاس ربط می دهیم .

اگر دقت کنید می بینید که در سطر 21 ما شی اشاره گر d را بعنوان آرایه ای با طول 2 در نظر گرفته ایم پس دستور سطر 26 فقط به آدرس آن آرایه یعنی اولین خانه اشاره می کند. اما در سطر 27 ما دومین عضو آرایه که خود یک شی از کلاس است را به تابع عضو ربط دادیم به همین علت آنرا دیگر اشاره گر در نظر نمیگیریم و مانند یک شی معمولی از نقطه برای استفاده از کلاس عضو استفاده می کنیم .

در سطرهای 28 الی 32 ما با استفاده از دستور خروجی cout نتایج مورد نظر را در خروجی نمایش می دهیم و در انتها باید اشیائی را که با استفاده از کلمه کلیدی new ایجاد کرده ایم و به آنها در حافظه فضا اختصاص دادیم را با استفاده از کلمه کلیدی delete پاک کرده و فضاهای آنها را به حافظه برگردانیم .

عزیزان باید بادقت کد را مورد مطالعه قرار دهند و مفاهیم فصول قبل مثل اشاره گرها، توابع، آرایه ها و دیگر موارد را درک کرده باشند تا به راحتی قطعه برنامه C++ بالا را تجزیه و تحلیل نمایند .

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

حالت توضیح
*x اشاره شده توسط x
&x آدرس x
x.y عضو y از شی x
x.y عضو y از شی x
x->y عضو y از شی اشاره گر x
(*x)->y عضو y از شی اشاره گر x (همان مفهوم ردیف بالا)
x[0] اولین شی اشاره گر به x
x[1] دومین شی اشاره گر به x
x[n] n+1امین شی اشاره گر به x
+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:34 توسط مهدی مترجمی | | تعداد بازدید : 10

مفاهیم شی گرایی در برنامه نویسی C++ - OOP(Object Oriented Programming) :

ما در ابتدای مطالب کلی در مورد C++ صحبت کردیم و گفتیم که بد ترکونده، نه برای اینکه 1 در صد از این زبان را بنده شاید بلد باشم. بلکه برای اینکه این جز حقیقت چیزی نیست .

تنها اختلاف بین زبان C و C++ مبحثی است بنام شی گرایی یا OOP(Object Oriented Programming) که همین مورد کافی است که دنیای نرم افزار شاهد تحول عظیمی در طراحی و پیاده سازی نزم افزارهای کنونی باشد .

بد نیست بدانید که اندیشه شی گرایی در زبان C++ آنقدر قوی است که به جرئت می توان گفت تمامی نرم افزارهای موجود مدیون این دید از برنامه نویسی هستند. اکثر سیستم عامل های رایج مانند Linux, Macintosh, ... بر گرفته از تفکر C++ هستند و Windows را صرفا با C++ و مبانی C نوشته اند .

نرم افزار های غولی مانند Office, Photoshop, Nero, ... را با این زبان طراحی و پیاده سازی کرده اند .

بیشتر زبان های کاربری امروزی توانایی های خود را بدون تفکر C++ هیچ می دانند مثل Java, Javascript, PHP, Delphi, C#, .NET, ... !!!

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

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

مثال) یک مثال ساده را میتوان DragDrop در درون محیط Windows در نظر گرفت. این کار را با Copy,Paste نیز می توان انجام داد اما عمل کشیدن و رها کردن یک فایل یا فولدر و قرار دادن آن در محلی دیگر نیاز نرم افزارهای پیشرفته و کاربران پر توقع امروزی است .

مفهوم شی گرایی

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

به کارخانه BMW سازنده و طراح آن اتومبیل گفته می شود و به طرح و سیستم کلی آن طرح و الگوی ساخته شده از آن، مدل گفته می شود هر چند که مدل ها و طرح های دیگری نیز برای BMW وجود دارد. به اتومبیل BMW740Li که در همین تهران زیر پای یک آقا یا خانم توانمند است شیی از آن مدل گفته می شود. در این بین ممکن است فردی توانمندتر، از همان مدل با ویژگی های بهتری را به شرکت سازنده سفارش دهد که با کمی تغییر در جزئیات طرح اصلی شرکت آنرا به مشتری تحویل می دهد .

در برنامه نویسی شی گرا نیز همین طرز تفکر برقرارا است. در این مورد چهار مفهوم اساسی وجود دارد که هر یک را بررسی می کنیم :

نوع داده انتزاعی یا تجریدی (Data Abstract)

در زبان C++ انواع داده ای مختلفی مانند int,char,... تعریف شده اند و می توان از آنها در طول برنامه استفاده نمود اما نوع داده انتزاعی نوعی است که صرفا توسط خود کاربر تعریف می شود و نوع خاصی را شامل نمی شود و با ایجاد یک شی از آن نوع داده انتزاعی یا تجریدی می توان از داده ها و روال ها و رخدادهای درون آن بهره گرفت .

از این دسته می توان به Class, struct اشاره نمود که صدها و هزاران نوع از آنها را می توان با داده ها و روالهای مختلف تعریف نمود و با استفاده از یک یا چند شی آنها را در برنامه پیاده سازی کرد .

محرمانگی یا بسته بندی (Encapsulation)

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

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

وراثت (Inheritance)

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

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

چند ریختی (polymorphism)

طرف میره کارخانه BMW و تقاضا می کند که روی همین دنده ای که وجود دارد یک دنده هوایی برای پرواز کردن هم قرار بگیرد. شرکت هم سیستمی را پیاد سازی می کند که مثلا دنده X مثل قبل کار کند و در این شرایط به دنده هوایی تبدیل شود .

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

کلاس (Class)

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

شی (Object)

همان مدلی است که در تهران زیر پای شخص خاصی است. یعنی استفاده از خصوصیات و روالهای تعریفی در Class برای استفاده از آن .

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

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

با استفاده از برنامه نویسی مبتنی بر شی، یک نوع داده انتزاعی مثل Class تعریف شده و تمامی پارامترها، متغیرها، روالها، توابع، رخدادها و ... در همان Class تعریف می شود و برای دسترسی به هر یک از بیمه شدگان و کار با داده های آنها با تعریف یک Object از آن Class براحتی با تعداد بیشماری از بیمه شدگان می توان کار کرد و در صورت بروز مشکل یا ایجاد تغییر تنها کافی است که Class را تغییر داد .

ممکن است بیمه شدگانی دارای بیمه تکمیلی باشند پس از Class عمومی بیمه شدگان استفاده می کنند و Class جدیدی برای آنها تعریف می شود که از Class کلی خصوصیات و روالها را به ارث می برد یعنی دارای تمامی خصوصیات دیگر بیمه شدگان است به اضافه خصوصیات تعریفی برای خود. پس فرزند دارای کل خصوصیات و توابع پدر است بعلاوه خصوصیات خود و کاملتر از پدر .

با برنامه نویسی شی گراست که می توان به راحتی و مثل دنیای واقعی با برنامه تعامل داشت .

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:32 توسط مهدی مترجمی | | تعداد بازدید : 12

آموزش اشاره گر ها در برنامه نویسی C++ | Poiners

دوستان عزیز دقت داشته باشند که داریم کم کم از درب ورودی برنامه نویسی رد می شیم .

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

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

تعریف مفاهیم

آموزش برنامه نویسی، اشاره گرها، آرایه ها، پارامترهای تابع و توابع اشاره گر : متغیری است که آدرس خانه های سیستم را در خود نگه می دارد (آدرس هر متغیر در حافظه اشاره گر است) .

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

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

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

می دانیم که متغیر ها در حافظه ذخیره می شوند اما مقدار حافظه مورد نیازشان با یکدیگر متفاوت است :

  • char : 1 Byte
  • int : 2-4 Byte
  • float : 4 Byte
  • double : 8 Byte

مثلا اگر ما متغیری از نوع int را تعریف کنیم 2 یا 4 بایت را اشغال می کند و به این معنی است که تعداد 4 تا 8 خانه پشت سر هم از حافظه را اشغال می کند که آدرس آن اولین آدرس خانه حافظه در نظر گرفته خواهد شد .

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

آدرس حافظه را فقط می توان در یک متغیر از نوع اشاره گر تعریف نمود :

Type *Name;

int *P;

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

تعریف اشاره گر بالا را می توان به طریق زیر تفسیر نمود :

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

دقت کنید که نوع یک اشاره گر به نوع متغیرهایی که به آدرس آنها اشاره می کند بستگی دارد و باید با آن یکسان باشد. یعنی نوع اشاره گری که به آدرسهایی که شامل متغیر هایی از نوع duoble است نمی تواند int یا char یا هر چیز دیگری غیر از همان duoble باشد .

تعریف مفاهیم

آموزش برنامه نویسی، اشاره گرها، آرایه ها، پارامترهای تابع و توابع عملگرهای اشاره گر در C++ :

آموزش برنامه نویسی، اشاره گرها، آرایه ها، پارامترهای تابع و توابع عملگر & : این عملگر دارای یک عملوند است و آدرس عملوند خود که نام یک متغیر است را مشخص می نماید .

آموزش برنامه نویسی، اشاره گرها، آرایه ها، پارامترهای تابع و توابع عملگر * : این عملگر هم دارای یک عملوند است و محتویات (مقادیر) جایی که عملوندش (نام اشاره گر) به آنجا اشاره می کند را مشخص می کند .

int *pointer, x, y;  // define three variables whit int type
x = 9;                // equal x to 9
pointer = &x;  // pointer contains Address of x
y = *pointer  // y equal the contains of content address of pointer 

در کد C++ بالا در خط اول 3 متغیر از نوع int که یکی از آنها یک اشاره گر است تعریف شده اند. خط دوم مقدار 9 را در متغیر x قرار می دهد. متغیر x با مقدار 9 در جایی از حافظه ذخیره شده است که خط سوم آدرس آن محل را در متغیر اشاره گر pointer قرار می دهد یعنی pointer به جایی اشاره می کند که متغیری بنام x و از نوع int که مقداری برابر 9 را دارد اشاره می کند. در آخرین خط محتویات جایی که آدرس آن در اشاره گر pointer ذخیره شده است در متغیر y قرار می گیرد یعنی مقدار 9 .

آموزش برنامه نویسی، اشاره گرها، آرایه ها، پارامترهای تابع و توابع

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
#include <iostream.h>
#include <conio.h>

void main()
{
    int firstValue, secondValue;
    int *myPointer;

    myponter = &firstValue;
    *myponter = 10;       // firstValue = *myponter = 10
    myponter = &secondValue;
    *myponter = 20;       // secondValue = *myponter = 20
    cout << "The firstValue is " << firstValue;
    cout << "nThe secondValue is " << secondValue;

    getch();
}
The firstValue is 10
The secondValue is 20

در خطوط 6 و7 برنامه C++ بالا سه متغیر که 2 متغیر معمولی از نوع int تعریف شده است و یک متغیر pointer. دستور خط 9 آدرس متغیر firstValue را در اشاره گر قرار می دهد. در خط بعد محتویات جایی که اشاره گر به آنجا اشاره می کند را برابر با مقدار 10 در نظر می گیریم. چون جایی که متغیر myPointer به آنجا اشاره می کند آدرس متغیر firstvalue است پس مقدار 10 در آنجا و در واقع در متغیر firstValue ریخته خواهد شد و به همین ترتیب برای متغیر secondValue .

عملیات روی اشاره گرها

کلا 3 نوع عمل را می شود بر روی pointer انجام داد :

  • 1. انتساب اشاره گر ها به همدیگر
  • 2. اعمال محاسباتی جمع و تفریق
  • 3. مقایسه
  • انتساب اشاره گرها به همدیگر :

وقتی دو اشاره گر (pointer) را برابر با یکدیگر قرار دهیم با 2 حالت مواجه خواهیم شد، یکی آدرس و دیگری مقدار است. به کد زیر دقت نمایید :


1
2
3
4
5
6
7
8
9
 
int *p1, *p2, *p3, a, b, c;
a = 50;
b = 100;
c = 200;
p1 = &a;  // p1 = Address a and *p1 = 50 and assume that &p1 = 10000
p2 = &b;  // p2 = Address b and *p2 = 100 and assume that &p2 = 10020
p3 = &c;  // p3 = Address c and *p3 = 200 and assume that &p3 = 10040
*p1 = *p2;   // *p1 = *p2 = 100 and &p1 = 10000 and &p2 = 10020
p1 = p3;   // &p1 = &p3 = 10040 and *p1 = *p3 = 200

در کد بالا و در خط 5 اشاره گر p1 به جایی که متغیر a در حافظه ذخیره شده اشاره می کند بنابراین *p1 برابر با مقدار آن آدرس یعنی 50 خواهد شد. در دستور خط بعدی آدرس جایی که متغیر b در آنجا ذخیره شده درون اشاره گر p2 قرار می گیرد یعنی به آن آدرس اشاره می کند و چون محتویات آن آدرس برابر با 100 است پس مقدار *p2 برابر با 100 می شود. در سطر 8 با نوشتن این دستور فقط محتویات جایی که p1 به آنجا اشاره می کند درون درون جایی که p2 به آنجا اشاره می کند ریخته می شود و آدرس دو اشاره گر تغییر نخواهد کرد. اما در سطر 9 آدرس جایی که p3 به آنجا اشاره می کند در اشاره گر p1 قرار می گیرد، بنابراین جایی که p1 به آنجا اشاره می کرد برابر با جایی می شود که p3 اشاره می کند که به ازاء این تغییر بنابراین محتویات جایی که p1 به آنجا اشاره می کرد به مقدار 200 تغییر می کند. OK?

  • اعمال جمع و تفریق :
آموزش برنامه نویسی، اشاره گرها، آرایه ها، پارامترهای تابع و توابع

وقتی اشاره گری را افزایش یا کاهش می دهیم در واقع اینکار را با آدرسها انجام خواهیم داد و متناسب با طول آن متغیر کم یا زیاد می کنیم. در شکل بالا p متغیری از نوع int است پس با هر واحد افزایش، pointer 2 خانه یعنی 2 بایت در حافظه پیش خواهد رفت و متغیر char از نوع char در نظر گرفته شده که با هر واحد افزایش یا کاهش فقط یک خانه کم یا زیاد می شود .

  • مقایسه اشاره گرها :

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


1
2
3
4
5
6
7
8
 
int *p1, *p2, char1, char2;
char1 = char2 = 'Q';
p1 = &char1;
p2 = &char2;
if( p1 == p2 )
    ...
else
    ...

در کد C++ بالا چون اشاره گرها هر یک به آدرسهای مختلفی اشاره می کنند هر چند مقادیر آن آدرسها یکی است اما با هم برابر نیستند .

اشاره گر ها به عنوان آرگومان های توابع :

همچنان که پیشتر در فصل توابع در مورد آرگومان های توابع بحث شد می توان از اشاره گر ها بعنوان آرگومان تابع استفاده نمود. در کد زیر از تکنیک inline function بهره می گیریم :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
#include <iostream.h>
#include <conio.h>

inline void foo(int &y)
{
    cout << "y=" << y << "n";
    y = 6;
    cout << "y=" << y << "n";
}

void main()
{
    int x = 5;
    cout << "x=" << x << "n";
    foo(x);
    cout << "x=" << x << "n";
    getch();
}
x=5
y=5
y=6
x=6

در کد برنامه نویسی C++ تابعی با نام foo که دارای یک آرگومان از نوع اشاره گر است را تعریف نمودیم. این تابع حاوی آدرس پارامتر ورودی خود است پس یک اشاره گر است. در درون تابع foo ابتدا یک بار مقدار متغیر ورودی که در این تابع نامش y و در تابع main نامش x است راچاپ می کند اما با استفاده از مراجعه به آدرس آن متغیر .

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

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

خوب، در سطر 7 مقدار متغیر به 6 تغییر می کند و در سطر بعدی عدد 6 بعنوان مقدار متغیر جاری درج می گردد. در بازگشت به تابع main چون آرگومان اشاره گر بوده پس تغییرات در آدرس متغیر اعمال شده و با مراجعه کامپایلر به آدرس مورد نظر و چاپ مقدار آن دوباره عدد 6 چاپ می شود در صورتی که اگر آرگومان معمولی بود 5 چاپ می شد یعنی همان مقدار اولیه متغیر در این تابع. فراموش نکنید که برنامه از تابع اصلی آغاز می شود بنابراین در ابتدا مقدار x که 5 است چاپ خواهد شد .

برای درک تفاوت میان روش ارسال پارامتر ها با استفاده از مقادیر یا ارجاع (آدرس) مثالی دیگری را بررسی خواهیم نمود :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
#include <iostream.h>
#include <conio.h>

void pass(int, int *);

void main()
{
    int x = 1, y=1;
    pass(x, &y);
    cout << "x=" << x << "n";
    cout << "y=" << y << "n";
    getch();
}
void pass(int a, int *b)
{
    cout << "x=" << ++a << "n";
    cout << "y=" << ++*b << "n";
}
x=2
y=2
x=1
y=2

با اجرای کد برنامه C++ بالا، کامپایلر در سطر 6 ابتدا وارد تابع main خواهد شد. دو متغیر از نوع int با نامهای x,y تعریف شده که هر کدام دارای مقدار برابر یک هستند. در سطر 8 کامپایلر با فراخوانی تابع pass به سطر 14 می رود. در این تابع دو پارامتر که یکی int و دیگری اشاره گر است را می بیند. ما با اینکار مقدار x را با ارسال پارامتر بروش مقدار و y را با استفاده از ارسال پارامتر بروش ارجاع انجام داده ایم، یعنی مقدار x را و آدرس y را به تابع می فرستیم .

در سطر 16 ابتدا یک واحد به x اضافه شده وسپس چاپ می شود که مقدار 2 را خواهیم داشت .

در سطر 17 ابتدا یک واحد به مقدار جایی که آدرس آن محل به عنوان پارامتر (اشاره گر) به تابع ارسال شده اضافه خواهد شد و بعد 2 چاپ خواهد شد .

با پایان بلوک تابع pass کامپایلر باز به تابع main بازگشته و ادامه دستورات را از سطر 10 از سر می گیرد .

در سطر 10 چون x با مقدار به تابع ارسال شده بود پس مقدار آن در ابن تابع همان 1 است پس اینبار 1 چاپ خواهد شد .

اما در سطر 11 چون با آدرس متغیر y کار کردیم پس مقدار کنونی در این تابع هم دستخوش تغییرات در تابع pass خواهد بود و عدد 2 برای آخرین دستور چاپ می شود و برنامه پایان میابد .

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

اشاره گر ها و آرایه ها :

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

در قطعه برنامه C++ زیر به بررسی ارتباط اشاره گر ها و آرایه ها می پردازیم :


1
2
3
4
5
6
7
 
char array[] = {'c','s','h','a','r','p'};
char *pointer;
pointer = array;            // آرایه و اشاه گر هر دو به یکجا یعنی ابتدای آرایه اشاره می کنند
*pointer = array[0];        // = 'c'
*(pointer+1) = array[1];    // = 's'
pointer[3] = *(array+3);    // = 'a'
*pointer = *array;          // = 'c'

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
 
#include <iostream.h>
#include <conio.h>

void main()
{
    int numbers[5];
    int *p;

    p = numbers;
    *p = 10;
    p++;
    *p = 20;
    p = &numbers[2];
    *p = 30;
    p = numbers+3;
    *p = 40;
    p = numbers;
    *(p+4) = 50;
    for(int n=0 ; n<5 ; n++)
        cout << numbers[5] << ", ";
    getch();
}
10, 20, 30, 40, 50

در قطعه برنامه C++ بالا آرایه ای بنام numbers و یک اشاره گر بنام p تعریف کرده ایم. در سطر 9 اشاره گر را برابر با عنصر اول آرایه قرار می دهیم پس هر دو به یکجا اشاره می کنند. سپس در سطر 10 بجایی که اشاره گر اشاره می کند و برابر با عنصر اول آرایه است مقدار 10 را می دهیم. در سطر بعد اشاره گر را یکواحد افزایش می دهیم که با اینکار به خانه بعدی یا همان عنصر دوم آرایه اشاره می کند و باز مقدار محتوای آن خانه را برابر با 20 قرار می دهیم. در کد بالا سعی شده تا انواع برابری های آرایه و اشاره گر را نشان دهم تا برای شما عزیزان بحث جذابتر و روشنتر گردد. به همین روال ما به اشاره گر مقدار می دهیم و چون اشاره گر و آرایه با هم برابرند پس آرایه نیز با اینکار مقداردهی می شود. سپس با استفاده از یک حلقه تکرار for در سطرهای 19و20 مقادیر آرایه را چاپ می کنیم .

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

اشاره گر به اشاره گر (pointer to pointer) :

آموزش برنامه نویسی، اشاره گرها، آرایه ها، پارامترهای تابع و توابع

در شکل بالا،a متغیری از نوع char است که دارای مقدار z می باشد و b اشاره گری است که شامل آدرس a است و c نیز اشاره گر دیگری است که آدرس b را در بر دارد .

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 
#include <iostream.h>
#include <conio.h>

void main()
{
    char a = 'z';
    char *b, **c;

    b = &a;
    c = &b;

    cout << a << "n"
    cout << *b << "n";
    cout << **c << "n";
    cout << b << "n";
    cout << *c << "n";
    getch();
}
z
z
z
7230
8092

با فرض قرار گیری متغیر های برنامه طبق شکل بالا، مقادیر خروجی برای هر دستور cout طبق خروجی برنامه خواهد بود .

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:30 توسط مهدی مترجمی | | تعداد بازدید : 15

رشته ها (Strings) در برنامه نویسی C++ :

ما در فصول قبل با آرایه ها آشنا شدیم. در برنامه نویسی C++ نوع خاصی برای رشته ها یا همان String وجود ندارد و در این مورد باید از آرایه ای از کاراکترها استفاده کنیم. البته در Visual C++ میشه از فضای نامی std در مورد رشته ها استفاده کرد که کار را راحتتر می کند اما چون ما در Borland برنامه نویسی می کنیم نمی توانیم مستقیما با یک متغیر از نوع string کار کنیم .

قبلا یادگرفتیم که اعداد و کاراکترها را چگونه در آرایه قرار دهیم. برای استفاده از رشته ها باید از آرایه دو بعدی با نوع کاراکتر استفاده کنیم. به این نکته توجه نمایید که در زبان برنامه نویسی C++، رشته ها را بین " " و کاراکترها را بین ' ' قرار خواهیم داد. در زیر به نحوه تعریف یک رشته می پردازیم :

char str[] = "programming";
char s[10] = "computer";
char str1[] = {'C','+','+',''};

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

نکته) در مقداردهی یک String باید بدانیم که انتهای آن آرایه با تهی یا Null مشخص می شود. یعنی در خط اول از کد یالا یک آرایه بوجود خواهد آمد که اولین خانه آن حرف p و دومین خانه آن حرف r و علی آخر که در نهایت یکی مانده به آخرین خانه حرف g و آخرین خانه Null یا  می باشد .

در خط دوم ما Stringی را با طول 10 تعریف و مقداردهی کرده ایم، اما عبارت computer از 7 حرف تشکیل شده و آخرین خانه هم شامل  برای تعیین انتهای String خواهد بود که 2 خانه بلا استفاده باقی خواهد ماند .

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

نکته) در تعریف و مقدار دهی یک String باید طول آرایه را همیشه یک واحد بیشتر از طول مورد نیاز انتخاب نماییم و دلیل آن مشخص نمودن انتهای آرایه با استفاده از کاراکتر تهی () است .

Strings Array in ram

برای خواندن و نوشتن Stringها می توانیم از دستورات ورودی خروجی cin ,cout استفاده کنیم، اما ممکن است در این مورد دچار مشکل شویم و آن مشکل این است که اگر ما نامی را بعنوان یک متغیر رشته ای مثل alireza aria را در نظر بگیریم در میان رشته خود ناگزیر از کاراکتر تهی یا همان استفاده می کنیم که در اینصورت تابع cin آنرا بعنوان انتهای رشته در نظر گرفته و aria را دریافت نمی کند و لذا در ورود این متغیر String با استفاده از دستور cin به مشکل بزرگی بر می خوریم. پس دستور cin کاراکترهای فاصله (Space) و Enter را بعنوان انتهای یک آرایه از کاراکترها در نظر می گیرد .

برای رفع مشکل دریافت متغیری از نوع String، از تابع cin.get() استفاده می کتیم. تابع cin.get() آرایه ای از کاراکترها را می گیرد با این تفاوت که انتهای آرایه یا همان متغیر String را با فشار دادن دکمه Enter مشخص می نماید، پس با استفاده از این تابع مشکل ورود یک نام کامل برطرف می شود .


1
2
3
4
5
6
7
8
9
10
11
12
 
#include <iostream.h>
#include <conio.h>

void main()
{
    char strArray[5][11];
    for(int i=0 ; i<5 ; i++)
    {
        cin.get(strArray[i],10);
    }
    getch();
}

همانطور که در کد C++ با مشاهده می کنید تابع cin.get() دارای دو پارامتر ورودی است. اولین آرگومان شامل نام آرایه یا همان متغیر String است بهمراه اندیس عنصر مورد نظر و دومین آرگومان مربوط به بیشترین طول متغیر است. دقت کنید که این مقدار تخمینی از بیشترین طول ممکن برای یک نام کامل است و ضرورتی ندارد که نامها حتما هم مقدار با عدد مشخص شده باشد .

در کاملترین حالت از بکارگیری تابع cin.get() می توان آرگومان سومی نیز برای آن در نظر گرفت که مشخص کننده کاراکتر پایانی آرایه است، یعنی با نوشتن آرگومان سوم، کاربر برای کامپایلر تعیین می کند که با رسیدن به کدام کاراکتر انتهای آرایه یا همان String را مشخص نماید. بعنوان مثال در کد زیر از نقطه بعنوان کاراکتر پایانی بهره گرفته ایم، مشخص کرده ایم که فقط 15 کاراکتر اول را در نظر بگیرد. یعنی اگر نام از 15 کاراکتر بیشتر شد از کاراکتر 15 به بعد را در نظر نگیرد و اگر کمتر از 15 شد با فشار دادن دکمه نقطه از کیبرد پایان آنرا مشخص نماید .

char s[21];
cin.get(s,15,'.');

اعمال بر روی رشته ها (Strings) :

  • انتساب رشته ها یا کپی کردن رشته ها در یکدیگر :

اگر دارای دو متغیر از نوع صحیح به نامهای aوb باشیم برای انتساب آنها از عملگر تساوی برای این منظور استفاده می کردیم(a=b;). اما در مبحث string نمی توانیم برای برابری دو رشته از این عملگر استفاده کنیم. برای انتساب یا کپی یا برابر قرار دادن یک رشته با رشته ای دیگر باید از تابعstrcopy(string1,string2) که در فایل سرآیند <string.h> قرار دارد استفاده کنیم.


1
2
3
4
5
6
 
#include <iostream.h>
#include <conio.h>
#include <string.h>  // strcopy بکارگیری فایل سرآیند جهت استفاده از تابع 

char str1[21], str2[21];
strcopy(str1,str2);

با اجرای تابع strcopy هرآنچه که در آرگومان دوم وجود دارد در آرگومان اول کپی خواهد شد، یعنی مقدار str2 در str1 قرار خواهد گرفت .

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

  • مقایسه رشته ها (string) :

برای مقایسه دو متغیر از نوع صحیح یا اعشاری یا کاراکتری از دستور (if(x==y)) استفاده کردیم. در مورد string ما از تابع strcmp() بهره می گیریم. تابعstrcmp() نیز در فایل سرآیند <string.h> قرار دارد .


1
2
3
4
5
6
7
 
#include <iostream.h>
#include <conio.h>
#include <string.h>  // strcmp بکارگیری فایل سرآیند جهت استفاده از تابع 

char str1[11] = "Ali";
char str2[11] = "Alireza";
strcmp(str1,str2);

در صورت برابری دو مقدار، تابع عدد صفر و اگر str1<str2 باشد تابع مقدار منفی برمی گرداند یعنی str1 از str2 کوچکتر است و در حالی که str1>str2تابع مقدار مثبتی را برمی گرداند یعنی اینکه str1 از str2 بزرگتر است .

در کد بالا بنابر توضیحات داده شده، تابع strcmp مقداری منفی را بر میگرداند .

  • الحاق یا اتصال رشته ها (string) :

برای الحاق دو string از تابع strcat() استفاده خواهیم نمود که این تابع هم در فایل سرآیند <string.h> وجود دارد .


1
2
3
4
5
6
7
 
#include <iostream.h>
#include <conio.h>
#include <string.h>  // strcat بکارگیری فایل سرآیند جهت استفاده از تابع 

char str1[15] = "Alireza";
char str2[11] = "Aria";
strcat(str1,str2);  // str1=Alireza Aria

تابع strcat مقدار string دوم را در ادامه string اول قرار می دهد و باید توجه نمود اگر طول str1 از نتیجه نهایی کمتر باشد کاراکترهای باقی مانده در ادامه str1 در حافظه قرار خواهند گرفت و اگر در آنجا متغیرهایی باشند از بین خواهند رفت .

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:29 توسط مهدی مترجمی | | تعداد بازدید : 13

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

آموزش الگوریتم های مرتب سازی حبابی و درجی آرایه ها در برنامه نویسی C++ آموزش الگوریتم های مرتب سازی آرایه ها در برنامه نویسی C++

  • الگوریتم مرتب سازی حبابی (bubble sort) :

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

 A = {7, 3, 9, 1}

 3 7 9 1 ---> 3 7 9 1 ---> 3 7 1 9     Step 1
 3 7 1 9 ---> 3 1 7 9 ---> 3 1 7 9     Step 2
 1 3 7 9 ---> 1 3 7 9 ---> 1 3 7 9     Step 3

همانگونه که ملاحظه کردید در مرحله اول، ابتدا 7 با 3 مقایسه شده و چون 3 از 7 کوچکتر است جایشان عوض می شود. سپس در همان مرحله 7 با 9 مقایسه شده و چون 9 از 7 بزگتر است پس جابجایی صورت نمی گیرد و در انتهای همان مرحله 9 با 1 مقایسه شده و بدلیل کوچکتر بدن 1 از 9 بین آن دو جابجایی صورت می گیرد .

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


1
2
3
4
5
6
7
8
9
10
11
12
13
 
void bubbleSort(int x[], int y)
{
    int i, j, temp;

    for(i=y-1 ; i>0 ; i--)
        for(j=0 ; j<i ; j++)
            if(x[j] > x[j+1])
            {
                temp = x[j];
                x[j] = x[j+1];
                x[j+1] = temp;
            } //end of if
}

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

  • الگوریتم مرتب سازی درجی (insertion sort) :

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

 A = {7, 3, 9, 5, 1}

7 [3] 9 5 1  --->  3 7 [9] 5 1  --->  3 7 9 [5] 1  --->  3 5 7 9 [1]  --->  1 3 5 7 9

کد الگوریتم درجی را با هم می بینیم با این توضیح که عنصری که علامت درج روی آن است (عنصری که برابر با مقدار متغیر i در حلقه تکرار for ) حتما عناصر قبل از آن مرتب هستند اما در الگوریتم حبابی اینچنین نبود لذا بازده زمانی الگوریتم درجی از حبابی بیشتر است، و کارایی برنامه را بالا می برد .


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
void insertSort(int s[], int len)
{
    int i, j, x;

    for(i=1 ; i>len ; i++)
        {
            x = s[i];
            j = i-1;
            while(j>=0 && s[j]>x)
            {
                s[j+1] = s[j]
                j--;
            }
            s[j+1] = x;
        }
}

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

آموزش الگوریتم های جستجوی ترتیبی و دودویی آرایه ها در برنامه نویسی C++ الگوریتم های جستجو در برنامه نویسی C++

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

  • جستجوی ترتیبی در برنامه نویسی C++ :

1
2
3
4
5
6
7
8
 
int lsearch(int arr[], int length, int num)
{
    for(int i=0 ; i<length ; i++)  // Search in arr[]
        if(arr[i] == num)          // Find number 6 in arr[]
            return 1;
        return -1;                 // Do not find number 6 in arr[]
            
}

در تابع lsearch بالا که الگوریتم جستجوی ترتیبی است، ما دارای 3 پارامتر ورودی که شامل آرایه، طول آن و عدد مورد جستجو هستیم. اگر عدد را پیدا کردیم تابع مقدار 1 و در غیر اینصورت مقدار منفی 1 را برمیگرداند که می توانیم در تابع main از نتیجه این تابع استفاده نماییم .

  • الگوریتم جستجوی دودویی در برنامه نویسی C++ :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
int lsearch(int arr[], int length, int num)
{
    int min, low = 0, high = length-1;
    while(low <= high)  // برای اطمینان از وجود بیش از یک عنصر در آرایه
    {    
        mid = (low+high)/2;          // پیدا کردن عنصر وسط آرایه
        if(num < arr[mid])   // جستجو در نیمه سمت چپ آرایه
            high = mid-1;
        else if(num > arr[mid])   // جستجو در نیمه سمت راست آرایه
            low = mid +1;
        else return mid;                    // در اینصورت عدد مورد نظر عدد وسط است 
    }
    return -1;          // در اینصورت عدد در آرایه وجود ندارد
}

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

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:28 توسط مهدی مترجمی | | تعداد بازدید : 14

توابع بازگشتی در C++

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

کدی به زبان C++ با استفاده از تابع بازگشتی بنویسید که حاصلضرب دو عدد را با استفاده از حاصلجمع آنها بدست آورد .(برای حل این مثال لازم است بدانید که :)

            a*b=a          ----->     اگر b=1
            a*b=a*(b-1)+a  ----->     اگر b>1                              

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
 
#include <iostream.h>
#include <conio.h>

int product(int, int);      

int main()
{
    int a, b;

    cout << "Enter first number :" ;
    cin >> a;
    cout << "Enter second number :" ;
    cin >> b;
            
    cout << product(a, b);

    getch();
    return 0;
}

int product(int a, int b)       
{
    if(b == 1)
        return a;
    return (a + product(a, b-1));
}

 //////////////////////توضیح\\\\\\\\\\

/* a=4, b=3

1) if(3==1)
 return 4;
return(4+product(4,3-1))

2) if(2==1)
 return 4;
return(4+product(4,2-1))

3) if(1==1)
 return 4;
return(4+product(4,1-1)) */
Enter first number :4
Enter second number :3
12

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

در مورد توابع بازگشتی باید چندین نکته را رعایت کنید :

الف) غیر از اینکه تابع بازگشتی را در تابع main فراخوانی می کنیم باید در درون تعریف خود تابع بازگشتی هم آنرا فراخوانی کنیم.

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

پ) در فراخوانی تابع بازگشتی در خود تابع، یکی از پارامترها باید تغییر نماید حال زیاد شود یا کم یا ... و این بسته به نیاز تابع خواهد بود .

ج) هر تابعی را نمی توان بصورت بازگشتی نوشت مگر اینکه رابطه منطقی و ریاضی در این مورد برای آن پیدا کنیم .

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

مثال سری فیبوناچی را با هم به وسیله توابع بازگشتی در C++ بررسی می کنیم :

می دانیم که برای پیدا کردن فاکتوریل یک عدد باید خود عدد را در عدد قبلی ضرب کرده و حاصل آنرا هم به همین ترتیب در عدد قبلی ضرب و به همین ترتیب ادامه دهیم تا به 1 برسیم. لذا وقتی ضرب اعداد در هم ادامه پیدا می کند که به عد 1 برسیم و این شرط ما خواهد بود وهمینطور می دانیم که فاکتوریل 1 برابر با 1 است .

           5! = 5*4*3*2*1 = 120  
           n! = n*(n-1)*(n-2)*... تا زمانیکه n>1 باشد                            

برنامه سری فیبوناچی با توابع بازگشتی :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
 
#include <iostream.h>
#include <conio.h>

long factorial(int);      

int main()
{
    long number;

    cout << "Please type a number :" ;
    cin >> number;
            
    getch();
    return 0;
}

long factorial(int a)       
{
    if(a > 1)
        return ( a*factorial(a-1) );
    else
        return (1);
}
Please type a number :9
9! = 362880                         

خدمت عزیزان باید عرض کنم که در کد بالا نوعی را به نام long می بینیم که شامل اعداد صحیح بزرگتر از int می باشد . دلیل استفاده از این نوع این است که int شامل اعداد بین 32767 و -32767 است و چون جواب ما از این محدوده بیشتر است باید از long استفاده کنیم .

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:25 توسط مهدی مترجمی | | تعداد بازدید : 14

آموزش برنامه نویسی C++ تعریف آرایه های یک بعدی و دوبعدی و چندبعدی و عناصر آرایه آرایه ها در C++

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

گاهی وقتها لازم است که یک سری از داده هم نوع را دریافت کرده و بروی آنها عملیات خاصی را مثل مقایسه یا مرتب کردن و ... را انجام دهیم، لذا باید آنها را بگونه ای خاص در کنار یکدیگر قرار دهیم که این مسئله در برنامه نویسی را با استفاده از آرایه ها حل خواهیم کرد .

آرایه مجموعه ای از عناصر هم نوع است. در برنامه نویسی C++ برای تعریف آرایه باید نوع عناصر آنرا مشخص کنیم و آرایه باید حتما دارای نام باشد که از قانون نامگذاری برای متغیرها تبعیت می کند و بعد از نام از [] استفاده می کنیم که درون آن می توان از یک عدد صحیح برای تعیین طول آرایه استفاده نمود .

تعریف آرایه و ساختار آرایه در برنامه نویسی C++

برای دسترسی به عناصر آرایه از اندیس استفاده می کنیم که اولین اندیس هر آرایه ای از عدد صفر شروع می شود .

int  arr[4];

کد برنامه نویسی C++ بالا آرایه ای را با نام arr تعریف می کند که عناصر آن از نوع عدد صحیح هستند و تعداد عناصر آرایه (طول) برابر با 4 است .

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

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

معمولا آرایه ها با توجه به ابعادشان تقسیم بندی می شوند :

  • آرایه های یک بعدی :

آرایه های یک بعدی دارای یک سطر و چند ستون و یا دارای یک ستون و چند سطر هستند و فقط دارای یک اندیس برای دسترسی به عناصرشان می باشند .

  • مقدار دادن به عناصر آرایه ها :

برای مقدار دادن به آرایه ها هم می توان به تمامی عناصر بصورت یکجا مقدار داد که حالت مجموعه در ریاضی را بخود می گیرد و هم بصورت تک به تک. وقتی طول آرایه را مشخص نمی کنیم با مقدار دادن به عناصر، طول آرایه نیز مشخص خواهد شد .

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
intx[5] = { 10, 37, -3, 8023, 0 };//////////// یا \\\\\\

int  x[5];

x[0] = 10;
x[1] = 37;
x[2] = -3;
x[3] = 8023;
x[4] = 0;//////////// یا \\\\\\

int  x[] = { 10, 37, -3, 8023, 0 };

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

برای دسترسی به عناصر آرایه کافی است اندیس آن عنصر از آرایه را در درون [] قید نماییم :

int  x[5] = { 10, 37, -3, 8023, 0 };

x[0] = 10
x[2] = -3

در کد بالا منظور از خط دوم، مقدار اولین عنصر از آرایه و منظور از خط بعدی مقدار سومین عنصر می باشد .

آموزش تعریف و ساختار آرایه و عناصر در برنامه نویسی C++ مثال) برنامه ای به زبان C++ بنویسید که تعداد 5 عدد را از کاربر دریافت کرده و حاصلجمع آنها را در خروجی نمایش دهد :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
#include <iostream.h>
#include <conio.h>

int main()
{
    int num[5];
    int sum = 0, count;

    for(count = 0 ; count < 5 ; count++)
    {
        cout << "Enter number " << count+1 << " :";
        cin >> num[count];

        sum += num[count];
    }
    cout << "nSum of numbers is " << sum;
    getch();
    return 0;
}
Enter number 1 : 1
Enter number 2 : 5
Enter number 3 : 9
Enter number 4 : 0
Enter number 5 : 18

Sum of numbers is 33

در برنامه بالا آرایه ای بنام num با طول 5 تعریف شده که از یک حلقه تکرار for برای مقدار دادن به عناصر آن استفاده می کنیم و در درون حلقه، مقدار هر عنصر از آرایه را با متغیر sum که دارای مقدار اولیه صفر است جمع می کنیم. دقت کنید که حلقه for باید حتما از صفر شروع شود چون اندیس اولین عنصر آرایه صفر است. در نهایت و با خروج از حلقه حاصلجمع عناصر آرایه که در متغیر sum ریخته شده است را چاپ می کنیم .

آموزش برنامه نویسی C++ تعریف آرایه های یک بعدی و دوبعدی و چندبعدی و عناصر آرایه و پارامتر و آرگومان تابع و توابع ارسال آرایه به عنوان پارامتر برای تابع در برنامه نویسی C++

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 
#include <iostream.h>
#include <conio.h>

int minFunction(int[], int);  //------------------> اعلان تابع با پارامترهای نام آرایه و طول آن

void main()
{
    const int k=4;
    int array[k];

    cout << "nMinimum of array elements is " << minFunction(array, k);  //------> فراخوانی تابع
    getch();
}

int mainFunction(int arr[], int length)  //------> تعریف تابع با تمامی متعلقات
{
    for(count = 0 ; count < length ; count++)
    {
        cout << "Enter number [" << count+1 << "] :";
        cin >> arr[cout]
    }

    int minNum = arr[0];

    for(count = 1 ; count < length ; count++)
    {
        if (arr[count] < minNum)
            minNum = arr[cout]
    }

    return minNum;
}
Enter number 1 : 12
Enter number 2 : 3
Enter number 3 : 28
Enter number 4 : 109

Minimum of array elements is 3

همانطور که در کد C++ بالا می بینیم، در اعلان توابع باید نوع و نام آرایه به همراه عللامت [] آورده شود تا کامپایلر تشخیص دهد پارامتر ورودی یک تابع است نه عدد صحیح. دومین پارامتر، طول آرایه را به تابع ارسال می کند که اینکار را می توانستیم مستقیما در درون پارامتر اول (آرایه) نیز انجام دهیم .

آموزش برنامه نویسی C++ تعریف آرایه های یک بعدی و دوبعدی و چندبعدی و عناصر آرایه و پارامتر و آرگومان تابع و توابع نکته) می بینیم که در فراخوانی تابع که در دستور cout قرار گرفته است ما فقط نام های پارامترها را قید می کنیم و از بیان نوع و [] اجتناب می کنیم .

در نهایت امر، تابع خود را با تمامی پارامترها و انواع و نامهایشان و ملزومات دیگر تعریف می نماییم .

آموزش برنامه نویسی C++ تعریف آرایه های یک بعدی و دوبعدی و چندبعدی و عناصر آرایه و پارامتر و آرگومان تابع و توابع نکته مهم) هر متغیر جز در درون تابع (حوزه) تعریفی خود قابل دسترسی نیست. بعنوان مثال ما در تابع main در کد بالا آرایه array را تعریف کردیم و در و دیگر نمی توانیم از آن در تابع minFunction استفاده کنیم چون کامپایلر محدوده آنرا فقط در تابع خود می داند. اما در تابع minFunction آرایه دیگری را بنام arr تعریف کرده که از آن استفاده می کنیم. این نکته را بخاطر داشته باشید که ما آرایه array را بعنوان پارامتر به تابع ارسال کردیم، و آرایه arr همان آرایه array است اما با نامی دیگر.

برنامه C++ بالا با استفاده از توابع و ارسال آرایه بعنوان پارامتر تابع، کوچکترین عدد آرایه را به ما نشان می دهد. برای این کار لازم است ابتدا عناصر آرایه را با یک دستور حلقه تکرار for مقدار دهی کنیم و سپس اولین عنصر را برابر با minNum بگیریم. سپس با یک حلقه for دیگر آنرا با دیگر عناصر آرایه مقایسه می کنیم، اگر مقداری کمتر از آن باشد در متغیر minNum ریخته می شود و اگر نباشد پس خود اولین عنصر از همه کوچکتر است. در دستور حلقه تکرار for دوم به این دلیل count را از 1 شروع کردیم چون در بالا عنصر با اندیس صفرم آرایه را به عنوان کوچکترین عنصر در نظر گرفتیم و دیگر احتیاجی نیست آنرا دوباره با خودش مقایسه نماییم. عبارت const که در جلوی متغیر k آمده است به کامپایلر می گوید که مقدار این متغیر ثابت است و در طول برنامه تغییری نمی کند و نوشتن هر دستوری مبنی بر تغییر مقدار آن باعث بروز خطا در برنامه خواهد شد .

  • آرایه چند بعدی Multi-Dimensional Arrays

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

  • مقدار دهی به آرایه های چند بعدی :
char x[3][4] = {{'t', 'b', 'p', 'z'}, // Row 1
                {'m', 'c', 'c', 'q'},  // Row 2
                {'a', 'z', 'd', 'g'}};  // Row 3

x[0][0] = t;
x[1][3] = q;
x[2][1] = z;
x[2][0] = a;
x[2][3] = g;
                                

همانطور که در دستور برنامه نویسی C++ بالا مشخص است به ازای هر سطر (بعد اول) یک مجموعه و در درون آن مجموعه، عناصر ستونها (بعد دوم) را مقدار دهی می کنیم. در دستور تعریف آرایه بالا ما 3 سطر و 4 ستون داریم که به ازای بعد اول یک مجموعه و به ازای بعد دوم 4 عنصر در هر مجموعه را تعریف می کنیم .

آموزش برنامه نویسی C++ تعریف آرایه های یک بعدی و دوبعدی و چندبعدی و عناصر آرایه و پارامتر و آرگومان تابع و توابع نکته) عزیزان توجه کنند که چون آرایه ما از نوع char است بنابراین برای هر عنصر باید از ' ' استفاده نماییم، و می دانیم که اگر string باشد باید هر عنصر و بطور کل هر متغیر از این نوع را در " " قرار دهیم. (این یک قانون است.)

آموزش تعریف و ساختار آرایه و عناصر در برنامه نویسی C++ مثال) برنامه ای با آرایه دو بعدی بنویسید که شماره هر سطر را نوشته و در مقابل آن جمع عناصر آن سطر را هم محاسبه و چاپ نماید :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
 
#include <iostream.h>
#include <conio.h>

void sum(int[][2], int);  //------------------> اعلان تابع با پارامترهای نام آرایه و طول آن

void main()
{
    const int m=3, n=2;
    int matrix[m][n] = {{2,5}, {15,9}, {0,32}};

    sum(matrix, m);
    getch();
}

void sum(int x[][2], int a)
{
    int i, j;
    cout << "Rowtt" << "Sumt";
    cout << "---------------------n";

    for (i=0 ; i<a ; i++)
    {
        int sum = 0;
        for (j=0 ; j<2 ; j++)
            sum += x[i][j];
        cout << i+i << "tt" << sum << "n";
    }
}
Row        Sum
---------------
1           7
2           24
3           32
+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:25 توسط مهدی مترجمی | | تعداد بازدید : 17

 Function | توابع در C++

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

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

برای بکارگیری توابع به سه جزء نیازمندیم: تعریف تابع، اعلان تابع، فراخوانی تابع

  • تعریف تابع :
آموزش تعریف تابع و توابع و پارامترهای و ورودی و نوع توابع در برنامه نویسی C++

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

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

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

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

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

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

void sample ( int x, int y )  
{
    .
    .
    .
}
  • اعلان یا الگوی تابع :

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

#include <iostream.h>
#include <conio.h>

void sample ( int a, int b );  

int main()
{
    .
    .
    .
}

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

  • فراخوانی تابع :

در نهایت باید در درون برنامه خود، تابع را صدا بزنیم که به اینکار فراخوانی توابع گفته می شود .

int main()
{
    sample (a, b);
}                              

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

در شکل زیر شمای کلی تابع در برنامه نویسی را می بینید :

توابع در C++

در کد زیر به بررسی یک مثال ساده از توابع می پردازیم :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
 
#include <iostream.h>
#include <conio.h>

void print(void);      // اعلان تابع

int main()
{
    print();             // فراخوانی تابع
    getch();
    return 0;
}

void print( void )       // تعریف تابع
{
    cout << "This is my first function!" ;
}

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

کد فوق تابعی را با نام print تعریف می کند که بدون خروجی و ورودی است که در بالای برنامه هم به همین ترتیب اعلان شده است و در فراخوانی آن، چون نوعی ندارد ما آنها را خالی می گذاریم .

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

آموزش تعریف تابع و توابع و پارامترهای و ورودی و نوع توابع در برنامه نویسی C++ مثال) کدی به زبان C++ با استفاده از توابع بنویسید که 2 عدد را در درون تابع main دریافت کند و بعنوان آرگومان به تابعی بفرستد، تابع آنها را با هم جمع کند و نتیجه را به تابع main برگرداند و سپس نتیجه چاپ شود .


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
 
#include <iostream.h>
#include <conio.h>

float sum(float, float);      // = float sum(float num1, float num2);

int main()
{
    float num1, num2 ,numSum;

    cout << "Enter first number :" ;
    cin >> num1;
    cout << "Enter second number :" ;
    cin >> num2;

    numSum = sum(num1, num2);             
    cout << numSum;

    getch();
    return 0;
}

float sum(float f1, float f2)       // float sum(float num1, float num2);
{
    float fSum = f1 + f2;
    return fSum;
}

Comment هایی را که در کد بالا می بینید به این معنی است که می شود اینگونه هم نوشت. همانطور که میبینید در تابع main دو عدد را دریافت می کنیم و در فراخوانی تابع آنها را بعنوان آرگومانهای تابع ذکر می کنیم. چون تابع sum مقداری از نوع float را برمی گرداند لازم است که تابع را برابر با همان مقدار برگشتی قرار دهیم تا حاصل جمع اعداد در numSum ذخیره کنیم . اولین comment به این معنی است که می شود در اعلان یک تابع اسم پارامترها را نوشت یا ننوشت اما ذکر انواع ضروری است و دومین comment به این معنی است که نام پارامترها در اعلان و در تعریف توابع هم می تواند یکسان باشد و هم نباشد، نکته مهم نوع و تعداد و ترتیب یکسان آنها می باشد .

در حالت کلی به دو روش می توان پارامترها را به توابع ارسال نمود :

  • ارسال از طریق مقدار Arguments passed by value
  • ارسال از طریق آدرس Arguments passed by reference

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

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
#include <iostream.h>
#include <conio.h>

int sqr(int x);      // ارسال پارامتر از طریق مقدار

int main()
{
    int num = 10;

    cout << "square = " << sqr(num) << "and number = " << num;

    getch();
    return 0;
}

int sqr(int x)       // ارسال پارامتر از طریق مقدار
{
    x = x * x;
    return x;
}
square = 100 and number = 10

همان طور که در برنامه C++ بالا می بینیم پارانتر x از طریق مقدار به تابع sqr ارسال شده، در درون تابع مقدار پارامتر به توان 2 می رسد و به عدد 100 تغییر میابد اما مقدار num در تابع اصلی همان 10 است و تغییری نمی کند .

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

آموزش تعریف تابع و توابع و پارامترهای و ورودی و نوع توابع inline در برنامه نویسی C++ توابع inline در برنامه نویسی C++ :

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

برای رفع این مورد و بهینه سازی کدنویسی می توان از توابع inline در برنامه نویسی استفاده کرد. در واقع کامپایلر در برخورد با این توابع تعریف تابع را در حافظه کپی نمی کند بلکه با فراخوانی تابع در برنامه، کپی از آنرا در خود برنامه قرار می دهد که مورد آدرس دهی از میان خواهد رفت. بهتر است در جایی که تعریف تابع کم است و از تابع بیش از 2 یا 3 بار در طول برنامه استفاده نمی کنیم از این روش بهره بگیریم و بدانیم که inline از کلمات کلیدی در زبان C++ است. به نحوه تعریف یک تابع inline در برنامه نویسی C++ دقت کنید :

inline type name(parameters) ------>  اعلان و تعریف تابع 
{
    ...
}

برنامه زیر را با هم می بینیم :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
#include <iostream.h>
#include <conio.h>

inline int max(int a, int b)      // اعلان و تعریف تابع بصورت یکجا
{
    return a > b ? a : b;
}

int main()
{
    clrscr();

    cout << "maximum of 100 & 101 is : " << max(100, 101);

    getch();
    return 0;
}
maximum of 100 & 101 is : 101                    

در مورد تابع inline این نکته را باید دانست که تعریف تابع، در درون اعلان همان تابع انجام می شود .

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

آموزش تعریف تابع و توابع و پارامترهای و ورودی و نوع توابع inline وسربارگذاری تواع در برنامه نویسی C++ حوزه (ناحیه) تعریف و کار با متغیر ها در برنامه نویسی C++ :

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

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

طول عمر یک متغیر با اتمام حوزه آن از بین رفته و کامپایلر آن کپی را دور می ریزد. منظور از حوزه متغیر همان تابع یا کلاس جاری است .


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
 
#include <iostream.h>
#include <conio.h>

void scope(int);

void main()
{
    int x = 10;
    cout << "first value of A=" << x << "n";
    scope(x);
    cout << "third value of A=" << x;
    
    getch();
}
void scope(int a)
{
    a++;
    cout << "second value of A=" << a << "n";
}
first value of A=10
second value of A=11
third value of A=10

با اجرای برنامه بالا کامپایلر از سطر 6 برنامه را آغاز می کند. در سطر 8 متغیری از نوع int بنام x را تعریف کردیم پس در حافظه محلی بنام x با مقدار اولیه 10 ذخیره می شود. در سطر 9 و با برخورد کامپایلر با متغیر x کپی از آن ایجاد شده و مقدار آن یعنی 10 چاپ می شود. در سطر 11 کامپایلر به فراخوانی تابع scope می رسد پس ادامه برنامه را در سطر 15 ادامه می دهد. تابع scope دارای پارامتری به نام a است که همان متغیر x در تابع main می باشد چون در فراخوانی تابع scop ما x را به تابع ارسال نمودیم و فقط نامش در اینجا تغییر کرده است. تابع scope در اینجا فقط a را می شناسد و اگر از x استفاده کنیم انرا نمی شناسد پس اعلام خطا می کند مگر اینکه متغیر جدیدی را بنام x در این تابع تعریف کنیم که متغیر جدیدی است و هیچ ربطی به x در تابع main ندارد .

در سطر 17 یک واحد به a اضافه می شود و چون a همان x در main است کامپایلر یک کپی از مقدار آن گرفته و یک واحد به آن اضافه می کند و عدد 11 را چاپ می کند و با پایان تابع و برگشت کامپایلر به تابع main کامپایلر آن کپی را دور می ریزد در حالی که کپی را یک واحد افزایش داده بود و برای متغیر a .

کامپایلر اینبار برنامه را از سطر 11 ادامه می دهد ولی دیگر آن مقداری را که در تابع scope یعنی a را دور ریخته یعنی عمرش تمام شده و فقط در آن تابع معنی داشت. پس باز به سراغ محل x در حافظه که مقدارش همان 10 است رفته و آنرا چاپ کرده و با پایان برنامه و خروج از تابع main (حوزه x ) کپی آنرا هم دور میریزد و عمر آن متغیر هم تمام می شود و حافظه اختصاص داده شده به آنها آزاد می شود .

آموزش تعریف تابع و توابع و پارامترهای و ورودی و نوع توابع inline وسربارگذاری تواع در برنامه نویسی C++ سربارگذاری توابع در برنامه نویسی C++ (Overloading functions) :

برای درک سربارگذاری توابع کد زیر را می بینیم :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
 
#include <iostream.h>
#include <conio.h>

void func(int a){cout << a << "endl";};
void func(int a, int b){cout << a+b << "endl";};
void func(int a, int b, int c){cout << a+b+c;};

void main()
{
    func(10);
    func(10,10);
    func(10,10,10);
    getch();
}
10
20
30

در بالا می بینیم که سه تابع با نامهای یکسان func را تعریف و صدا زده ایم. درست است که نامها یکسان است اما تعداد آرگومانهای هر تابع با دیگری متفاوت است .

عمل فوق را سربارگذاری توابع گویند یعنی توابعی که دارای نام مشابه هستند ولی در تعداد آرگمانها و ترتیب ورودی آنها با یکدیگر تفاوت دارند. وقتی در تابع main در سطر 11 تابع func صدا زده می شود، کامپایلر با توجه به آرگومانهای آن متوجه می شود که از کدام یک از سربارگذاری تابع استفاده نماید .

عزیزان دقت نمایند که بنده بخاطر صرفه جویی در فضا، بدنه توابع را در اعلان تابع قرار داده ام که این هم سبکی از برنامه نویسی C++ می باشد و شما می توانید مانند قبل تعریف توابع را جداگانه بیان کنید .

آموزش تعریف تابع و توابع و پارامترهای و ورودی و نوع توابع inline و سربارگذاری تواع در برنامه نویسی C++ مقدار دهی اولیه آرگومان های توابع (Initialization functions) :

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


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
 
#include <iostream.h>
#include <conio.h>

int initializefunction(int num = 50);
// int initializefunction(int=50);

void main()
{
    cout  << "Initialize value is : " << initializefunction();
    cout  << "Passed value is : " << initializefunction(100);
    getch();
}

int initializefunction(int x)
{
    return x;
}
Initialize value is : 50
Passed value is : 100

خوب همانطور که ملاحظه می کنید تابعی را بنام initializefunction که دارای یک آرگومان از نوع int است ومقداری از نوع int را هم برمی گرداند را در سطر 4 از برنامه بالا اعلان کردیم. به آرگومان تابع دقت نمایید که مقدار اولیه 50 را دریافت می کند. این عمل باعث می شود اگر در فراخوانی تابع مقداری به آن ارسال نشود از همین مقدار 50 بعنوان مقدار پیش فرض استفاده نماید مانند سطر 9 واگر هم مقداری برایش ارسال شد، مقدار پیش فرض را در نظر نگرفته و مقدار ارسالی را لحاظ می کند مانند سطر 10 .

در سطر 5 از برنامه هم روش تعریفی دیگری را مشاهده می کنید که بصورت توضیح آمده است. از هر دو صورت می توان استفاده نمود

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:24 توسط مهدی مترجمی | | تعداد بازدید : 12

ساختارهای تصمیم در برنامه نویسی C++

در برنامه هرگاه بخواهیم در شرایط ویژه ای برخی از دستورات اجرا شوند و برخی دیگر اجرا نشوند از ساختارهای تصمیم استفاده می کنیم.

  • ساختار if :

با استفاده از ساختار if، شرطی را کنترل می کنیم. اگر شرط جلوی if درست باشد دستورات آن اجرا خواهد شد، در غیر اینصورت دستورات درون else اجرا خواهند شد .

توجه کنید که فقط و فقط یا دستورات if اجرا می شود و یا دستورات else و هرگز این دو با هم اجرا نمی شوند.

if ( عبارت شرطی )  
{
    Line Command 1;
    Line Command 2;
    Line Command n;
}

در ادامه به بررسی حالات مختلفی در بکارگیری دستور if در C++ می پردازیم :


1
2
3
4
 
int num = 5;

if ( num == 10 )  
    cout << "num is equal 10" ;

در کد برنامه نویسی بالا می بینیم که num برابر 5 است، بنابراین شرط if نادرست است و دستور مربوط به آن چاپ نمی شود.


1
2
3
4
5
6
7
 
int num = 10;

if ( num == 10 ) 
{ 
    cout << "num is :" ;
    cout << num ;
}
num is :10                                  
                                    

در کد برنامه نویسی بالا چون دستورات مربوط به if از یک سطر بیشتر است آنها را در بلوک آکولاد قرار دادیم. می بینیم که این بار مقدار num برابر با شرط است، در نتیجه دستورات مربوط به if اجرا می شوند.

نکته مهم اینجاست که برای بررسی تساوی از == استفاده کردیم و دلیل آن این است که این عملگر یک عملگر رابطه ای است و در بررسی شروط باید از عملگرهای رابطه ای استفاده کنیم .


1
2
3
4
5
6
7
8
9
10
11
12
 
int num = 5;

if ( num == 10 ) 
{ 
    cout << "num is :" ;
    cout << num ;
}
else
{
    cout << "num is not 10 % is :" ;
    cout << num ;
}
num is not 10 and is :5                                 

در کد برنامه نویسی بالا چون num برابر با 10 نیست پس دستورات درون else اجرا می شود .

مطالب قبلی دربرگیرنده 2 حالت از بررسی شرط if بودند، اما گاهی اوقات لازم است که ما حالات بیشتری را بررسی نماییم که در اینصورت از else if بهره می گیریم .


1
2
3
4
5
6
 
if ( num > 0 ) 
    cout << "num is positive ";
else if ( num < 0)
    cout << "num is negative ";
else
    cout << "num is 0 ";


  • ساختار switch :

از این ساختار زمانی استفاده می شود که تعداد حالات تصمیم گیری زیاد باشد و همان عملکرد else if را دارد با این تفاوت که کار با آن راحتتر است، به ساختار زیر توجه کنید :

switch ( عبارت شرطی )  
{
    case  مقدار 1 :
         command block 1;
         break;

    case  مقدار 2 :
         command block 2;
         break;
         .
         .
         .
    default
        command block n

}

به بررسی مثالی در C++ می پردازیم :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
int x = 2 ;

switch ( x )  
{
    case 1:
         cout << X is : "One" ;
         break;

    case 2:
         cout << X is : "Two" ;
         break;
         
    default :
        cout << X is : "is not One or Two" ;
}
X is : Two                              

در کد برنامه نویسی بالا متغیر x از نوع عدد صحیح تعریف شده است و مقدار اولیه 2 گرفته است. می خواهیم اگر 1 یا 2 باشد مقدار حروفی عدد را در خروجی نمایش دهیم و در غیر اینصورت خروجی نشان دهد که x نه 1 است نه 2 .

برای این منظور متغیر x را در جلوی switch میاوریم تا به برنامه بگوییم که قصد بررسی x را داریم، سپس در مقابل هر case مقادیر مورد انتظار خود را می نویسیم. در نهایت متغیر در یکی از case ها قرار می گیرد و دستورات مربوط به آن اجرا می شود و با رسیدن به عبارت break برنامه از switch خارج می شود .

عبارت default مواردی که خارج از موارد مورد انتظار ماست را در بر می گیرد و همان کار else در if را انجام خواهد داد .


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
 
int garde = 15 ;

switch ( grade )  
{
    case 20:
    case 19:
        cout << "A" ;
    break;

    case 18:
    case 17:
         cout << "B" ;
    break;

    case 16:
    case 15:
    case 14:
         cout << "C" ;
    break;

    case 13:
    case 12:
    case 11:
    case 10:
         cout << "D" ;
    break;

    default :
        cout << "Reprobate " ;
}
 C

کد برنامه نویسی بالا معدل دانش آموزی را گرفته و با توجه به معدل به او رتبه می دهد. توجه کنید که بعضی از case های موجود خالی از دستورند و علت آن اینست که دستورات برای تمامی آنها مشترک است، مثلا اگر معدل 20 یا 19 باشد رتبه دانش آموزش A خواهد بود و به همین ترتیب تا آخر .

با توجه به اینکه معدل دانش آموز در این مثال 15 است پس به او رتبه C نسبت داده شده و در خروجی چاپ می شود .

  • عملگر ؟

در برنامه نویسی C++ ساختار تصمیم دیگری وجود دارد که به صورت زیر نوشته می شود :

variable = ( condition ) ? true : false;

1
2
 
int X = 10;
int Y = (X < 9) ? 100 : 200;

منظور از دستور بالا اینست که اگر X کوچکتر از 9 است Y را برابر با 100 بگیر، در غیر اینصورت آنرا برابر 200 قرار بده. در واقع ساختار تصمیم عملگر ؟ برابر با ساختار تصمیم if else است .


1
2
3
4
5
6
 
int X = 10;

if (X < 9)
    int Y = 100;
else
    Y = 200;

پس اگر عبارت قبل از ؟ درست باشد، دستور بعد از آن فقط اجرا شده و اگر شرط نادرست باشد عبارت بعد از : اجرا می شود .

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:21 توسط مهدی مترجمی | | تعداد بازدید : 7

ساختارهای کنترلی - حلقه while

در این فصل از آموزش برنامه نویسی C++ قصد داریم به بررسی ساختار حلقه while() بپردازیم که وظیفه ای شبیه به حلقه for() را برعهده دارد.

while ( عبارت شرطی )  
{
    Line Command 1;
    Line Command 2;
    Line Command n;
}

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


1
2
3
4
5
6
7
8
9
10
11
 
int n;

cout << "Enter the starting number that bigger than zero : " ;
cin >> n ;

while ( n > 0 )  
{
    cout << n << ", " ;
}

cout << "Fire! n" ;
Enter the starting number that bigger than zero : 8
8, 7, 6, 5, 4, 3, 2, 1, Fire!                                   

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

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

شکل دیگری از این دستور وجود دارد که شبیه به while() بوده و به آن حلقه do while گفته می شود، با این تفاوت که اگر شرط درون آن نادرست باشد دستورات درون حلقه حداقل یکبار اجرا می شوند و اگر شرط درست باشد، حلقه تا زمان نادرستی شرط ادامه خواهد یافت و ساختار آن بدینگونه است :

do 
{
    Line Command 1;
    Line Command 2;
    Line Command n;
}
while ( عبارت شرطی )  
{
    Line Command 1;
    Line Command 2;
    Line Command n;
}

در ساختار do while() ابتدا دستورات do اجرا شده و بعد شرط درون while() بررسی می شود و در صورت درستی شرط، اجرای دستورات do ادامه پیدا خواهد کرد.

نکته ) دوستان توجه داشته باشند که اگر دستورات مربوط به for, while, do, … فقط یک دستور باشد نیازی به قرار دادن دستور درون آکولاد نیست و تکرار فقط بر روی تنها سطر دستور ادامه خواهد داشت و تا زمانیکه شرط برقرار باشد فقط و فقط آن سطر تکرار و اجرا می شود و تا زمان پایان به خط بعدی نخواهد رفت اما اگر دستورات بیش از یکی باشد لازم است که آنها را در آکولاد قرار دهیم و این قانون کلی در برنامه نویسی است.


1
2
3
4
5
6
7
8
 
int n;

do
{
    cout << "Enter number (0 to end): " ;
    cin >> n ;
    cout << "You entered: " << n << "n" ;
} while ( n != 0 )
Enter number (0 to end): 1298
You entered: 1298                                
Enter number (0 to end): 35
You entered: 35   
Enter number (0 to end): 0
You entered: 0   

اگر عدد ورودی در کد بالا در ابتدا صفر باشد دستورات یکبار اجرا می شود.

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:20 توسط مهدی مترجمی | | تعداد بازدید : 6

ساختارهای کنترلی و تصمیم for,if,else,if else,while,do while در برنامه نویسی C++ ساختارهای کنترلی در برنامه نویسی C++ (Control Structures)

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

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

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

  • ساختارهای کنترل
  • ساختارهای تصمیم

ساختارهای کنترلی و تصمیم و حلقه تکرار تو در تو for,if,else,if else,while,do while در برنامه نویسی C++ ساختارهای کنترل :

  • for
  • while

در برنامه نویسی C++ از ساختار حلقه for برای تکرار یک سری از دستورات استفاده می شود و شکل کلی ایجاد حلقه تکرار بصورت زیر است :

for( مقدار اولیه حلقه ; شرط حلقه ; گام حرکت )
{
    Line Command 1;
    Line Command 2;
    Line Command n;
}
آموزش دستور و ساختار حلقه های تکرار تو در تو for در برنامه نویسی C++

مثال) با استفاده از حلقه تکرار for کدی بنویسید که اعداد 1 تا 10 را چاپ کند.


1
2
3
4
 
for ( int i = 1; i <= 10; i++ )
{
    cout << i << " ";
}
1 2 3 4 5 6 7 8 9 10                                   

در کد بالا متغیر i از نوع int تعریف شده و شرط خاتمه حلقه for تا زمانی است که i کوچکتر یا مساوی 10 باشد. گام حرکت حلقه یک است و با هر بار تکرار حلقه یک واحد به متغیر اضافه خواهد شد. متغیر i در پایان حلقه و با خروج از آن یک واحد اضافه خواهد شد. زمانیکه i برابر با 11 می شود برنامه با رسیدن به شرط حلقه و عدم برقرار بودن شرط، از حلقه خارج می شود. برای چاپ اعداد باید در درون خود حلقه، دستور خروجی را نوشت.

در برنامه نویسی، برای تست دستورات روشی به نام Trace وجود دارد که در این مورد از دستورات بسیار مفید است:

عملیات i<=10 i
چاپ 1 yes 1
چاپ 2 yes 2
چاپ 3 yes 3
چاپ 4 yes 4
چاپ 5 yes 5
چاپ 6 yes 6
چاپ 7 yes 7
چاپ 8 yes 8
چاپ 9 yes 9
چاپ 10 yes 10
خروج از حلقه no 11

شما با ترسیم چنین جدولی بر روی کاغذ و ردگیری گام به گام حلقه قادر به نوشتن حلقه های پیچیده تر در C++ خواهید بود، با کمی تمرین به راحتی به این مهم خواهید رسید.

آموزش دستور حلقه تکرار و پیچیده و تو در تو for در C++ مثال) با استفاده از حلقه تکرار for کدی بنویسید که در آن کاربر جمله ای را وارد کرده و در انتهای جمله Enter را فشار دهد و برنامه تعداد حروف جمله را نمایش دهد:


1
2
3
4
5
 
int  count;
cout << "Enter a statement with enter in end:" << endl;
for ( count = 0; cin.get()!='r' ; count++ );
cout << "Lenght of statement is: " << count;
getch();
Enter a statement with enter in end:
I like C++ programming!
Lenght of statement is: 23                                 

آموزش و مثال کاربردی حلقه تکرار و تو در تو و پیچیده for در برنامه نویسی C++ در برنامه بالا چند نکته مهم وجود دارد که به بررسی آنها می پردازیم:

الف) به شرط حلقه توجه کنید. تابع cin.get() برای تشخیص ورود Enter بکار می رود. تابع دانه دانه حروف ورودی را بررسی می کند و به محض Enter کردن کاربر از حلقه خارج می شود.

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

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

آموزش دستور و ساختار حلقه های تکرار تو در تو for در برنامه نویسی C++ حلقه های تودرتو

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

معروفترین مثال برنامه نویسی در مورد حلقه های تودرتو، نمایش جدول ضرب اعداد است:


1
2
3
4
5
6
7
8
 
int  i,j;

for ( i = 0; i<=10 ; i++ )
{
    for ( j = 0; j<=10 ; j++ )
        cout <<  i*j  << "t";
    cout << endl;
}
1   2   3   4   5   6   7   8   9   10                          
2   4   6   8   10  12  14  16  18  20
3   6   9   12  15  18  21  24  27  30
4   8   12  16  20  24  28  32  36  40
5   10  15  20  25  30  35  40  45  50
6   12  18  24  30  36  42  48  54  60
7   14  21  28  35  42  49  56  63  70
8   16  24  32  40  48  56  64  72  80
9   18  27  36  45  54  63  72  81  90
10  20  30  40  50  60  70  80  90  100

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

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

سپس برنامه با اجرای دستور بعدی به خط جدید می رود. از حلقه اول 9 بار تکرار دیگر مانده، پس این رویه تکرار شده تا برنامه کامل گردد. در آخر وقتی i برابر با 11 می شود از حلقه بیرونی خارج شده و برنامه به پایان می رسد.

آموزش دستور حلقه تکرار و پیچیده و تو در تو for در C++ مثال مهم) قصد داریم با استفاده از حلقه های تکرار تودرتو شکل زیر را ایجاد نماییم :

*****
****
***
**
*

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


1
2
3
4
5
6
 
for ( int i = 5; i>0 ; i-- )
{
    for ( int j = i; j>0 ; j-- )
        cout << "*";
    cout << "n";
}

با شروع حلقه for اول، برنامه وارد بلوکی می شود که دارای حلقه for دیگری است و دو دستور cout، که اولین دستور مربوط به حلقه درونی است و دومی مربوط به حلقه بیرونی.

متغیر i از 5 شروع شده با هر بار اجرای حلقه یک واحد کاهش میابد. به این دلیل متغیر j را برابر با متغیر i گرفته ایم چون با کاهش i آنهم باید کاهش یابد یعنی در هر بار چرخش حلقه بیرونی (هر سطر ).

در ابتدا i برابر با 5 است و شرط حلقه هم درست است پس وارد دستورات حلقه for بیرونی می شود و به حلقه for درونی برخورد می کند که j برابر با i یعنی 5 است و شرطش هم درست است پس 5 بار ستاره چاپ می کند و با نقیض شدن شرط حلقه (وقتی که j برابر صفر می شود ) از حلقه درونی خارج می شود و ادامه دستورات حلقه for بیرونی را انجام میدهد یعنی یک سطر پایین می رود .

این بار یک واحد از i کم شده و برابر با 4 می شود که باز هم شرط حلقه بیرونی درست است و دستورات آنرا دوباره اجرا می کند. در درون حلقه for درونی j برابر با i یعنی 4 شده و شرطش هم درست است پس اینبار چهار ستاره چاپ می کند و به همان ترتیب قبل دستورات ادامه میابد تا شکل بالا حاصل می شود .

آموزش دستور حلقه تکرار و پیچیده و تو در تو for در C++ مثال) می خواهیم شکل زیر را با استفاده از دستور حلقه تکرار for تودرتو در برنامه نویسی C++ رسم نماییم :

      *
     ***
    *****
   *******
  *********
 ***********
*************
 ***********
  *********
   *******
    *****
     ***
      *

برای رسم این شکل ما ابتدا شکل را به 2 قسمت تقسیم کرده و برای رسم هر قسمت از دستور حلقه تکرار for تودرتو استفاده می کنیم :


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
 
for ( int i = 6; i>0 ; i-- )
{
    for ( int j = i; j>0 ; j-- )
        cout << " ";

    for ( j = i; j<6 ; j++ )
        cout << "*";

    for ( j = i; j<=6 ; j++ )
        cout << "*";

    for ( int j = i; j>0 ; j-- )
        cout << " ";

    cout << "n";
}

for ( i = 6; i>=0 ; i-- )
{
    for ( j = i; j<6 ; j++ )
        cout << " ";

    for ( j = i; j>0 ; j-- )
        cout << "*";

    for ( j = i; j>=0 ; j-- )
        cout << "*";

    for ( int j = i; j<6 ; j-- )
        cout << " ";

     cout << "n";
}

عزیزان اگر کمی دقت کنید و با حوصله کد بالا را بررسی نمایید حتما مطلب را یاد گرفته و با کمی تمرین براحتی می توانند در C++ دستورات حلقه تکرار for تو در توی پیچیده را براحتی حل نمایید .

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:18 توسط مهدی مترجمی | | تعداد بازدید : 7

عبارات محاسباتی و تقدم عملگرها در برنامه نویسی C++ (Precedence of operators) :

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

a = b+10*(9%4);
a = b+10*9%4;                                     

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

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

آموزش عبارات محاسباتی و تقدم و اولویت عملگرها در برنامه نویسی C++ جدول زیر تقدم عملگرها را با اولویت از بالا به پایین به ما نمایش میدهد.

1 ()
2 !  ~  ++  --  sizeof
3 *  /  %
4 +  -
5 <<  >>
6 <  <=  >  >=
7 ==  !=
8 &
9 ^
10 |
11 &&
12 ||
13 ?
14 =  +=  -=  *=  /=  %=
15 ,

همینطور که در جدول بالا مشخص شد بالاترین تقدم عملگرها را پرانتز و پایین ترین تقدم را کاما دارا می باشند.

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

عبارات محاسباتی و تقدم و اولویت عملگرها در C++ برای درک مطلب به بررسی مثالی می پردازیم :

a = 20-3*4+19%(3*(2+1));
20-3*4+19%(3*3)

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

20-3*4+19%9

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

20-12+19%9

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

20-12+1

سپس نوبت به % میرسد.

8+1

اکنون عملگرهای + و – در عبارت باقی می مانند که بدلیل یکسانی تقدم اولین عملگر از چپ یعنی – ابتدا محاسبه می گردد.

9

و در پایان عملگر + محاسبه شده که در نهایت به جواب 9 می رسیم.

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:17 توسط مهدی مترجمی | | تعداد بازدید : 6

Basic input/output - I/O - دستورات ورودی خروجی در برنامه نویسی C++

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


1
2
3
4
5
6
7
8
9
10
11
 
#include <iostream.h>
#include <conio.h>
int main()
{
    int a;            //a=?
    cin >> a;         //a=value of user input
    cout << "a:";     //Prints a: on screen
    cout << a;        //Prints value of a
    getch();    
    return 0;
}
a:120

برای استفاده از کلمات کلیدی cin و cout لازمه که از کتابخانه iostream.h در برنامه خود استفاده کنیم.

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

دستور cin باعث می شود که از کاربر یا برنامه دیگه ای یک مقدار یا متنی را بگیریم . در واقع کامپایلر با رسیدن به این دستور منتظر ورود اطلاعات از طرف کاربر شده تا زمانی که کاربر Enter را فشار بده و مقدار ورودی کاربر را در متغیری که در جلوش اعلان شده بریزه و همونطور که قبلا اشاره شد موجب مقدار دهی به متغیر مربوطه میشود .

آموزش دستورات ورودی خروجی cin,cout,input,output در برنامه نویسی C++ در برنامه بالا تابعی بنام getch() هست که برای استفاده از اون باید از کتابخانه conio.h استفاده کنیم که باعث میشود بعد از اجرای برنامه و رسیدن کامپایلر به این خط، برنامه متوقف شده و منتظر این باشه که کاربر یک کلید از کیبورد را فشار دهد . با این دستور می توانیم خروجی برنامه را ببینیم چون اگر این تابع نباشد در کسری از ثانیه برنامه اجرا و بلافاصله بسته میشود و دیگر ما قادر به دیدن خروجی نخواهیم بود . ( امتحان کنید! )

در مثال بالا فرض بر اینه که کاربر مقدار 120 را وارد کرده است.

گاهی اوقات لازمه که ما چند مقدار را با استفاده از دستور cin به برنامه بدهیم، در اینصورت به ازاء هر مقدار از یک << استفاده می کنیم و همینطور برای دستور cout ازیک >> .

int a, b;            //a=?, b=?
cin >> a >> b;
cout << a << b;                        

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

cout << a << endl;

عبارت endl به کامپایلر پایان خط جاری را نشان می دهد و در صورت وجود خروجی دیگه ای در برنامه، نمایش خروجی را از خط بعدی ادامه میدهد .

cout << a << "n";

عبارت n نیز مثل endl خروجی را به خط بعدی هدایت می کند .


1
2
3
4
5
6
7
8
9
10
11
12
13
 
#include <iostream.h>
#include <conio.h>
int main()
{
    int a, b;                                    //a=?,b=?
    cout << "Please inter value of a:";
    cin >> a;                                    //a=value of user input
    cout << "Please inter value of b:";
    cin >> b;                                    //b=value of user input
    cout << "a:" << a << "n";                   //Prints a:(value of a) on screen and go to next line
    cout << "b:" << b;                           //Prints b:(value of a) on screen
    return 0;
}
Please inter value of a:
Please inter value of b:
a:120
b:87

باید بگم فرض بر این است که مقادیر 120 و 87 توسط کاربر وارد شده است . نکته ای که اینجا قابل توجه است اینه که دستور cin خودش باعث میشود که کامپایلر با گرفتن مقدار بطور خودکار به خط بعدی برود و دیگه اینجا نیازی به قید n یا endl نیست .

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:15 توسط مهدی مترجمی | | تعداد بازدید : 7

 انواع داده ها در C++ :

در C++ شش نوع داده وجود دارد. منظور از داده، متغیری است که در قالب متن یا عدد در طول برنامه مورد استفاده قرار می گیرد.

داده های موجود در C++ عبارتند از :

char, int, float, double, void, bool ,string

 

نوع char برای ذخیره داده های کاراکتری مانند : ‘a’ , ‘z’ , ‘W’ بکار می رود.

از نوع int برای ذخیره اعداد صحیح مانند 128، 5، 4508 استفاده می شود.

نوع float برای ذخیره اعداد اعشاری مثل 12.5، 7805.11 بکار می رود.

نوع double برای اعداد اعشاری بزرگتر از float استفاده می شود.

از boolean برای ذخیره مقادیر منطقی استفاده می شود ( درستی یا نادرستی ).

نوع void هیچ مقداری را نمی گیرد

نوع دیگری از داده وجود دارد که برای استفاده از رشته ها مورد استفاده قرار میگیرد که string گفته میشود اما در برخی از نسخه های کامپایلر زبان برنامه نویسی C++ پشتیبانی نمی شود، لذا مجبور به استفاده از آرایه ای از کاراکترها برای این منظور خواهیم بود .

آموزش تعریف انواع داده ها، عملگرها،  متغیرها و نوع آنها در برنامه نویسی C++ متغیرها

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

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

    ;نام متغیر     نوع متغیر

int  count ;

در قطعه کد بالا می بینیم که هر متغیر باید دارای نام منحصر بفردی باشد که برای نامگذاری متغیر ها باید توجه داشته باشیم که :

  • برای نامگذاری متغیرها از ترکیبی از حروف a تا z یا A تا Z ، ارقام و خط ربط ( _ ) استفاده می شود.
  • اولین کاراکتر نام نباید از ارقام باشد.
  • نام می تواند هر طولی داشته باشد اما فقط 31 کاراکتر ابتدایی استفاده می شوند.
اسامی غیر مجاز             اسامی مجاز
-------------------------------------
  count3                   3count
  count                    .count
  co_unt                   co.unt

آموزش تعریف انواع داده ها، عملگرها،  متغیرها و نوع آنها در برنامه نویسی C++ مقدار دادن به متغیر ها

بعد از تعریف یک متغیر باید مقداری را به آن نسبت دهیم که به یکی از چهار روش زیر می توان اینکار را انجام داد :

  • هنگام تعریف متغیر
int  x = 4;     // initial value = 4
char  char1 = 'a' , char2 = char3 = 'y';    // initial values = 'a' and 'y'
bool  b = true;     // initial value = true                                     
  • بعد از تعریف و با عمل انتساب ( = ).
int  y;
y = 12;     // initial value = 12
  • با استفاده از قالب سازنده.
float float_1 (2);     // initial value = 2                
  • دستورات ورودی که در فصل مربوط به ورودی / خروجی گفته خواهد شد.
float a, b;
cin >> a >> b;

آموزش تعریف انواع داده ها، عملگرها،  متغیرها و نوع آنها در برنامه نویسی C++ ثوابت و عملگرها در C++ - (Constants)

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

برای تعریف ثوابت در c++ دو الگو وجود دارد :

  • 1. با استفاده از دستور #define
#define  <name>  <value>

// For example :
#include <iostream>
#define  P  3.14
int main()
{
    cout >> P;
    return  0 ;
}
3.14

به محل استفاده از این دستور دقت کنید که در کجای برنامه مورد استفاده قرار گرفته است (بعد از فایلهای سرآیند) .

نکته ای که باید در اینجا توجه نمود و در مثال بالا هم مشخص بود این است که در پایان دستور #define از ; (سمی کالن) استفاده نمی کنیم.

  • 2. با استفاده از کلمه کلیدی const :
const  <مقدار> = <نام ثابت>  <نوع داده>;

// For example :
#include <iostream>
int main()
{
    const  float  P = 3.14 ;
    cout >> P;
    return  0 ;
}
3.14

می بینیم که محل این دستور درون خود تابع main هست اما دستور #define در بیرون از تابع main و در بالای برنامه.

آموزش تعریف انواع داده ها، عملگرها،  متغیرها و نوع آنها در برنامه نویسی C++ عملگر ها (Operators)

برای انجام عملیات بر روی داده ها از عملگرها استفاده می کنیم. عملگرها نمادهایی هستند که عملیاتی مانند جمع،ضرب، کوچکتری و از این قبیل را روی داده ها انجام می دهند که عبارتند از :

  • انتساب ( Assignment ) ( = )

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

#include <iostream>
int main()
{
    int a, b ;        // a:?, b:?
    a = 10 ;          // a:10, b:?
    b = 4 ;           // a:10, b:4
    a = b ;           // a:4, b:4
    b = 7 ;           // a:4, b:7
    cout >> "a:" ;
    cout >> a ;
    cout>> "b:" ;
    cout >> b ;
    return  0 ;
}
a:4  b:7

نحوه عملکرد این عملگرد به این شکله که مقدار سمت راست تساوی را در سمت چپ قرار میدهد. آموزش انواع type در زبان برنامه نویسی C++

  • عملگرهای محاسباتی ( Arithmetic Operators ) ( + , - , * , / , % )

پنج عملگر محاسباتی موجود در C++ عبارتند از :

+ جمع
- تفریق
* ضرب
/ تقسیم
% باقیمانده تقسیم

با 4 عملگرد اول آشنا هستید اما آخرین که خوانده می شود ( مـد "با واو تلفظ کنید" ) عملوند سمت چپ را بر عملوند سمت راست تقسیم کرده و باقیمانده آنرا بدست می آورد .

#include <iostream>
int main()
{
   int  a = 11;
   int  b = 3;
   int c = a % b;
   cout >> "c:" ;
   cout >> c ;
   return  0 ;
}
c: 2
  • عملگرهای ترکیبی ( Compund Operators ) ( =+ , =- , =* , =/ )
عبارت برابر است با
a += b a=a+b
a -= b a=a-b
a *= b+1 a=a*(b+1)
a /= b a=a/b

در واقع جواب این نوع از عملگرها برابر حاصل عمل عملگر، بر خود عبارت سمت چپ و عبارت سمت راست تساوی است . علت اینگونه نوشتار هم مختصرنویسی است.

عملگرهای ترکیبی دیگری نیز وجود دارند که در ادامه در موردشان بحث می کنیم مثل : => و =<

#include <iostream>
int main()
{
   int  a ,b = 3;     // a=?, b=3
   a = b;             // a=3, b=3
   a += 2;            // a=a+2=3+2=5
   cout >> a;
   return  0 ;
}
5
  • عملگرهای افزایش کاهش ( Increase , Decrease ) ( ++ , -- )

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

#include <iostream>
int main()
{
   int  a = 2, b = 3;        // a=2, b=3
   a += b++;                 // a+=(b+1) ---> a=a+(b+1) ---> a=2+4=6
   cout >> "a:";
   cout >> a;
   return  0;
}
a:6

اگر عملگر سمت راست یا چپ عملوند خود باشه در هر دو صورت یک واحد به عملوند اضافه می شود . اما تفاوت این دوحالت در عبارات محاسباتی خود را نشان می دهد . عبارات محاسباتی ترکیبی از متغیرها، ثوابت و عملگرها هستند مثل 4*5-5/10 و 6-x/y

int  A , B = 3;        // A=?, B=3
A = ++B;               // A=(++B) ---> A=(B+1) , B=B+1 ---> A=4, B=4                     
                                    
A=4   ,B=4

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

int  A , B = 3;        // A=?, B=3
A = B++;               // A=(B++) ---> A=B, B=B+1 ---> A=3, B=4                     
                                    
A=3   ,B=4

اما در مثال بالا چون افزایش بعد از B قرار دارد اول مقدار B که 3 هست در A ریخته میشود و بعد یک واحد به B اضافه میشود .

  • عملگرهای رابطه ای و تساوی (Relational and equality operators) ( = = , =! , > , < , =< , => )

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

int  a = 10 , b = 7;     //a=10, b=7
(a == b) ;               //a=10 and not equal to b so return false
(a >= b) ;               //a=10 greater than b so return false
(a > b) ;                //a=10 greater than b so return true

عملگرهای دیگه ای هم وجود دارند که در آینده و با برخورد به اونها در موردشون صحبت می کنیم تا مبحث کسل کننده و طولانی نشود .

+ نوشته شده در یکشنبه 12 آبان 1392ساعت 11:13 توسط مهدی مترجمی | | تعداد بازدید : 6
عناوين آخرين مطالب ارسالي
» درس 17
» درس 16
» درس 15
» درس 14
» درس 13
» درس 12
» درس یازده
» درس دهم
» درس نهم
» درس هشتم
صفحات دیگر