上一篇基礎鏈接 https://www.cnblogs.com/xuexidememeda/p/12283845.html
主要說一下鏈表里面雙重指針
先說一下結構體
typedef struct LNode { int data; struct LNode *next; }LNode, *LinkList; typedef 把這個結構體定義一個別的名字 LNode==LNode 類型 LinkList==LNode* 類型 *LinkList 是函數指針..........這個寫法我也很懵逼沒法從內存角度理解 最后也有簡單介紹函數指針
你不定義typedef一樣直接可以用LNode 就是寫的時候不方便 但是我覺得對新手易於理解
先上總代碼 兩個main12是測試函數 自己改着玩

// ConsoleApplication1.cpp : 定義控制台應用程序的入口點。 // #include "stdafx.h" #include<malloc.h> using namespace std; typedef struct LNode { int data; struct LNode *next; }LNode, *LinkList; //--------------后插法創建單鏈表 ------------------ void CreateList_E(LinkList &head, int n) { int i; LinkList pnew; LinkList pend;//定義最后的節點指針; //先建立頭結點,數據為空; head = new LNode; head->next = NULL; pend = head;//頭結點是最后的節點 ; for (i = 0; i < n; i++) { pnew = new LNode; printf("請輸入第%d個節點的數據:\n",i); scanf_s("%d", &pnew->data); pnew->next = NULL; pend->next = pnew; pend = pnew; } } void CreateList_E1(LNode* &head, int n) { int i; LinkList* ptr; LinkList pnew; LinkList pend;//定義最后的節點指針; //先建立頭結點,數據為空; head = new LNode; //返回的是分配空間的首地址LNode* 類型 head->next = NULL; pend = head;//頭結點是最后的節點 ; for (i = 0; i < n; i++) { pnew = new LNode; printf("請輸入第%d個節點的數據:\n", i); scanf_s("%d", &pnew->data); pnew->next = NULL; pend->next = pnew; pend = pnew; } } //雙重指針 頭結點貌似必須在外面創建?? void CreateList_E1(LNode** lnode, int n) { LinkList head = *lnode; head->next = NULL; for (int i = 0; i < n; i++) { LNode* pnew = new LNode; printf("請輸入第%d個節點的數據:\n", i); scanf_s("%d", &pnew->data); pnew->next = head->next; head->next = pnew; } } //------------------打印鏈表---------------- void PrintList(LinkList head) { LinkList item; item = head; item = item->next;//這一步不是必須要做的,為了跳過頭結點(沒有數據) while (item != NULL) { printf("----%d----\n", item->data); item = item->next; } } void main1() { LNode* L = NULL; int n; printf("輸入要創建的鏈表結點個數:\n"); scanf_s("%d", &n); CreateList_E1(L, n); printf("\n打印結果!\n"); PrintList(L); } void main2() { LNode* temp= new LNode; LNode** L= &temp; int n; printf("輸入要創建的鏈表結點個數:\n"); scanf_s("%d", &n); CreateList_E1(L,n); printf("\n打印結果!\n"); PrintList(*L); } int _tmain(int argc, _TCHAR* argv[]) { //main1(); main2(); }
說一下創建+賦值鏈表函數(自己看着前面的看)
void CreateList_E(LinkList &head, int n)==void CreateList_E1(LNode* &head, int n)
LinkList 的類型其實是LNode* 類型 然后&head 是傳參引用?好像是這樣的(忘怎么說了) 如果你不帶&符號只能在本函數打印出來賦值語句 在封裝的函數是無法打印的
跟你的swap學過一個函數交換值他真實的值還是不變,多數人疑問就是我傳的可是一個指針類型,他是一個地址呀!為什么還是傳不過去呢 因為你的指針地址是在棧中分配空間用完就銷毀呢( CreateLis函數運行結束main函數無法找到原來分配的地址) 只要頭結點是在main函數中分配的那么他以后的指針在哪分配都沒問題的..... 看似簡單的一個問題,要 真正弄懂其實要看編譯器怎么辦的就是看匯編
(本人匯編基礎不扎實自學的以后博客再補上!!)
唯一確定的是不加&函數call return 之后會 main函數無法得到指針的地址
void CreateList_E1(LNode** lnode, int n) 這個和CreateList_E(LinkList &head, int n) 差不多因為我們之前說過 加一個& 相當於類型后加個*
其實你完全可以想簡單點你完全可以把指針類型當成類似int之類的類型 ,比如 要實現 void swap1(int a, int b)交換a b的值 我們都知道無法交換值 要交換值有兩種方法 一種是void swap1(int* a, int* b) 一種是引用 所以要使用指針的指針
函數指針...............簡單例子
例如:
class Test { private: int x; int y; public: Test(){ x = 1; y = 2;} void Pintf() { cout << x << " " << y << endl; } };
int _tmain(int argc, _TCHAR* argv[]) { Test a; a.Pintf(); int* b = (int*)&a; //cout << *b; cout << &a << endl; //如果直接輸出a的內存的話 是0001 0002 //沒法直接輸出必須用指針查看值 short* c = (short*)&a; char* d = (char*)&a; cout << *d << endl; cout << *c<<endl; cout <<b; getchar(); /* 17: Test a; 00972CC8 8D 4D F0 lea ecx,[a] ecx 0x0108FCB0 this 指針 00972CCB E8 E5 E7 FF FF call Test::Test (09714B5h) 18: a.Pintf(); 00972CD0 8D 4D F0 lea ecx,[a] 00972CD3 E8 7A E6 FF FF call Test::Pintf (0971352h) 19: int* b = (int*)&a; 00972CD8 8D 45 F0 lea eax,[a] 00972CDB 89 45 E4 mov dword ptr [b],eax 20: //cout << *b; 21: cout << &a<<endl; 00972CDE 8B F4 mov esi,esp 00972CE0 68 ED 13 97 00 push 9713EDh 00972CE5 8B FC mov edi,esp 00972CE7 8D 45 F0 lea eax,[a] 00972CEA 50 push eax 00972CEB 8B 0D F8 10 98 00 mov ecx,dword ptr ds:[9810F8h] 00972CF1 FF 15 FC 10 98 00 call dword ptr ds:[9810FCh] 00972CF7 3B FC cmp edi,esp 00972CF9 E8 40 E6 FF FF call __RTC_CheckEsp (097133Eh) 00972CFE 8B C8 mov ecx,eax 00972D00 FF 15 9C 10 98 00 call dword ptr ds:[98109Ch] 00972D06 3B F4 cmp esi,esp 00972D08 E8 31 E6 FF FF call __RTC_CheckEsp (097133Eh) */ }
Test a; 這個a 到底是什么? 其實就是這個類的開頭 比如這個開頭存的就是0001 0002 x,y 我原來認為a存的 一直是一個地址指向 00010002這位置
假如test 類里面有虛函數 例如 virtual void Function_4() 則 Test a 中 a的首地址開頭存的就是一個虛表函數 總地址例如是A (意思是 *A 是你第一個虛函數 *(A+1)是你第二個虛函數)
如果你多繼承而且父類中有虛函數則比如有2個則有2個虛表