让你不再害怕指针的应用-全程仿真+注解(第一部分:变量)
讓你不再害怕指針的應用-全程仿真+注解(第一部分:變量)(持續更新)
寫此文章一是為了分享,二是為了溫習!
預計包含的內容為:變量如int? 、數組? 、結構體? 、枚舉 、聯合體、(這個自己也在了解)。
軟件:CODE::Blocks? ? ? Compiler:GCC5.1.0
什么是指針:
指針(Pointer)是編程語言中的一個對象,利用地址,它的值直接指向(points to)存在電腦存儲器中另一個地方的值。由于通過地址能找到所需的變量單元,可以說,地址指向該變量單元。---摘自:百度百科
大概的意思就是講:指針可以直接指向另一個地方(包括變量的指針或者是機器的地址)的地址,然而大家也會迷茫當然我也會迷茫(大佬不要笑)。
指針到底是什么?
就是指針指向別人的地址,它自己有沒有地址呢?
(ps:如果不了解指針的類型、指針所指向的類型。請看另一篇文章:https://blog.csdn.net/Britripe/article/details/83544439)
答案:當然有
舉例一:
int main() {int a = 3;int *pointer;//指針變量pointer的類型為int *pointer = &a;//把指針變量pointer初始化為a的地址printf("%d\n",a);//\n換行,輸出變量a的值printf("%d\n",&a);//\n換行,輸出變量a的地址printf("%d\n",pointer);//輸出指針變量pointer的值,即是a的地址printf("%d\n",&pointer);//輸出指針變量pointer地址的值printf("%d",*pointer);//*指的是“取內容”,意思是“取pointer指向地址”的內容return(0);}運行結果:
總結:
說明指針也有地址。指針本身指向一個機器的地址, 它自己也有地址的。這個例子中,pointer的地址是:6356744。當運行到pointer的時候,pointer就會指向一個地址,這個地址就是a地址。
然后我又有一個疑問:
能不能通過指針pointer改變變量a的值呢?
舉例二;
int main() {int a = 3;int *pointer;pointer = &a;*pointer = 20;//*pointer 就是把pointer指向地址的變量a“取內容”取出來,然后賦值20printf("%d\n",a);return(0);}運行結果:
總結:
此時變量a已經從3改變到20了,說明通過指針變量pointer可以更改變量a的值。具體執行的流程是:運行到pointer的時候,pointer會指向a的地址,然后*pointer就會把poiner指向的地址取出來。由于事先定義此地址(pointer指向的地址)為變量a的地址,所以說白了*pointer就是個變量a等價的。自然可以賦值。
很明顯還有一個疑問:
既然指針變量pointer指向別人的地址,我能不能事先知道變量a的地址,然后直接賦值到指針變量pointer,還能不能改變變量a的值呢?雖然這沒有多大實用價值,不過還是值得仿真的!哈哈
我們試試看:舉例三
int main() {int a = 3,tr;//因為指針變量pointer的類型是int *,指向的類型為intint *pointer;//所以定義tr變量要為int型,保證類型一致tr = &a;pointer = tr;*pointer = 20;//*pointer 就是把pointer指向地址的變量a“取內容”取出來,然后賦值20printf("%d\n",a);return(0);}可以執行哈
那咱們要再深入的研究這個指針pionter,也是我之前一直疑問的。
就是指針pointer,到底占用多大內存呢?
帶這個問題我先科普一下老掉牙的東西,反正我記不住,難受!
在32位系統中:舉例四
int main() {printf("%d\n",sizeof(char));printf("%d\n",sizeof(short));printf("%d\n",sizeof(int));printf("%d\n",sizeof(float));printf("%d\n",sizeof(long));printf("%d\n",sizeof(double));return(0); }結果:
可以看出:char占用1個字節,short占用2個字節。以此類推看圖!
那么問題來了:
如果我這樣定義指針的類型:那么它的大小(也就是所占的內存)會不會變化呢?
舉例五:
int main() {int *pointer;short *Spointer;char *Cpointer;double *Dpointer;printf("%d\n",sizeof(pointer));printf("%d\n",sizeof(Spointer));printf("%d\n",sizeof(Cpointer));printf("%d\n",sizeof(Dpointer));return(0);}其實是不變的,為什么呢?
指針長度和地址總線有關。因為指針記錄的就是一個地址,那么32位的就是4字節,64位的就是8字節,
也正是地址總線的意義所在~---摘自:CSDN:foreverhuylee
????????? 也就是說:指針的地址也即是機器的地址。定義一個指針,在32位地址總線中,指針就是32位,不管你怎樣改變指針的類型和所指向的類型,指針本身說指向的地址也是32位,占用4個字節。
那么指針本身的地址會不會變呢?肯定不會變。因為指針本身的地址也是一個地址。自然不會變。
不信的話上程序:
舉例六:
int main() {int *pointer;short *Spointer;char *Cpointer;double *Dpointer;printf("%d\n",sizeof(&pointer));printf("%d\n",sizeof(&Spointer));printf("%d\n",sizeof(&Cpointer));printf("%d\n",sizeof(&Dpointer));return(0);}運行結果:
在這里我在嘮叨幾句:指針到底也是一個地址。
在32位機器總線中:指針指向的地址是32位,4個字節。指針本身的地址也是32位的,4個字節。
那么指針到底怎么用呢?
在變量中的運用
運用在變量int里面上面實例已經說明,不再贅述。
那我再舉個運行在char類型的例子:
舉例七:
int main() {char b = 'B';//定義變量b為字符型變量,c語言中沒有字符串變量char *pointer;//定義一個指針pointer,指針類型位char *pointer = &b; //把b的地址賦給 pointer*pointer = 'C';//把C賦給pointer取出來的內容printf("%d\n",sizeof(pointer));//輸出指針所占內存大小printf("%d\n",sizeof(&pointer));//輸出指針本身的地址所占內存的大小printf("%d\n",sizeof(b));//輸出變量所占內存的大小printf("%c\n",b);//輸出變量breturn(0);}輸出結果:
如果我們調皮一點呢?我們定義指針類型為char * 然后讓它指向 int型變量,會不會出問題呢?我們試一下哈
舉例八:
int main() {int b = 20;//定義變量b為字符型變量,c語言中沒有字符串變量char *pointer;//定義一個指針pointer,指針類型位char *pointer = &b; //把b的地址賦給 pointerprintf("%d\n",sizeof(pointer));//輸出指針所占內存大小printf("%d\n",sizeof(&pointer));//輸出指針本身的地址所占內存的大小printf("%d\n",sizeof(b));//輸出變量所占內存的大小printf("%c\n",b);//輸出變量breturn(0);}結果:
但是編譯器會報警,據說有的編譯器會報錯。
不同的編譯器處理問題的方法不同具體報錯的內容為:warning: assignment from incompatible pointer type
意思是:警告:從 “不兼容的指針類型” 分配。
這個問題大家注意一下,比較高級的編譯器對這種問題可以自己應付的,它可能明白你的意圖,哇智能了呀!
總結
以上是生活随笔為你收集整理的让你不再害怕指针的应用-全程仿真+注解(第一部分:变量)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 让你不再害怕指针-摘自:无名
- 下一篇: 代码详细解析简单常用DOS命令 jav