Code Corona

نسخه‌ي كامل: آموزش اشاره گر ها
شما هم اكنون متن قالب بندي نشده را مي‌بينيد.مشاهده‌ي نسخه‌ي اصلي
اشاره گرها
یکی از مباحثی که برنامه نویسان مبتدی معمولا در آن با مشکل مواجه می شوند مبحث اشاره گر(pointer) میباشد.
در اینجا سعی می کنیم با زبانی ساده به معرفی و نحوه استفاده از اشاره گرها بپردازیم:
تعریف:اشاره گر،متغییری است که آدرسی از حافظه را نگه میدارد.همانطور که میدانید یک متغییر در خود به طور مستقیم یک مقدار را نگه میدارد اما یک اشاره گر به طور غیرمستقیم به یک مقدار اشاره میکند(از طریق آدرس).برای تعریف یک اشاره گر میبایست نوع داده ای که اشاره گر به آن اشاره می کند مشخص شود(مثلا int,double,float,…)البته لزومی ندارد که این انواع داده از انواع داده داخلی زبان باشد بلکه میتواند از انواع تعریف شده توسط برنامه نویس نیز باشد
برای تعریف اشاره گر پس از آوردن نوع داده از عملگر * استفاده میکنیم و سپس نامی برای اشاره گر انتخاب میکنیم.
مثال:
Int * x; اشاره گر از نوع صحیح
توجه کنید که داخل اشاره گر آدرس قرار میگیرد و ما مستقیما در آن آ درس را قرار میدهیم،برای این کار باید از عملگر & استفاده کنیم. با قرار دادن یک متغییر پس از & در واقع ما آدرس متغییر را به دست می آوریم که میتوان آن را مستقیما در متغییر اشاره گر قرار داد.
int x;
int * y=&x;
حال در اشاره گر y آدرس x قرار دارد.
توجه کنید که اگر پس از تعریف اشاره گر می خواستیم آدرسی را در آن قرار دهیم نباید از * استفاده کنیم چرا که پس از تعریف، این عملگر، عمل دیگری (dereferencing یا ارجاء) را انجام میدهد.یعنی با فرض اینکه y یک اشاره گر صحیح باشد و بخواهیم آدرس x را در آن قرار دهیم داریم :
y=&x;
و اما ارجاء :زمانی که بخواهیم از مقداری که اشاره گر به آن اشاره میکند استفاده کنیم باید توسط عملگر *، مقدار را برگردانیم در واقع توسط این عملگر به آدرس موجود در اشاره گر رفته ومقدار موجود در آن آدرس را باز می یابیم .
شکل زیر،شماتیکی برای pointerها نشان میدهد.دایره ای که در داخل فضای حافظه اشاره گر قرار دارد در واقع آدرس خانه حافظه intکه در داخل آن مقدارصحیحی(بیضی داخل شکل) قرار دارد، میباشد که استفاده از عملگر * قبل از اشاره گر، آن مقدار را برمیگرداند.
[تصوير: 4klaz5h.gif]
برای جلوگیری از پیچیدگی توصیه میشود کدهای زیر را اجرا کنید تا به مفهوم اشاره گر تسلط پیدا کنید:
کد:
#include <iostream>

using std::cout;
using std::endl;

int main()
{
   int a;      // a is an integer
   int *aPtr;  // aPtr is a pointer to an integer

   a = 7;
   aPtr = &a;  // aPtr assigned address of a

   cout << "The address of a is " << &a
        << "\nThe value of aPtr is " << aPtr;

   cout << "\n\nThe value of a is " << a
        << "\nThe value of *aPtr is " << *aPtr;

   cout << "\n\nShowing that * and & are inverses of "
        << "each other.\n&*aPtr = " << &*aPtr
        << "\n*&aPtr = " << *&aPtr << endl;

   return 0;  // indicates successful termination

} // end main
دو برنامه زیر در واقع استفاده از pointerدر توابع را نشان میدهد(برنامه اول بدون استفاده از اشاره گر و دومی با استفاده از اشاره گر است) که البته تنها جنبه آ موزشی دارد:
کد:
#include <iostream>

using std::cout;
using std::endl;

int cubeByValue( int );   // prototype

int main()
{
   int number = 5;

   cout << "The original value of number is " << number;

   // pass number by value to cubeByValue
   number = cubeByValue( number );

   cout << "\nThe new value of number is " << number << endl;

   return 0;  // indicates successful termination

} // end main

// calculate and return cube of integer argument
int cubeByValue( int n )
{
   return n * n * n; // cube local variable n and return result

} // end function cubeByValue
کد:
#include <iostream>

using std::cout;
using std::endl;

int cubeByValue( int );   // prototype

int main()
{
   int number = 5;

   cout << "The original value of number is " << number;

   // pass number by value to cubeByValue
   number = cubeByValue( number );

   cout << "\nThe new value of number is " << number << endl;

   return 0;  // indicates successful termination

} // end main

// calculate and return cube of integer argument
int cubeByValue( int n )
{
   return n * n * n; // cube local variable n and return result

} // end function cubeByValue
توجه کنید که در اشاره گرها میتوان از اعمال ریاضی هم استفاده کرد .
فرض کنید در یک اشاره گرint با نام xآدرس حافظه 3002 ذخیره شده حال اگر این اشاره گر را با عددی مثل یک جمع کنیم آنگاه آدرس موجود در اشاره گر با sizeof(int)جمع می شود مثلا با فرض اینکه int به اندازه 4 بایت فضا بگیرد آنگاه مقدار آدرس برابر با 3006(3002+1*4) میشود در واقع ریاضیات اشاره گرها کار با واحدهای حافظه است.برنامه زیر را امتحان کنید:
حالا میتوان نشان داد که عملا آرایه ها با اشاره گرها ارتباط تنگاتنگی دارند و در واقع کار با آرایه کار با اشاره گر هاست.
زمانی که یک آرایه را به تابع ارسال میکنید در واقع آدرس خانه اول آن آ رایه را به تابع پاس می دهید و عملگر []در آرایه ها عمل ارجاء را انجام میدهد
کد:
#include <iostream>

using std::cout;
using std::endl;

int main()
{
   int b[] = { 10, 20, 30, 40 };
   int *bPtr = b;   // set bPtr to point to array b

   // output array b using array subscript notation
   cout << "Array b printed with:\n\n"
        << "Array subscript notation\n";

   for ( int i = 0; i < 4; i++ )
      cout << "b[" << i << "] = " << b[ i ] << '\n';

   // output array b using the array name and
   // pointer/offset notation
   cout << "\nPointer/offset notation where "
        << "the pointer is the array name\n";

   for ( int offset1 = 0; offset1 < 4; offset1++ )
      cout << "*(b + " << offset1 << ") = "
           << *( b + offset1 ) << '\n';

   // output array b using bPtr and array subscript notation
   cout << "\nPointer subscript notation\n";

   for ( int j = 0; j < 4; j++ )
      cout << "bPtr[" << j << "] = " << bPtr[ j ] << '\n';

   cout << "\nPointer/offset notation\n";

   // output array b using bPtr and pointer/offset notation
   for ( int offset2 = 0; offset2 < 4; offset2++ )
      cout << "*(bPtr + " << offset2 << ") = "
           << *( bPtr + offset2 ) << '\n';

   return 0;  // indicates successful termination

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

// Converting lowercase letters to uppercase letters
// using a non-constant pointer to non-constant data.
#include <iostream>

using std::cout;
using std::endl;

#include <cctype>    // prototypes for islower and toupper

void convertToUppercase( char * );


int main()
{
   char phrase[] = "characters and $32.98";

   cout << "The phrase before conversion is: " << phrase;
   convertToUppercase( phrase );
   cout << "\nThe phrase after conversion is:  "
        << phrase << endl;

   return 0;  // indicates successful termination

} // end main

// convert string to uppercase letters
void convertToUppercase( char *sPtr )
{
   while ( *sPtr != '\0' ) {   // current character is not '\0'

      if ( islower( *sPtr ) )  // if character is lowercase,
         *sPtr = toupper( *sPtr );  // convert to uppercase

      ++sPtr;  // move sPtr to next character in string

   } // end while

} // end function convertToUppercase

// This program puts values into an array, sorts the values into
// ascending order, and prints the resulting array.
#include <iostream>

using std::cout;
using std::endl;

#include <iomanip>

using std::setw;

void bubbleSort( int *, const int );    // prototype
void swap( int * const, int * const );  // prototype

int main()
{
   const int arraySize = 10;
   int a[ arraySize ] = { 2, 6, 4, 8, 10, 12, 89, 68, 45, 37 };

   cout << "Data items in original order\n";

   for ( int i = 0; i < arraySize; i++ )
      cout << setw( 4 ) << a[ i ];

   bubbleSort( a, arraySize );  // sort the array

   cout << "\nData items in ascending order\n";

   for ( int j = 0; j < arraySize; j++ )
      cout << setw( 4 ) << a[ j ];

   cout << endl;

   return 0;  // indicates successful termination

} // end main

// sort an array of integers using bubble sort algorithm
void bubbleSort( int *array, const int size )
{
   // loop to control passes
   for ( int pass = 0; pass < size - 1; pass++ )

      // loop to control comparisons during each pass
      for ( int k = 0; k < size - 1; k++ )

         // swap adjacent elements if they are out of order
         if ( array[ k ] > array[ k + 1 ] )
            swap( &array[ k ], &array[ k + 1 ] );

} // end function bubbleSort

// swap values at memory locations to which
// element1Ptr and element2Ptr point
void swap( int * const element1Ptr, int * const element2Ptr )
{
   int hold = *element1Ptr;
   *element1Ptr = *element2Ptr;
   *element2Ptr = hold;

} // end function swap
در صورت وجود هر گونه اشکال لطفا توسط پست اطلاع دهید.
در صورت رضایت شما و آقا ی نخلبند مباحث پیشرفته تر در مورد pointerها را در هفته های بعد قرار میدهم.باتشکر.
توجه:کدهای استفاده شده از کتاب زیر استخراج شده اند:
c++ how to program
rrm عزیز ممنون خیلی باحال بود.
مطالب ذکر شده خیلی خوب هستند .خسته نباشید
آدرس اصلي