『壹』 c語言指針詳解
指針是一個特殊的變數,它裡面存儲的數值被解釋成為內存里的一個地址。數據在內存中的地址也稱為指針,如果一個變數存儲了一份數據的指針,我們就稱它為指針變數。
計算機中所有的數據都必須放在內存中,不同類型的數據佔用的位元組數不一樣,例如 int 佔用 4 個位元組,char 佔用 1 個位元組。
為了正確地訪問這些數據,必須為每個位元組都編上號碼,就像門牌號、身份證號一樣,每個位元組的編號是唯一的,根據編號可以准確地找到某個位元組。
C語言用變數來存儲數據,用函數來定義一段可以重復使用的代碼,它們最終都要放到內存中才能供 CPU 使用。數據和代碼都以二進制的形式存儲在內存中,計算機無法從格式上區分某塊內存到底存儲的是數據還是代碼。
當程序被載入到內存後,操作系統會給不同的內存塊指定不同的許可權,擁有讀取和執行許可權的內存塊就是代碼,而擁有讀取和寫入許可權(也可能只有讀取許可權)的內存塊就是數據。
CPU 只能通過地址來取得內存中的代碼和數據,程序在執行過程中會告知 CPU 要執行的代碼以及要讀寫的數據的地址。
如果程序不小心出錯,或者開發者有意為之,在 CPU 要寫入數據時給它一個代碼區域的地址,就會發生內存訪問錯誤。這種內存訪問錯誤會被硬體和操作系統攔截,強製程序崩潰,程序員沒有挽救的機會。
變數名和函數名為我們提供了方便,讓我們在編寫代碼的過程中可以使用易於閱讀和理解的英文字元串,不用直接面對二進制地址,那場景簡直讓人崩潰。
需要注意的是,雖然變數名、函數名、字元串名和數組名在本質上是一樣的,它們都是地址的助記符,但在編寫代碼的過程中,我們認為變數名表示的是數據本身,而函數名、字元串名和數組名表示的是代碼塊或數據塊的首地址。
(1)c語言指針詳解ppt擴展閱讀
指針使用(* 和 &)
*&a可以理解為*(&a),&a表示取變數 a 的地址(等價於 pa),*(&a)表示取這個地址上的數據(等價於 *pa),繞來繞去,又回到了原點,*&a仍然等價於 a。
&*pa可以理解為&(*pa),*pa表示取得 pa 指向的數據(等價於 a),&(*pa)表示數據的地址(等價於 &a),所以&*pa等價於 pa。
對星號*的總結
在我們目前所學到的語法中,星號*主要有三種用途:
1、表示乘法,例如int a = 3, b = 5, c; c = a * b;,這是最容易理解的。
2、表示定義一個指針變數,以和普通變數區分開,例如int a = 100; int *p = &a;。
3、表示獲取指針指向的數據,是一種間接操作,例如int a, b, *p = &a; *p = 100; b = *p;。
『貳』 C語言中指針的用法介紹(2)
如果上例中,ptr是被減去5,那麼處理過程大同小異,只不過ptr的值是被減去5乘 sizeof(int),新的ptr指向的地址將比原來的ptr所指向的地址向低地址方向移動了20個位元組。
總結一下,一個指針ptrold加上一個整數 n後,結果是一個新的指針ptrnew,
ptrnew的類型和ptrold的類型相同,ptrnew所指向的類型和ptrold所指向的類型也相同。ptrnew的值將比ptrold的值增加了 n乘sizeof(ptrold所指向的類型)個位元組。就是說,ptrnew所指向的內存區將比ptrold所指向的內存區向高地址方向移動了 n乘 sizeof(ptrold所指向的類型)個位元組。
一個指針ptrold減去一個整數 n後,結果是一個新的指針ptrnew,ptrnew的類型和ptrold的類型相同,ptrnew所指向的類型和ptrold所指向的類型也相同。ptrnew的值將比ptrold的值減少了 n乘 sizeof(ptrold所指向的類型)個位元組,就是說, ptrnew所指向的內存區將比ptrold所指向的內存區向低地址方向移動了n乘sizeof(ptrold所指向的類型)個位元組。
第三章。運算?amp;和*
這里&是取地址運算符,*是...書上叫做"間接運算符"。
&a的運算結果是一個指針,指針的類型是 a的類型加個*,指針所指向的類型是a的類型,指針所指向的地址嘛,那就是a 的地址。*p的運算結果就五花八門了。總之*p的結果是p所指向的東西,這個東西有這些特點:它的類型是p指向的類型,它所佔用的地址是p所指向的地址。
例五:
int a=12;
int b;
int *p;
int **ptr;
Generated by Foxit PDF Creator ? Foxit Software
http://www.foxitsoftware.com For evaluation only.p=&a;//&a的結果是一個指針,類型是 int*,指向的類型是 int,指向的地址是a的地址。*p=24;//*p的結果,在這里它的類型是 int,它所佔用的地址是p所指向的地址,顯然,*p就是變數a。ptr=&p;//&p的結果是個指針,該指針的類型是p的類型加個*,在這里是 int**。該指針所指向的類型是p的類型,這里是 int*。該指針所指向的地址就是指針p自己的地址。
*ptr=&b;//*ptr是個指針,&b的結果也是個指針,且這兩個指針的類型和所指向的類型是一樣的,所以用&b來給*ptr賦值就是毫無問題的了。**ptr=34;//*ptr的結果是ptr所指向的東西,在這里是一個指針,對這個指
針再做一次*運算,結果就是一個 int 類型的變數。
第四章。指針表達式。
一個表達式的最後結果如果是一個指針,那麼這個表達式就叫指針表達式。
下面是一些指針表達式的例子:
例六:
int a,b;
int array[10];
int *pa;
pa=&a;//&a是一個指針表達式。
int **ptr=&pa;//&pa也是一個指針表達式。
*ptr=&b;//*ptr和&b都是指針表達式。
pa=array;
pa++;//這也是指針表達式。
例七:
char *arr[20];
char **parr=arr;//如果把arr 看作指針的話,arr 也是指針表達式
char *str;
str=*parr;//*parr 是指針表達式
str=*(parr+1);//*(parr+1)是指針表達式
str=*(parr+2);//*(parr+2)是指針表達式
由於指針表達式的結果是一個指針,所以指針表達式也具有指針所具有的四個要素:指針的類型,指針所指向的類型,指針指向的內存區,指針自身占據的內存。
好了,當一個指針表達式的結果指針已經明確地具有了指針自身占據的內存的話,這個指針表達式就是一個左值,否則就不是一個左值。
在例七中,&a不是一個左值,因為它還沒有占據明確的內存。*ptr是一個左值,因為*ptr 這個指針已經占據了內存,其實*ptr 就是指針 pa,既然 pa 已經在內存中有了自己的位置,那麼*ptr當然也有了自己的位置。
第五章。數組和指針的關系
Generated by Foxit PDF Creator ? Foxit Software
http://www.foxitsoftware.com For evaluation only.如果對聲明數組的語句不太明白的話,請參閱我前段時間貼出的文?lt;<如何理解c 和c++的復雜類型聲明>>。數組的數組名其實可以看作一個指針。看下例:
例八:
int array[10]={0,1,2,3,4,5,6,7,8,9},value;
...
...
value=array[0];//也可寫成:value=*array;
value=array[3];//也可寫成:value=*(array+3);
value=array[4];//也可寫成:value=*(array+4);
上例中,一般而言數組名array代表數組本身,類型是 int [10],但如果把array看做指針的話,它指向數組的第 0個單元,類型是 int *,所指向的類型是數組單元的類型即 int。因此*array等於 0 就一點也不奇怪了。同理,array+3 是一個指向數組第3個單元的指針,所以*(array+3)等於3。其它依此類推。
例九:
例九:
char *str[3]={
"Hello,this is a sample!",
"Hi,good morning.",
"Hello world"
};
char s[80];
strcpy(s,str[0]);//也可寫成strcpy(s,*str);
strcpy(s,str[1]);//也可寫成strcpy(s,*(str+1));
strcpy(s,str[2]);//也可寫成strcpy(s,*(str+2));
上例中,str是一個三單元的數組,該數組的每個單元都是一個指針,這些指針各指向一個字元串。把指針數組名 str 當作一個指針的話,它指向數組的第 0號單元,它的類型是char**,它指向的類型是char *。
*str也是一個指針,它的類型是char*,它所指向的類型是char,它指向的地址是字元串"Hello,this is a sample!"的第一個字元的地址,即’H’的地址。
『叄』 C語言指針運算詳解
C語言中的數組是指 一類 類型,數組具體區分為 int 類型數組,double類型數組,char數組 等等。同樣指針 這個概念也泛指 一類 數據類型,int指針類型,double指針類型,char指針類型等等。
通常,我們用int類型保存一些整型的數據,如 int num = 97 , 我們也會用char來存儲字元: char ch = 'a'。
我們也必須知道:任何程序數據載入內存後,在內存都有他們的地址,這就是指針。而為了保存一個數據在內存中的地址,我們就需要指針變數。
因此:指針是程序數據在內存中的地址,而指針變數是用來保存這些地址的變數。
『肆』 怎麼理解C語言里的指針
指針就是內存的地址。
內存懂吧,就是放數據的地方,數據就像一個人的家,懂吧,一棟樓里,肯定住了不止一家人吧,那麼確定每家的地址,就需要幾樓幾零幾這樣設置地址吧。內存也是一樣的,內存是按一個位元組的大小來安排地址的。
比如int a;我們申請了一個int型,整形的變數,int是四個位元組的數據類型,所以變數a在內存上會有一個地址,地址是按第一個數字為準的。假設內存上沒有任何數據,都是空的,那麼內存就會按順序來放地址,假設內存的第一個地址是0,以此類推,那麼當我們int a變數的時候,內存就會把0-3地址的空間分配給變數a,因為a佔四個單元內存,那麼怎麼確定變數a的地址呢?計算機是按這個內存地址上的最開始那個算的,即變數a的地址是0。
當我們在聲明了int a變數之後,再聲明一個char b變數。如下:
int a;
char b;
這個時候,int a先被聲明了,假設內存是空的,那麼變數a就會被安排0-3的地址。第二個聲明char b;就會接在變數a之後,因為char是一個位元組的數據,所以內存只會分配一個4號內存給變數b,變數b的地址就是4。以此類推,其他類型是一樣的。
指針就是用來存放內存地址的地方。指針變數一般也會單獨存放。
比如:
int a; //內存分配編號為0-3的內存空間給變數a;變數a的地址就是最開頭的那個編號即變數a的地址是0;
char b; //內存緊接著分配編號為4的內存空間給變數b,因為char是一個位元組的,所以變數b的地址唯一,就是4。
隨後,我們申請指針。
int * p;
char * t;
我們申請了兩個指針, *是指針的標志,有*的變數是指針,沒有*的是一般變數,*只是用來區別變數是int型數據還是指針。
當變數是指針的時候,意味著這個變數只能存放內存地址,而不能存放任何自然數。
即指針p,只能用p=&a; 變數a在C語言中,單用的時候,使用變數a裡面存放的值,而不是他的地址,比如 我們再聲明一個變數 int g; g=a;這個例子里,我們聲明了一個int型變數g,並用g=a來初始化g,g=a的意思是,用a里存放的數,即讀取出a裡面存的數,然後把這個數給g,並不是把a的地址給g。所以C語言里規定了符號&為取地址操作符,p=&a;的意思就是取出a的地址,給p,這個時候是可以的,因為p是指針,並且p指針指向的類型是int。
在C語言中,給指針賦地址,要檢查變數的類型的,比如int *p;這個指針p,p前面的*表示他是指針,說明他只能存放地址,*號前面的類型說明符,進一步說明,p這個指針只能存int型變數的地址,即如果p=&b;是不會成立的,並且會報錯,因為p是一個存放int型變數的指針,而變數b是一個char型變數,在C語言里,指針和對應的變數的類型要一致。不能夠混用。
不能混用的原因在於,到時候解引用的時候會出錯,即如果 p=&b,成立的話,那麼到時候使用 a=*p;的時候會出現嚴重錯誤,因為p=&b,是把char型變數的地址給int型指針,當我們在使用解引用符號*的時候,就會錯誤,a=*p;的意思是,用p里存放的地址,找到內存上的數據,並且給變數a,編譯器會檢查,得知p是int型變數指針,所以需要按照這個地址取出的數據是四個位元組的數據,所以程序會把b的地址4按照int型的數據變數地址來使用,會調取內存上編號為4,5,6,7號位的數據,然而編號為4的內存上放的是char 型變數b的數據,5,6,7號內存上,根本沒有數據,從而出錯。所以C語言嚴格要求,指針的類型和變數類型要一致,即int *的指針只能存放int型變數的地址,不可混用。
最後一個疑問點在於*符號,在C語言里是復用的,即有三種使用方法,這里給你區別一樣,要不然你會有疑問,* 這個符號,在C語言有三種意思,一種是乘法,即 a=5*3里,這個時候這個符號*是乘法的意思,認出他很簡單,因為乘法必須要有乘數,被乘數,即符號*左右兩邊都要有實數或者變數,即使是c=a*b;的表達也不會錯,a,b是變數的話,符號*是乘號用法。
第二種用法就是我們看到的 int *p;這裡面符號*是指針的標志,只是用來說明p是一個指針,假設一個int p,那請問怎麼區別p是指針還是變數,所以就是通過添加符號*來區別變數和指針的,而且指針和變數一樣,都需要int,char,double等類型說明,所以只有在聲明變數的時候,才使用。
第三中用法就是和符號&的操作相反的操作,符號&在C語言里,只有一個用法,就是表明,這個運算符是取出後面的地址,即&a,就是取出變數a的地址,即指針,符號&左邊沒有任何變數,只有右邊有變數,而符號*則是相反操作,意思是取出符號*右邊的指針里的地址,並取出這個地址里存放的數,所以*P,就是取出指針p里的地址,然後取出這個地址里存放的數。符號*也是右邊有變數,而左邊沒有任何變數的操作,他們都是單操作符。
第二種和第三種用法要怎麼區別,就是第三種一定是a=*p這樣使用的,符號*的左邊一定沒有任何類型說明符,而如果是第二種用法,那麼符號*的左邊一定有類型說明符,即第二種一定是int *p; 即 類型說明符 + * +變數名的形式,而且只用在聲明指針變數的時候。
『伍』 求解C語言指針,講解越詳細越好
p是一個包含四個指向char指針的數組
pp是一個指向char類型指針的指針 也就是一個二維指針 所以在輸出的時候*pp就相當於p *(*pp+1)相當於*(p+1)也就是想當於p[1]
這個就是輸出每個字元串的第二個字母 夜也就是O E I E
『陸』 c語言指針的概念
指針是C語言中廣泛使用的一種數據類型。 運用指針編程是C語言最主要的風格之一。利用指針變數可以表示各種數據結構; 能很方便地使用數組和字元串; 並能象匯編語言一樣處理內存地址,從而編出精練而高效的程序。指針極大地豐富了C語言的功能。 學習指針是學習C語言中最重要的一環, 能否正確理解和使用指針是我們是否掌握C語言的一個標志。同時, 指針也是C語言中最為困難的一部分,在學習中除了要正確理解基本概念,還必須要多編程,上機調試。只要作到這些,指針也是不難掌握的。
指針的基本概念 在計算機中,所有的數據都是存放在存儲器中的。 一般把存儲器中的一個位元組稱為一個內存單元, 不同的數據類型所佔用的內存單元數不等,如整型量佔2個單元,字元量佔1個單元等, 在第二章中已有詳細的介紹。為了正確地訪問這些內存單元, 必須為每個內存單元編上號。 根據一個內存單元的編號即可准確地找到該內存單元。內存單元的編號也叫做地址。 既然根據內存單元的編號或地址就可以找到所需的內存單元,所以通常也把這個地址稱為指針。 內存單元的指針和內存單元的內容是兩個不同的概念。 可以用一個通俗的例子來說明它們之間的關系。我們到銀行去存取款時, 銀行工作人員將根據我們的帳號去找我們的存款單, 找到之後在存單上寫入存款、取款的金額。在這里,帳號就是存單的指針, 存款數是存單的內容。對於一個內存單元來說,單元的地址即為指針, 其中存放的數據才是該單元的內容。在C語言中, 允許用一個變數來存放指針,這種變數稱為指針變數。因此, 一個指針變數的值就是某個內存單元的地址或稱為某內存單元的指針。圖中,設有字元變數C,其內容為「K」(ASCII碼為十進制數 75),C佔用了011A號單元(地址用十六進數表示)。設有指針變數P,內容為011A, 這種情況我們稱為P指向變數C,或說P是指向變數C的指針。 嚴格地說,一個指針是一個地址, 是一個常量。而一個指針變數卻可以被賦予不同的指針值,是變。 但在常把指針變數簡稱為指針。為了避免混淆,我們中約定:「指針」是指地址, 是常量,「指針變數」是指取值為地址的變數。 定義指針的目的是為了通過指針去訪問內存單元。
既然指針變數的值是一個地址, 那麼這個地址不僅可以是變數的地址, 也可以是其它數據結構的地址。在一個指針變數中存放一
個數組或一個函數的首地址有何意義呢? 因為數組或函數都是連續存放的。通過訪問指針變數取得了數組或函數的首地址, 也就找到了該數組或函數。這樣一來, 凡是出現數組,函數的地方都可以用一個指針變數來表示, 只要該指針變數中賦予數組或函數的首地址即可。這樣做, 將會使程序的概念十分清楚,程序本身也精練,高效。在C語言中, 一種數據類型或數據結構往往都佔有一組連續的內存單元。 用「地址」這個概念並不能很好地描述一種數據類型或數據結構, 而「指針」雖然實際上也是一個地址,但它卻是一個數據結構的首地址, 它是「指向」一個數據結構的,因而概念更為清楚,表示更為明確。 這也是引入「指針」概念的一個重要原因。
『柒』 論述C語言中指針的概念和作用,並舉例說明
1、指針概念:變數的地址(計算機內存位元組的編號)叫做指針,存放變數地址的變數叫指針變
量,
簡言之,指針是用來存放地址的。
2、作用:指向這個變數或數組的首地址,是變數的間接引用方式。其值如果改變,變數的值或數組元素的值也會跟著改變。程序對變數的操作實際上是對變數所在的存儲空間讀取和寫入數據。方便對變數的操作。
舉例說明:
int
a=3;/*定義一個整型變數a,並賦初值3*/
int
*p;/*定義一個指針變數P*/
p=&a;/*讓p指向a的首地址,也就是a的地址*/
程序為a分配一個2個位元組的存儲單元,假如2個位元組的地址分別為(ABCD1和ABCD2,唯一),那麼p裡面放的值就是ABCD1,不是3。這時可通過p直接引用a,實際上*p=3。以後不管a存放在內存中的哪個地方,只用通過調用p就可以引用a。這時如果令*p=4,則最後的a值也為4。對於數組,指針是指向數組的首地址。