對指針的學習總結

来源:http://www.cnblogs.com/weifeng727/archive/2016/06/26/5584151.html
-Advertisement-
Play Games

這是我對指針學習的歸納記載,如有疑問歡迎聯繫作者本人一起探討~ 尊重作者的勞動,轉載請記得註明來源:http://www.cnblogs.com/weifeng727/p/5584151.html ...


  1 /*----------------------------------------
  2           指針練習(精華)
  3 
  4     1)首先,要理解變數或數組的首地址,指的就是存放數據的RAM或ROM中地址號最小的那個位元組地址。
  5     2)指針前面的類型說明符,具有2重意義(既決定了對一級指針進行解引用時,將會操作的位元組數,以及對一級指針進行算術運算時,會跳轉的地址個數)。    
  6       ①決定了指針加一時,指針會跳轉多少個地址,
  7       例如:
  8               如果指針是
  9               char類型的,(指針+n) 指針會跳轉n*1個地址。
 10               int 類型的,(指針+n) 指針會跳轉n*2個地址。
 11               long類型的,(指針+n) 指針會跳轉n*4個地址。
 12               
 13       ②並且還決定了通過指針操作地址值時,實際上會返回多少個位元組的值,且地址號大的位元組先返回。 
 14       例如:    
 15               假設要操作指針的一次地址返回值,那麼如果指針是
 16               char類型的,返回1個位元組。
 17               int 類型的,返回2個位元組。
 18               long類型的, 返回4個位元組。
 19               
 20       數組前面的類型說明符,同樣具有2重意義,且跟上面的很相似。
 21       例如:
 22               #include"stdio.h"
 23               int c[]={0x1234,0x5678};
 24               void main()
 25               {
 26                 printf("%p %d\n",c,*c);            //數組是int類型意味著返回2個位元組
 27                 printf("%p %d\n",(c+1),*(c+1));  //實際上(c+1)與c是夾著一個地址,因為數組類型符號是int,如果數組類型是long,則夾著3地址
 28               }
 29       
 30       也就是要註意類型所占的位元組數,還有就是什麼時候該看數組類型符號或者指針類型符號。
 31     3)&叫取首地址符號,*叫解引用符號。
 32     4)數組名是指一個首地址,所以,point=a(point是一個指針,a是一個數組名), a的前面不需要加&符號。
 33       變數名指的是一個值,a[1]指的也是一個值,這些值包含著一個或多個位元組,在想要讓指針指向這些值的位元組的地址時,
 34       需要在變數名以及a的前面加上&符號,即意思是要讓指針賦值符號(=)右邊的東西是地址。
 35     5)數組或變數的數據是一個一個位元組的存放的,而且位元組的地址是呈現連續的,賦值的時候,從左到右看,
 36       越往右,位元組的地址號越大。因此,對於多位元組數據類型的數組而言,看起來有種“首尾相連”的效果,
 37       因為一個元素的最低位位元組其地址的加一地址對應的位元組,就是下一個元素的最高位位元組。
 38       
 39       簡單點來說就是低地址存放高位元組,這種現象稱為大端排列(常用單片機)。註意:有些時候則是低地址存放低位元組,這種現象稱為小端排列(ARM)。
 40       
 41     6)指針可分為:函數指針,數組指針(多維指針),變數指針,結構體指針。  又可分為:多級指針,多維指針。  地址可分為:多級地址,多維地址。
 42     7)只有字元數組的最後一個元素會緊接一個隱藏元素,該元素值為0,映射的字元為“\0”。
 43     8)數據指針型函數,也叫指針函數(即返回值是一個地址)。       
 44     9)char (*p)[2];   //聲明一個二維指針(也叫二維數組指針)
 45       分析方括弧([])對多維指針的操作時,要遵循一個原則:先明確指針的維數,再分析有多少組方括弧,方括弧裡面的數字是多少,由此得到地址是如何跳轉的;
 46                                                         然後根據方括弧的組數得知地址最終會發生多少次的解引用,如果解引用的次數少於地址的維數,
 47                                                         那麼最終得到的還是一個地址,也如果解引用的次數等於地址的維數,那麼得到是一個數據值。
 48                                                         每次對多維地址進行一次解引用後,地址的維數將會變小。
 49       一維數組名就是一個一級一維地址,二維數組名就是一個一級二維地址,多維數組名就是一個一級多維地址。每一個數組名都是一個地址。這些地址是固定的。
 50       一級多維指針的特點是:解引用的寫法很特殊;運算時地址的跳轉很特殊。
 51       探究代碼如下:
 52       int Array[2][3][2]={{{1,2},{3,4},{5,6}},{{7,8},{9,10},{11,12}}};  
 53 
 54       printf("%d\n", Array); 
 55       printf("%d\n", Array[1]);   //與上一行代碼相比,發生了 3*2*4=24個地址 的跳轉
 56       printf("%d\n", Array[1][1]);    //與上一行代碼相比,發生了 2*4=8個地址 的跳轉
 57 
 58       printf("%d\n",*(Array[1][1]));//對1維地址進行1次解引用,得到一個數據值,為9
 59 
 60       printf("%d\n",*(*(Array[1])));    //對2維地址進行2次解引用,得到一個數據值,為7
 61       printf("%d\n",*(Array[1]));        //對2維地址進行1次解引用,得到的是一個1維地址,且與Array[1]值一樣,但Array[1]是一個2維地址
 62     10) #include<stdio.h>  
 63         #include<stdlib.h>  
 64         int main()  
 65         {  
 66 
 67             //下麵是存在著非法讀寫的演示,雖然非法讀寫是可以實現,但是這隻能存在於同一個進程裡面,而且這種情況沒有什麼有利的實際意義
 68 
 69             int *p;    //int類型指針,操作4個位元組
 70             p=(int *)malloc(2);  //向堆區域存儲空間申請了2個位元組,但不進行初始化,calloc方式的申請會進行初始化
 71             if(p)  
 72                 printf("Memory Allocated at: %p\n",p);  
 73             else  
 74                 printf("Not Enough Memory!\n");
 75             printf("%x\n",*p);     //由於只申請了2個位元組,所以非法讀取了2個位元組
 76             *p=0x12345678;        //由於只申請了2個位元組,所以非法寫入了2個位元組
 77             printf("%x\n",*p);    //由於只申請了2個位元組,所以非法讀取了2個位元組     
 78             free(p);   //釋放堆中申請過的2個位元組,並且有可能把記憶體中的值也清0,這要取決於運行的內核
 79             //下麵是非法讀寫了4個位元組
 80             printf("%x\n",*p);    
 81             *p=0x87654321;
 82             printf("%x\n",*p);    
 83             return 0;  
 84         } 
 85     11)經探究發現,不同類型的指針指向的地址跟指針類型不一致時,有可能會報錯,也有可能只是警告而已
 86     12)unsigned char (*q)();  //聲明一個函數指針
 87        指針形式調用函數時不給定傳遞參數值的話,預設是傳遞-1   ,  指針調用函數的格式為:"(*指針名)(形參列表)" 或 "指針名(形參列表)"
 88     13)一級和多級指針的使用:
 89     int val=0x1122;
 90     char *p3=&val;
 91     char **p2=&p3;
 92 
 93     printf("%x\n", p3); 
 94     printf("%x\n", p3+1); //跳轉1個地址(因為p3是個一級指針而且類型修飾符為char)
 95 
 96     printf("%x\n", *(p3)); //操作1個位元組(因為p3是個一級指針而且類型修飾符為char)
 97     printf("%x\n", *(p3+1));//操作1個位元組(因為p3是個一級指針而且類型修飾符為char)
 98 
 99     printf("%x\n", (p2)); 
100     printf("%x\n", (p2+1)); //跳轉4個地址(因為記憶體中位元組所使用的地址長度為32位且指針p2是一個二級指針)
101 
102     printf("%x\n", *(p2)); //操作4個位元組(因為記憶體中位元組所使用的地址長度為32位且指針p2是一個二級指針)
103     14)對多級多維指針的探究:
104     //假設已經掌握對多級一維指針,和一級多維指針的使用
105 
106     unsigned char (**p)[3];
107     int Array3[10]={0x804a0e0,0x55667788,2,3,4,5,6,7,8,9};  //之所以第一個元素為0x804a0e0,是因為該值取的不當,下麵對(*(*p))進行解引用的時候,有可能在程式執行時導致內核塌陷,看起來好像是程式語法錯誤,也就是說要保證解引用的指針是在正確範圍內的
108     p=Array3;
109 
110     printf("%x\n", p);  //p是一個二級二維指針,指向一個二級二維地址
111     printf("%x\n", p+1);  //發生4個地址的跳轉(因為地址長度為4個位元組),因為(p+1)是一個二級二維地址,也就是此行語句輸出值比上一行語句大4
112 
113     printf("%x\n", *p);   //解引用得到4個位元組的值,因為p是一個二級二維指針。*p 為一級二維指針
114     printf("%x\n", (*p+1));  //跳轉3個位元組,因為 *p 屬於一級二維指針,也就是此行語句輸出值比上一行語句大3。因為一級指針地址的跳轉,是取決於維數,*p是一個一級二維指針,那麼跳轉數為:sizeof(unsigned char)*[3]=3
115     
116     printf("%x\n", *(*p));  //對一級二維指針(*p)進行解引用,得到一級一維指針*(*p),該行語句列印值等效於一級二維指針*p
117 
118     printf("%d\n", *(*(*p))); //對一級一維指針*(*p)進行解引用,得到1個位元組的值,值為0xe0也就是224,因為指針 p 的類型修飾符為char,而sizeof(unsigned char)=1
119 
120     printf("%d\n", *(*(*p))+1); //該行列印值比上一行大1,為225
121 
122     //總結:對多級多維指針進行解引用的時,每次解引用都會遵循先降級再降維,當級數沒降到1,那麼維數不起作用,也就是把指針當做多級一維指針來處理。
123     //        當已經是一級指針了後,維數起作用,當做一級多維指針或一級一維指針處理   
124     
125 
126 
127 ------------------------------------------*/

 

這是我對指針學習的歸納記載,如有疑問歡迎聯繫作者本人一起探討~

尊重作者的勞動,轉載請記得註明來源:http://www.cnblogs.com/weifeng727/p/5584151.html


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • HELLO WORLD! 今天第一次開立博客,專門記載學習編程語言中的點點滴滴。今日學習內容: 搭建vs code+ python3.5 "ide" 學習廖雪峰python教程-使用list和tuple 因為之前有pascal基礎,所以學起來不是很難理解,但是貴在堅持,自我激勵。昨天《墊底辣妹》給打 ...
  • 題目:輸入一個矩陣,按照從外向里以順時針的順序依次列印出每一個數字。 例如輸入以下矩陣: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 則依次列印出數字 1、2、3、4、8、12、16、15、14、13、9、5、6、7、11、10 ...
  • 列印基本類型 以下列印基本的數據類型, 如int, char, float等, 最後兩行是以八進位和十六進位列印數字10 windows gcc輸出: 設置輸出寬度 設置每個整數占10個位置, 預設為右對齊 如果數字的長度比設置的寬度大, 那麼會忽略我們設置的輸出寬度 windows gcc輸出: ...
  • 英文原文:Micro Benchmarking with JMH: Measure, don’t guess!翻譯地址:使用JMH進行微基準測試:不要猜,要測試!原文作者:Antonio翻譯作者:Hollis轉載請註明出處。 很多Java開發人員都知道把一個變數聲明為null有助於垃圾回收(譯者註:... ...
  • 今天在寫框架的時候想把SaeMySQL初始化之後作為全局變數使用。但是後來發現PHP中的全局變數和Java或者OC中的全局變數還是有較大區別的。下麵記錄一下php裡面的global的使用相關註意事項。1.有些場合需要全局變數的出現,如下例子: 上面的代碼的結果為:"myname is" 。而不是期望 ...
  • 【課前思考】 1. 什麼是對象?什麼是類?什麼是包?什麼是介面?什麼是內部類? 2. 面向對象編程的特性有哪三個?它們各自又有哪些特性? 3. 你知道java語言在面向對象編程方面有何獨特的特點嗎? 難點: 1. 理解方法重載和方法重寫,不要混淆了兩者的使用。 2. 類變數和類方法的使用。 3. 接 ...
  • 前言: 目前在研究易信公眾號,想給公眾號增加一個獲取個人交通違章的查詢菜單,通過點擊返回查詢數據。以下是實施過程。 一、首先,用火狐瀏覽器打開XX省交管網,分析頁面信息: 可以看到共有4種查詢種類,我只要查詢違章數據,所以分析第一個電子警察信息查詢就好了,用firebug分別查看車牌號碼、車輛識別碼 ...
  • 搭建輕量級Java Web框架快速搭建開發框架如何載入配置文件如何實現一個簡單的 IOC 容器如何載入指定的類如何初始化框架 *註解開發 目標:打造一個輕量級的 MVC 框架,Controller 是MVC的核心,類似於 SpringMVC。通過 Controller 註解來定義 Controlle ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...