今天發生了一件特別有意思的事兒。而且是我自己解決的,我發現我更瞭解指針了。
情況發生在數據結構寫鏈表時的初始化,我傳了好久發現都不行。現在解決了,記錄一下。
我的數據結構採用如下沒有歧義的方式定義:
struct Node{
int data;//數據域
struct Node *next;//指針域
};
typedef struct Node Linkedlist;
在main函數中,我這樣寫:
int main()
{
Linkedlist L;
init(&L);
}
這裏給我搞蒙了,但是我發現Linkedlist其實和一種基本類型沒一點區別。因此我把Linkedlist想象爲int型。
我想做的事情呢,就是把這個數據結構的地址傳遞到函數中,然後委託函數init幫我分配一款內存。
我是這樣想的:
void init(Linkedlist *L){
//save length of linkedlist
L = (Linkedlist *)malloc(sizeof(Linkedlist));
if(!L){printf("OVERFLOW!\n");return;}
L->next = NULL;
L->data = 0;
printf("init linkedlist success!\n");
}
一切都看起來很好。然而我發現在init函數中輸出的L->next爲空指針,然而一到了這裏(main函數):
main 函數:
Linkedlist L;
init(&L);
printf("在main函數中的L->next:%p\n",L.next);
L的下一個不是空指針。這就不符合我的想法了。
爲什麼在init函數裏面沒有把NULL給我返回?這很讓我糾結。
說道這裏,我不得不吐槽一下C++這門語言。這門語言很奇葩啊,人家的&
和C裏面的&
是不一樣的。這門語言可以讓人迷惑好久。因爲嚴的教材裏面形參大量用到&
。而我喜歡用指針。因此我搞了好久才明白。
#include<stdio.h>
void c(int *p);
int main(int argc, char *argv[])
{
int a=1;
int *p=&a;
printf("in main\n");
printf("p = %p\n",&p);
printf("*p = %p\n",p);
printf("in main\n");
c(p);
return 0;
}
void c(int *p){
printf("in c\n");
printf("p = %p\n",&p);
printf("*p = %p\n",p);
printf("in c\n");
}
看吧,上面是我喜歡的傳遞參數的方式。
主要是說一點。
p的地址在行參,實參中不同。
而p是個指針嘛,它的值就是它所指向的那個值的地址。可以看到在傳遞參數時是沒有丟失的。
那我可以這樣理解,傳遞參數時,行參先開闢一段和實參一樣的空間,這個空間存放的值
是和實參一樣的。
這個就是指針在函數之間的傳遞。
不得不在吐槽一下,當初學C語言的時候老師直接教的是VC。那個人不人鬼不鬼的C++。既不是正宗的C++,也不是C語言–因爲有C++的關鍵字嘛。導致我一度因爲VC C++和C差不多。結果到了結構體,指針那一塊是徹底蒙了。當然C++考試還是容易混過去,但到了數據結構要寫代碼了我才一臉蒙B。
因爲理解了指針就可以看懂C的語法了。結果現實是在我學會指針當成參數傳遞等等我才更加理解指針的妙用。
中間繞了一段路跑去學了dos的彙編。
關鍵是老師都不教啊。。。
指針在我看來,初學的人直接這樣寫int a = 1; int* p=&a;
而不要寫成int *p=&a;
前者在於把指針當成一種基本的數據類型來看了。實際上指針根本就是一種基本的數據類型。爲什麼要有類型?以爲要確定在內存中的佔用的字節。爲什麼需要像p
,a
這樣的標識符,可以確定基地值嘛。base
。然後base + sizeof(類型)
纔在內存中完整的知道你嘛。既然都寫到這裏了,索性再寫兩句。
當然這部分不是C語言的範疇,而是彙編的範疇。我自己理解的。
c語言的內存管理做的相當的優秀。這裏指的是相對與彙編來說。–我個人更喜歡Java的內存管理。但是相對的語言不同。
彙編的話,經常需要做到操控字節。基本的邏輯就是:跳轉到段幾:偏移多少
,寫指令
。指令又分爲很多。最最最常用的就是把內存中的一個數移到寄存器中。(這樣的原因無非是爲了快,再吐槽一下,寫高級語言寫多了都快忘了這些東西了)。mov ax,bx;就是一條指令。說道這裏還想吐槽一下彙編。彙編有左着看的,也有右着看的。emmm,貴世界真亂。
彙編就是經常操作的對象是字節。沒錯。是8bit
。計算機的基本單位就是字節。這個大家可以放心。
寫一個彙編的循環可以是balabala,改變段地址和偏移地址寄存器的值,balabala,....
C呢?搞個個棧。聽着就好高級。C裏面的數組啊,int a[3];a[0+1];你知道這個+1有多厲害麼?可能你彙編需要寫+4字節。而c只要+1就能到下個字節了。多麼厲害。
開始畫圖吧。容易理解。
好吧,懶得畫了。。。。