“指針的愛情故事”(指針\多級指針 詳解,常量指針\指針常量\常量指針常量,數組指針\指針數組,函數指針\指針函數)
作者:譚丙章(AlexTan)
E-mail: [email protected]
注:轉載不貼上作者信息以及原文地址,必追究其法律責任
因爲最近要講課的原因,想着怎麼才能讓學弟學妹們把指針理解透,學指針學起來不枯燥。於是自己編寫了 ”指針的愛情故事“。
先聲明:此故事純屬虛構,如有雷同,不勝榮幸!
故事以及講解都在代碼註釋裏,所以就直接上代碼:
#include<iostream>
using namespace std;
/*-------------------------------------------指針的愛情故事---------------------------------------------*/
//講故事前,首先,介紹一下地址的概念 ps:其實地址就是變量的家啦~! 和人類世界不同的是,變量的整個一生都會待在家裏!
void address()
{
int baby; //一個叫baby的int類型的變量出生了,上帝會給他在棧區分配一個家(地址)。這裏的專業名字叫:聲明! 知識拓展一:局部變量的家(存放位置)是在棧區,全局變量和static變量的家(存放位置)在全局數據區。
//我們來看一看baby是在什麼地方出生的!
cout << &baby << endl; //給baby加上“&”(取地址符),就能找到去baby家的路
baby = 1; //經過成長的磨練,baby長大啦!他有了自己的個性,包括價值觀、愛情觀、性格等等(用1來代替)。 這裏的專業名字叫:定義!
//我們來看看baby的性格、價值觀、愛情觀是怎樣的
cout << baby << endl;
}
/*有了地址的概念,那麼我們就開始來講講指針,指針也許是計算機世界裏最癡情的人~,就好像人類世界裏的“了不起的蓋茨比”。*/
//首先是指針變量
void pointer()
{
int *Gatsby; //蓋茨比出生了,同樣,上帝也會給他在棧區分配一個家(地址)。
char baby;
int lover; //同時,另外兩個小孩兒也出生了
//我們來看看蓋茨比的家在哪
cout << &Gatsby << endl;
//蓋茨比小時候,也以爲自己和其他小孩兒(變量)一樣
baby = 'a';
lover = 2;
//*Gatsby = 1;
//cout << *Gatsby << endl;
//一次碰壁後,他才知道他與衆不同!他在人生的道路上不斷地尋找自己,通過他的努力,終於找到了正確的道路
Gatsby = new int(1); //知識拓展二:new int(1)代表從堆中給Int類型的值“1”(可以理解成結果等於1的Int類型變量)分配一個空間
cout << *Gatsby << endl;
//同時,他還有了一個驚奇的發現
cout << Gatsby << endl; //他發現自己可以找到別人的家(地址)。
//於是,他漸漸長大了,看了很多悲劇性的愛情電影,那時他就發誓,自己將來一定要好好對待一個女孩兒!懵懂的愛情在他腦中盪漾~。最開始,他遇到了baby,漸漸喜歡上了她,於是他向她表白了。
//*Gatsby = baby; //我喜歡你。。。一開始就被狠狠地拒絕了,可是,他不是那種輕易放棄的人
//Gatsby = baby; //結果,他直接在全班同學面前出糗了,很尷尬~! 於是他就開始反思,也許是他方法用得不對,於是他又去尋找不同的方法
//*Gatsby = &baby; //還是惹來同學的笑話
//Gatsby = &baby; //一次次地失敗,最終把他打擊得實在是沒有信心了....於是他就想:“也許他們倆根本就不適合!”
//他放棄了baby... 果然,沒過多久,他就遇到了另外一個女孩兒,並且是一見鍾情!他有了上一次的經驗,一下就找準了方法
*Gatsby = lover; //我喜歡你... 批註:這裏只是給指針賦值,把lover的值賦給指針,並沒有讓指針指向lover
cout << &lover << endl;
cout << Gatsby << endl;
cout << *Gatsby << endl;
Gatsby = &lover; //漸漸的...我喜歡你,變成了我愛你...蓋茨比把lover的家,lover的個性都深深地烙印在了自己的心底。 批註:指針指向lover。
cout << &lover << endl; //lover的家
cout << Gatsby << endl; //lover的家
cout << *Gatsby << endl; //lover的個性
lover = 3; //即使lover的個性或者是外貌改變了,蓋茨比也始終愛着她
cout << *Gatsby << " " << lover << endl;
*Gatsby = 4; //lover或許是因爲蓋茨比的愛而感動,或許是因爲其他,lover也愛上了蓋茨比
//他們形影不離,你變我也跟着變,彼此都住在對方的心底
cout << *Gatsby << " " << lover << endl;
}
//儘管蓋茨比他們彼此已經非常非常相愛了,但是,現實最終打敗了他們,不過,蓋茨比卻得到了昇華~
void multipointer()
{
int lover = 2;
int *Gatsbyago=&lover; //以前的蓋茨比只是純粹的愛上lover。知識拓展三:聲明這裏初始化可以這樣寫,其他地方必須得這樣寫:Gatsbyago=&lover,代表Gatsbyago指針指向lover。
//知識拓展四:如果指針未被初始化(未指向一個地址),那麼也不能進行*Gatsbyago = 3 之類的操作,指針本身的地址只能指向一個地址,不能存放普通值。
int family=3;
int *lovers = &family; //lovers愛自己的家人
int **Gatsbynow; //如今的蓋茨比
cout << &lovers << " " << &family << " " << lovers << " " << &Gatsbynow << endl;
Gatsbynow = &lovers;
cout << **Gatsbynow << " " << *Gatsbynow << " " << Gatsbynow << " " << &Gatsbynow << endl;
//如果family改變,其他所有人都跟着改變
family = 4;
cout << family << " " << *lovers << " " << **Gatsbynow << endl;
//如今的蓋茨比,不僅愛着lovers,他還愛着他愛人所愛的所有人。正所謂:愛屋及烏...
/*-----------------------------END------------------------------*/
//*Gatsbynow = &lover; //知識拓展五:清楚二級指針 **xxx(二級指針所指向的“一級指針指向的地址的值”),*xxx(一級指針所指向的地址),xxx(一級指針的地址)代表什麼後,可以進行篡改操作,這樣的篡改同時會把lovers一級指針所指向的地址改變(即,蓋茨比的愛人愛的人變了,他所愛的人同樣跟着變)
//cout << family << " " << *lovers << " " << **Gatsbynow << endl;
//多級指針同理
}
/*------------------------常量指針、指針常量、常量指針常量------------------------*/
void ConstPointer()
{
const int a = 1; //常量變量
//a = 2; //非法操作:常量不能被改變
int b = 2;
int c = 3;
const int *pointer = &a; //常量指針,是一個指針,即可以理解爲指向常量的指針,常量的值不能變,指針指向的地址可以變
//*pointer = 4; //非法操作
//pointer = &b; //合法操作
int const *pointer2 = &b; //常量指針的另外一種聲明方式
//*pointer2 = 4; //非法操作
//pointer2 = &c; //合法操作
int *const pointer3 = &c; //指針常量,是一個常量,即可以理解爲指針是常量,指針指向的地址的值可以變,指針指向的地址不可以變,
//*pointer3 = 4; //合法操作
//pointer3 = &b; //非法操作
const int *const pointer4 = &a; //常量指針常量,全都是常量,不管是指針指向的地址,還是值都不能被改變
//*pointer4 = 8; //非法操作
//pointer4 = &b; //非法操作
}
/*------------------------------------數組指針、指針數組---------------------------*/
void ArrayPointer()
{
//顧名思義,數組指針:是一個指針,這個指針是指向數組的指針;指針數組:是一個數組,這個數組是存放指針(地址)的數組
int *a[4]; //指針數組
cout << &a << endl;
int b[4] = { 1, 2, 3, 4 };
//給指針數組賦值
for (int i = 0; i < 4; i++) // int
{
a[i] = &b[i];
}
//輸出:
for (int i = 0; i < 4; i++)
{
cout << *a[i] << " ";
}
cout << endl;
int (*c)[4];//數組指針
c = &b; //數組指針指向b這個數組
//輸出:
for (int i = 0; i < 4; i++)
{
cout << (*c)[i] << " ";
}
}
/*------------------------------指針函數、函數指針-------------------------*/
int *f1(int a, int b) //指針函數
{
int *c;
if (a > b)
{
c = &a;
cout << &a << endl;
return c;
}
else
{
c = &b;
cout << &b << endl;
return c;
}
}
int(*f2)(int a, int b); //聲明函數指針
int max(int a, int b) //普通函數
{
if (a > b)
return a;
else
return b;
}
void FuncPointer()
{
//同樣,顧名思義,指針函數:是一個函數,不過這個函數返回的類型是一個指針;函數指針:即是一個指針,不過這個指針指向的是一個函數
int a = 1, b = 2;
cout << f1(a,b) <<endl; //調用指針函數,輸出的是地址,如果輸出 *f1(a,b) 將輸出值。
f2 = max; //函數指針指向max函數
cout << (*f2)(a, b) << endl; //通過函數指針調用函數
}
/*----------------------------------主函數----------------------------------*/
int main()
{
//address(); //地址
//pointer(); //一級指針
//multipointer(); //多級指針
//ConstPointer(); //常量指針、指針常量、常量指針常量
//ArrayPointer(); //數組指針、指針數組
//FuncPointer(); //函數指針、指針函數
return 0;
}
建議不懂的同學把代碼一步一步調試一下,如果還有什麼不懂的歡迎評論留言!
最後留下一句話(ps:也是自己編的):
程序猿的我愛你,是像指針那樣,愛你勝過愛自己,把兩個地址都連在了一起,有了你,我纔有存在的價值;如果你愛着別人,那麼我就是多級指針,愛你所愛的人,當然包括你~!