מצביע למצביע ב-C++

Mzby Lmzby B C



מאמר זה עוסק במושג מצביע למצביע ב-C++. המצביע למצביע מצביע או מאחסן כתובת של מצביע אחר ומאפשר את המניפולציה של המצביעים עצמם. באמצעות מושג זה, אנו יכולים לשנות בקלות מצביע ממיקום אחר בזיכרון. מצביעים כפולים מועילים בזיכרון המוקצה באופן דינמי או במערכים רב-ממדיים כדי לתפעל את האלמנטים של מערך. נדון במצביע זה לעבודת מצביע ושימוש ב-C++ עם דוגמאות מתאימות.

תרחיש 1:  ייצוג זיכרון של מצביע למצביע

בתרחיש זה, הכרזה על המצביע הכפול דומה להצהרת המצביע עם כוכבית נוספת (*) לפני שם המצביע. נוכל לייצג בקלות את מיקום הזיכרון של מצביע כפול ב-C++. קטע הקוד של המצביע למצביע ניתן בקטע הבא:







#include
שימוש במרחב שמות std;
int main ( )
{
int digit  = חמישים ;
int * ptrr;
ptrr = & סִפְרָה;
int ** ptrr1;
ptrr1 = & ptrr;
cout << 'כתובת זיכרון המצביע היא: \n ' ;
cout << 'ptrr (מצביע):' << ptrr << ' \n ' ;
cout << '*ptrr1 (מצביע כפול):' <<* ptrr1 << ' \n ' ;
cout << ' הערך המאוחסן במצביע הוא: \n ' ;
cout << '*ptrr = ' <<* ptrr << endl;
cout << '**ptrr1 (מצביע למצביע) = ' <<** ptrr1 << endl;
לַחֲזוֹר 0 ;
}


בפונקציה הראשית, ניקח משתנה שכתובת הזיכרון שלו צריכה להיות מאוחסנת במצביע. כעת, אנו מאתחלים את המשתנה 'ספרה'. לאחר מכן, אנו מכריזים על מצביע 'ptrr' המאחסן את כתובת הזיכרון 'ספרה'. כעת, אנו מכריזים על המצביע הכפול ששמו '**ptrr1' המאחסן את הכתובת של המצביע '*ptrr'. בסוף הקוד, אנו מציגים את הזיכרון והערך של המצביע והמצביע הכפול על מסך המסוף. הפלט של קוד זה מוזכר בהמשך:




כתובת הזיכרון של מצביע 'ptrr' היא '0x6ffe04', והמצביע '*ptrr1' מאחסן גם את כתובת הזיכרון של מצביע 'ptrr'. הערך המאוחסן בתוך המצביע הוא '50'. בעיקרון, הכתובת של המצביע הכפול זהה תמיד לכתובת הזיכרון של המצביע.



תרחיש 2:  מצביע למצביע כפרמטר פונקציה

בתרחיש זה, נלמד כיצד להעביר את המצביע הכפול בכל פונקציה כפרמטר לביצוע הקצאת הזיכרון הזמני בכל משתנה. קטע הקוד של פרמטר הפונקציה עם מצביע כפול מוזכר בהמשך:





#include
void getMemoryAddress ( int ** double_ptr ) {
אתה מזג אוויר = 200 ;
* double_ptr = & טמפ';
}

int main ( ) {
int * ptr_1;
int ** double_ptr;
double_ptr = & ptr_1;
getMemoryAddress ( double_ptr ) ;
std::cout << 'הערך של **double_ptr הוא: ' << ** double_ptr << std::endl;
לַחֲזוֹר 0 ;
}


כאן, נלמד כיצד פועל המושג מצביע למצביע ב-C++. זכור שמצביע אחד מוצהר בתוכנית לעבוד עם מצביע כפול. אז, אנו בונים את הפונקציה 'getMemoryAddress'. אנו מתכננים את הפונקציה הזו כך שכאשר נעביר את הפרמטר, הוא מקבל אוטומטית את כתובת הזיכרון של המצביע הכפול.

בפונקציה, ניקח את המשתנה 'tempp' ואת המצביע הכפול '**double_ptr'. אנו מעבירים את הכתובת של המשתנה שצוין שהוא 'tempp' למצביע הכפול ואת ערכי המצביע הכפול כארגומנט של הפונקציה. התוכנית מציגה את התוצאה של קוד הפונקציה הראשית במסך המסוף, כך שכל הדברים שנמצאים בפונקציה הראשית ניתנים להפעלה. אנחנו לוקחים את המצביע 'ptr_1' ואת המצביע הכפול בתור 'double_ptr' בפונקציה הראשית. אנחנו מעבירים את הכתובת של המצביע למצביע הכפול.



כעת, אנו מעבירים את משתנה המצביע הכפול בפונקציית override ומעבירים את המצביע למשתנה המצביע במשפט הפלט 'cout' כדי להציג את התוצאה של המצביע הכפול.

כאשר המהדר מגיע לפונקציית override, בודק המהדר שבו מוגדרת פונקציה זו מבצע את הקוד בתוך הפונקציה ומחזיר את התוצאה לפונקציה הראשית.

הפלט של קוד זה מצורף בקטע הבא:


תוצאה: הערך של המצביע הכפול הוא 200.

תרחיש 3:  שימוש במערך הדו-ממדי עם מצביע למצביע

בדוגמה זו, נעסוק במערך דו מימדי בעל מצביע כפול. אנחנו לוקחים מערך ומעבירים את הכתובת של מערך במצביע. הקוד המלא של תרחיש זה מסופק כדלקמן:

int main ( ) {
const int rows = 3 ;
const int cols = 2 ;
int ** מטריצה ​​= new int * [ שורות ] ;
ל ( int i = 0 ; אני < שורות; ++i ) {
מַטרִיצָה [ אני ] = חדש int [ קולס ] ;
}
ל ( int i = 0 ; אני < שורות; ++i ) {
ל ( int j = 0 ; י < קולס; ++j ) {
מַטרִיצָה [ אני ] [ י ] = אני * cols + j;
}
}
ל ( int i = 0 ; אני < שורות; ++i ) {
ל ( int j = 0 ; י < קולס; ++j ) {
cout << מַטרִיצָה [ אני ] [ י ] << '' ;
}
cout << endl;
}
ל ( int i = 0 ; אני < שורות; ++i ) {
לִמְחוֹק [ ] מַטרִיצָה [ אני ] ;
}
לִמְחוֹק [ ] מַטרִיצָה;
לַחֲזוֹר 0 ;
}


כפי שכולנו יודעים, יש לנו הרבה שורות ומספר עמודות במערך דו מימדי. בפונקציה הראשית, אנו מאתחלים את השורות והעמודות שיש להן 'const int'. לאחר מכן, אנו מקצים את שטח הזיכרון עבור השורות ואת שטח הזיכרון עבור העמודות לאורך כל שורה. אנו מעבירים את ערך מספר השורות כמצביע במצביע הכפול של המטריצה ​​בתור '** מטריצה'. במצביע כפול זה, הלולאה של מספר השורות מבוצעת או אמת. לאחר מכן, לולאה פנימית נוספת מבוצעת עד שהתנאי הופך לא נכון.

לאחר הקצאת הזיכרון, אנו מקצים שוב ערך במערך: לולאה חיצונית עבור השורות ולולאה פנימית עבור העמודות של המערך הדו-ממדי. בלולאה הפנימית, ערך השורות והעמודות מוקצה למצביע הכפול ומבצע פעולה אריתמטית נדרשת. אנו מציגים את הערכים של מערך דו מימדי כמו מספר השורות והעמודות שהוקצו בזיכרון. מספר השורות והעמודות מצביע תמיד על המצביע הכפול המאחסן את ערכי השורות והעמודות. בסופו של דבר, אנו מנקים את הזיכרון ומקצים את המערך הזה מהזיכרון ב-C++.

הפלט של מערך 2D עם מצביע כפול מצורף בקטע הבא:

תרחיש 4:  החלפת המצביעים באמצעות מצביע למצביע

כאן, נלמד כיצד להחליף את המצביעים ב-C++ על ידי הכרזה על המצביע הכפול. קטע הקוד של תרחיש זה מצורף בקטע הבא:

#include
החלפת בטל ( int ** ptrr_1, אתה ** ptrr_2 ) {
int * temp_var = * ptrr_1;
* ptrr_1 = * ptrr_2;
* ptrr_2 = temp_var;
}
int main ( ) {
int x = חֲמֵשׁ עֶשׂרֵה , y = 25 ;
int * ptrrA = & איקס, * ptrrB = & ו;
std::cout << 'לפני החלפה: *ptrrA הוא = ' << * ptrrA << ', *ptrrB הוא = ' << * ptrrB << std::endl;
לְהַחלִיף ( & ptrrA, & ptrrB ) ;
std::cout << 'לאחר החלפה: *ptrrA  is = ' << * ptrrA << ', *ptrrB  is= ' << * ptrrB << std::endl;
לַחֲזוֹר 0 ;
}


ראשית, אנו בונים את פונקציית ההחלפה, ומעבירים את שני המצביעים כארגומנט הפונקציה. בפונקציית ההחלפה, אנו לוקחים את מצביע ה-'temp' ומעבירים את הערך של 'pointer1' ב-'temp' למשך זמן מה. לאחר מכן, נעביר את הערך של 'מצביע2' ל'מצביע1'. בסופו של דבר, אנו מעבירים את הערך של מצביע ה-'temp' ל-'pointer2'.

בפונקציה הראשית, אנו זקוקים לשני מצביעים שאנו מעבירים או מחליפים בפונקציית 'החלפה'. אנו מעבירים את הכתובות של משתנים למצביעים הנתונים. לאחר מכן, הערך של המצביע לפני ואחרי החלפת המצביע מוצג.

הפלט של קוד זה מצורף בקטע הבא:


כפי שאנו יכולים לראות, ערכי המצביע מוחלפים בהצלחה באמצעות מצביע כפול ב-C++.

סיכום

הגענו למסקנה שהמצביע למצביע תמיד מאחסן את כתובת הזיכרון של כל מצביע ב-C++. אנו יכולים להשתמש במצביע הכפול כדי להשתמש באופן זמני במיקום הזיכרון של כל מצביע בכל רגע. זוהי דרך יעילה מאוד לתפעל את כתובת הזיכרון בעקיפין ולהתקרב לנתונים.