第五章 3 指針(11--33)

十一 指針的運算

一、 做爲一種特殊的變量,指針能夠進行一些運算,但並不是全部的運算都是合法的,指針的運算主要侷限在加減算術和其餘一些爲數很少的特殊運算。 數組

二、 把a的值5做爲地址 0x00000005賦值給*p是發生訪問衝突。整數與指針最好不要直接運算。 三、地址的賦值和指針的賦值。函數

num,*p1,*p2 他們中一個改變,其餘的兩個都會跟着改變 四、 a被編譯器解析爲數組的首地址 經過下標循環進行遍歷 工具

經過指針循環進行遍歷 五、經過dll注入的方式修改另外一個進程的數據 經過定義並初始化二級指針p,使其改變另外一個程序的指針p的指向,從而改變它的值。 外掛工具:cheat engine 注意不會實時刷新spa

十二 指針的算數運算

一、 使用遞增/遞減運算符(++ 和 --)將指針遞增或遞減.net

指針++就是按照指針類型的大小,前進一個類型的大小,int,前進四個字節 指針 ++ 和 -- 只有在數組的內部纔有意義。 二、指針++ 就是 指針每次向前移動sizeof(指針類型)個字節3d

經過指針循環的方式初始化數組a的每個元素 (從頭至尾掃描數組) (注:格式控制符「%p」中的p是pointer(指針)的縮寫。指針的值是語言實現(編譯程序)相關的,但幾乎全部實現中,指針的值都是一個表示地址空間中某個存儲器單元的整數。printf函數族中對於%p通常以十六進制整數方式輸出指針的值,附加前綴0x。) 三、指針加上2,在數組內部等價於向後移動兩個元素的大小 指針減去3,等價於數組內部,向前移動3個元素的大小指針

此時此刻,就會打印出 3 5 2 四、指針的加減法在非數組內部沒有任何意義,並且很容易越界報錯 一個exe不能讀寫其餘exe進程的內存。 code

十三 指針之間的比較

一、 對兩個毫無關聯的指針比較大小是沒有意義的,由於指針只表明了「位置」這麼一個信息, 可是, 若是兩個指針所指向的元素位於同一個數組(或同一塊動態申請的內存中), 指針的大小比較反映了元素在數組中的前後關係。 二、 經過比較兩個指針的地址,來判斷哪一個指針的位置考前仍是靠後 地址的比較沒有意義,只能判斷誰的地址也就是內存的編號比較靠前 三、經過指針指向數組中的元素,來比較數組元素的地址哪一個靠前 四、 指針是否相等,能夠判斷是否指向同一地址 對象

十四 指針運算

一、 如有p指向數組a,則: blog

二、 a是一個數組

p=p+1;

十五 指針相減

一、 指針變量所支持的另外一種運算方式是兩個同類型指針相減,返回值是個有符號整數

二、舉例來講,指針p1指向sz[i],指針p2指向sz[j],那麼p1-p2=i-j,兩個指針的距離並非其值簡單作差,還要除以「指針所指類型佔用的內存字節數」。

三、指針相減,若是值爲正,p1在p2後面。值爲負,p1在p2前面 具體之差就意味着指針之間相隔幾個元素的大小 具體之差不是地址之差,而是地址之差除以指針指向元素的大小 指針存儲的值與指針指向的數據沒有任何關係

四、數組之間能夠判斷誰的編號在前,誰的編號在後,而且能夠判斷兩個指針之間相隔多少個元素。具體之差不是地址之差,而是地址之差除以指針指向元素的大小。指針相減,能夠判斷下標。p1<p2,p1對應元素的下標小於p2對應元素的下標。

十六 指針與數組

一、 指針與數組  指向數組元素的指針變量

數組名是表示數組首地址的地址常量 注意:數組名a不表明整個數組,只表明數組首元素的地址。 「p=a;」的做用是「把a數組的首元素的地址賦給指針變量p」, 而不是「把數組a各元素的值賦給p」。 二、 數組名num就是 數組第一個元素的首地址 num是一個指向int 類型的常量指針 num=0x123234492; 常量不能夠賦值不能夠放在賦值號的左邊。

十七 指向元素指針與指向數組的指針

一、 指向元素的指針與指向數組的指針

運行結果:

十八 指針引用多維數組

一、

二、對於二維數組

三、 二維數組名是指向行的,它不能對以下說明的指針變量p直接賦值:

十九 指針遍歷輸出二維數組的值

一、 有一個3×4的二維數組,要求用指向元素的指針變量輸出二維數組各元素的值。 二維數組的元素是整型的,它至關於整型變量,能夠用int*型指針變量指向它 二維數組的元素在內存中是按行順序存放的,即存放完序號爲0的行中的所有元素後,接着存放序號爲1的行中的所有元素,依此類推 所以能夠用一個指向整型元素的指針變量,依次指向各個元素 線性的方式循環二維數組: 嵌套for循環的方式變量二維數組:

二十 指針的方式輸出二維數組任意元素

一、指針的方式輸出二維數組任一行任一列元素的值 定義一個二維數組a[3][4]

二十一 數組做爲函數參數

一、用指向數組的指針做函數參數  一維數組名能夠做爲函數參數,多維數組名也可做函數參數。  用指針變量做形參,以接受實參數組名傳遞來的地址。  能夠有兩種方法: ①一維數組用指向變量的指針變量 ②二維數組用指向一維數組的指針變量

(1)一維數組用指向變量的指針變量

int a[10] 數組做爲函數參數,傳遞的是地址,地址就是指針佔4個字節, 函數的參數對於數組沒有副本機制,爲了節約內存,拷貝數組浪費空間與CPU。 在main函數中調用test,將會打印出4 指針變量做爲一維數組的參數 (2)二維數組用指向一維數組的指針變量 實參數組名是指針常量,但形參數組名是按指針變量處理 二、將數組a中n個整數按相反順序存放 數組做爲函數參數,則數組沒有副本機制,等價於直接操做原生數組 三、用指針方法對10個整數按由大到小順序排序。

 解題思路:  在主函數中定義數組a存放10個整數,定義int *型指針變量p指向a[0]  定義函數sort使數組a中的元素按由大到小的順序排列  在主函數中調用sort函數,用指針p做實參  用冒泡進行排序 四、有一個班,3個學生,各學4門課,計算總平均分數以及第n個學生的成績。

 解題思路:這個題目是很簡單的。本例用指向數組的指針做函數參數。用函數average求總平均成績,用函數search找出並輸出第i個學生的成績。

求平均值: 第一個用指向數組的指針存儲二維數組名,傳遞多少個元素(每一個元素又是一個一維數組) 顯示出第n個學生的成績 五、有一個班,3個學生,各學4門課,查找有一門以上課程不及格的學生,輸出他們的所有課程的成績。  解題思路:在主函數中定義二維數組score,定義search函數實現輸出有一門以上課程不及格的學生的所有課程的成績,形參p的類型是float(*)[4]。在調用search函數時,用score做爲實參,把score[0]的地址傳給形參p。 變量因此元素,有不及格的就跳出循環,而後打印出來 檢測到不及格的就打印出來

二十二 函數指針概念

一、 若是在程序中定義了一個函數,在編譯時,編譯系統爲函數代碼分配一段存儲空間,這段存儲空間的起始地址,稱爲這個函數的指針。

(1) 定義一個函數msg 定義函數的指針p,使他指向函數名msg, 直接調用p();就會執行函數msg。 (2) 定義函數的指針p,使他指向函數名add, 直接調用add(1,10);就會執行函數add。

二十三 函數返回值是指針

一、 一個函數能夠返回一個整型值、字符值、實型值等,也能夠返回指針型的數據,即地址。其概念與之前相似,只是返回的值的類型是指針類型而已

定義返回指針值的函數的通常形式爲 類型名 *函數名(參數表列);

定義全局變量 二、 用隨機數生成一個數組,寫一個函數查找最小的數,並返回最小數的地址。在主函數中打印出來最小數。

函數返回一個地址,對於數組而言,函數參數調用沒有副本機制,爲了節約內存

二十四 函數返回值是指針練習--用途

一、 實現字符串的拷貝 返回拷貝好的字符串地址,進行拷貝字符串 二、本身實現字符串的拷貝

返回拷貝好的字符串地址 上面的while循環能夠拆分紅以下的代碼

二十五 指針左值指針與整數指針空指針以及指向爲空的指針

一、左值的概念, 「可放在賦值號左邊的均可稱爲左值」

二、空指針 void *指針是一種特殊的指針,不指向任何類型的數據,若是須要取出,用此地址指向某類型的數據,應先對地址進行類型轉換。

二十六 Void指針與空指針--詳細講解

一、空類型指針能夠指向任何類型的數據,包含他們的地址 二、任何指針均可以賦值給空類型的指針,用於保存地址

三、memset函數

從數組str的首地址開始,前進 5個字節,進行賦值,賦值一個字符 ’ A ’ 。 memset(str, ’A’ ,5) ;

對20個字節所有賦值爲0,對於數組清零 (num是數組) memset(num, 0 ,20);

遍歷數組num的因此元素,元素值都爲0。 四、malloc函數 malloc的全稱是memory allocation,中文叫動態內存分配,當沒法知道內存具體位置的時候,想要綁定真正的內存空間,就須要用到動態的分配內存。原型爲extern void

五、空類型指針能夠轉換爲任何類型的指針

一個類型的指針包含三個信息: 地址、 步長、內容如何解析

二十七 動態分配

一、 數組只能處理小數據 例如:定義數組 int a[1024102410] ; 運行報錯 二、動態分配,是指用戶能夠在程序運行期間根據須要申請或釋放內存,大小也徹底可控。動態分配不像數組內存那樣須要預先分配空間,而是由系統根據程序須要動態分配,大小徹底按照用戶的要求來,當使用完畢後,用戶還可釋放所申請的動態內存,由系統回收,以備他用。 malloc和free是C標準庫中提供的兩個函數,用以動態申請和釋放內存

 malloc()函數的基本調用格式爲:  void *malloc( unsigned int size );  參數size是個無符號整型數,用戶由此控制申請內存的大小,執行成功時,系統會爲程序開闢一塊大小爲size個內存字節的區域,並將該區域的首地址返回,用戶可利用該地址管理並使用該塊內存,若是申請失敗(好比內存大小不夠用),返回空指針NULL。

在棧區開闢一段內存,系統會本身回收。 在堆區開闢一段內存,須要本身手動用free釋放內存 開闢內存後當即釋放掉

free就是釋放內存,例如free(p) malloc()函數返回類型是void*,用其返回值對其餘類型指針賦值時,必須進行顯式轉換。

二十八 free函數注意事項

一、malloc函數和free函數 在stdlib.h頭文件裏面

二、蠶食法消耗內存

二十九 malloc_calloc_realloc

一、C語言標準庫函數還提供了calloc函數用以動態申請內存,和malloc函數以字節爲單位申請內存不一樣,calloc函數是以目標對象爲單位分配的,目標對象能夠是數組,也能夠是後面會講到的結構體等。 二、 calloc會自動將內存初始化爲0,malloc就不會

int num; scanf("%d",&num); (1)malloc函數 //動態數組,輸入19,就有19個元素,初始化

若是想對該數組進行擴充,就用到了realloc函數 addnum增長的個數

三十 內存分配習題以及小結

一、創建動態數組,輸入5個學生的成績,另外用一個函放數檢查其中有無低於60分的,輸出不合格的成績。

解題思路: 用malloc函數開闢一個動態自由區域,用來存5個學生的成績,會獲得這個動態域第一個字節的地址,它的基類型是void型。用一個基類型爲int的指針變量p來指向動態數組的各元素,並輸出它們的值。但必須先把malloc函數返回的void指針轉換爲整型指針,而後賦給p

經過malloc初始化5個學生的成績 二、 free(p); //釋放內存 printf(「p=%p\n」,p); //釋放內存之後,指針的值並不發生變化 printf(「%d\n」,p[2]); //釋放內存之後,若是再次引用指針,就會出現垃圾數值

所以,釋放內存之後,指針應該賦值爲空,(p=NULL)。

釋放內存以後,不能再次釋放內存

小總結:

內存不能夠反覆釋放,內存釋放以後不能夠引用不然會出現垃圾數據, 內存釋放之後,指針應該賦值爲空,就能夠規避再次引用,以及反覆釋放的問題。

三、內存泄露

若是沒有釋放內存,但記錄該塊內存的指針消亡了或者是指針的值發生了改變,這塊內存將永遠得不到回收,形成了內存泄漏

三十一 課後習題 植物大戰殭屍

一、遊戲的陽光值爲670.

三十二 深刻指針 迷途指針

迷途指針 定義一個指針p,經過malloc函數爲它分配內存 而後釋放內存free(p); //應該在此處讓p指向NULL,也就是p=NULL. p釋放了之後,仍然指向這片內存,就是迷途指針

三十三 指針代碼實踐

一、 記事本可以經過以下兩行代碼編譯,可是VS則不能經過編譯, 由於指針變量p沒有初始化。 二、 經過指針的方式交換兩個變量的值 三、 把a做爲一個實參傳遞給函數change,並不能改變實參a的值。 經過傳值的方式傳遞給change函數的形參,將會在棧區中開闢一段內存, (單向傳遞,只能接受)。 傳遞a的地址給changep函數,在函數中給形參從新賦值之後,實參的值發生改變。也不會開闢新的內存空間,(雙向傳遞,既接受了地址,也能經過地址改變變量)。 四、 定義一個函數 沒能實現交換兩個變量的值(經過傳值的方式,並沒能實現交換的功能) 傳入的是實參的地址和形參的地址並不相同,傳入以後,僅僅是在棧區新開闢了兩段內存,函數執行完後,並沒能把值傳遞給實參,傳值的方式是單向傳遞。 五、 經過傳遞地址的方式交換兩個實參變量的值。 這裏的形參pa,pb分別和實參的兩個參數一一對應指向同一塊內存, 改變了實參的值。(雙向傳遞) 六、若是建立指針沒有進行初始化就會編譯出錯。

建立指針t ,並無初始化t,而是經過間接訪問的方式把pa所指向的值付給了*t

相關文章
相關標籤/搜索