學習筆記11-C語言-指針

什么是指針:

指針是一種特護的數據類型,使用它可以定義指針變量,指針變量存儲的是整型數據,代表內存的編號,通過這個編號可以訪問到對應內存。

為什么使用指針

1、函數與函數之間是相互獨立的,但是有些時候需要共享變量傳參是單向值傳遞全局變量容易命名沖突使用數組還需要傳遞長度函數的命名空間是相互獨立的,但是地址空間是同一個,所以指針可以解決這個問題
2、由于函數傳參是值傳遞(內存拷貝),對于字節數較多的變量,值傳遞的效率較低,如果傳遞的是變量的地址,只需要傳遞4|8字節,根據32|64位決定
3、堆內存無法取名,它不像stack、bss、data讓變量名與內存建立聯系,只能使用指針來記錄堆內存的地址編號從而使用該堆內存。

如何使用指針:

定義: 類型* 變量名_p;   int* p;1、由于指針變量與普通變量的用法上有很大的區別,為了以示區分,建議在變量名后面加上_p2、指針的類型表示該指針變量存儲的是什么類型變量的地址,指針的類型決定了可以通過指針變量訪問的字節數3、一個*只能定義一個指針變量int a1,a2,a3;int* p1,p2,p3;//p1指針,p2,p3是intint *p1,*p2,*p3;//p1,p2,p3都是指針變量4、指針變量與普通變量一樣的是隨機的默認值,一般初始化為NULL(空值)。賦值(引用):變量名_p = 地址;//地址必須是有權限而且有意義的內存地址指向棧內存:int num;int* p = NULL;p = #指向堆內存:int* p = NULL;p = malloc(4);解引用: *p通過指針變量中記錄的內存編號來訪問對應的內存,該過程可能產生段錯誤。但是原因是因為存儲了非法的內存編號注意:訪問的字節數是由指針變量的類型決定的。*p=1000;

練習1:實現一個變量交換函數,調用它對一個數組進行排序

#include<stdio.h>void swap(int* p1,int* p2)
{int change=0;change=*p1;*p1=*p2;*p2=change;
}int main(int argc,const char* argv[])
{int num[10]={8,0,5,6,9,3,2,7,4,1};for(int i=0;i<9;i++){for(int j=i+1;j<10;j++){if(num[i]<=num[j])swap(&num[i],&num[j]);}}for(int i=0;i<10;i++){printf("%d",num[i]);}}

練習2:實現一個函數,計算兩個整數的最大公約數、最小公倍數,最大公約數用return返回,最小公倍數使用指針返回
注意:想要獲取多個返回值,可以借助指針返回

#include<stdio.h>int big(int n1,int n2)
{int a=n1>n2?n1:n2,b=n1>n2?n2:n1,c=1;while(c){c=a%b;a=b;b=c;}return a;
}int small(int n1,int n2)
{int a=n1>n2?n1:n2,b=n1>n2?n2:n1;int i=1;while(a*i%b!=0){i++;}return a*i;
}int max_min(int n1,int n2,int* p)
{*p=small(n1,n2);return big(n1,n2);
}int main(int argc,const char* argv[])
{int max=0,min=0;int num1,num2;printf("請輸入兩個數:");scanf("%d%d",&num1,&num2);max=max_min(num1,num2,&min);printf("%d %d\n",max,min);
}

使用指針需要注意的問題:

空指針:值是NULL的指針變量都是空指針,如果對空指針進行解引用產生段錯誤。一般NULL也是一種錯誤標志,如果一個函數返回值是指針類型時,當函數執行出錯可以返回NULL表示該函數執行出錯。注意:NULL在絕大多數的系統中都是0,在個別系統上是1if(NULL==p)if(!p)如何避免空指針帶來的段錯誤:使用來歷不明的指針之前先做判斷是不是空指針。1、當函數的參數是指針時,別人傳給你的就有可能使空指針2、從函數獲取返回值使,也可能獲取到的使空指針野指針:指針指向不確定的內存的指針野指針解引用的危害:1、臟數據2、段錯誤3、一切正常野指針的危害比空指針更嚴重,因為野指針無法判斷出來,而且可能是隱藏性的錯誤,短時間內不暴露所有的野指針都是人為制造的,如和避免產生野指針:1、定義指針是一定要初始化2、函數不返回局部變量地址3、指針指向的內存被釋放后,指針變量立即置空=NULL    

指針的運算:

指針變量里存儲的是整型,理論上整型數據能使用的運算符她都能用,但絕大多數都是無意義的。指針+n:指針+指針類型的寬度*n(int就是 4)   前進了n個元素
指針-n:指針-指針類型的寬度*n               后退了n個元素
指針-指針:(指針-指針)/指針類型寬度        計算相隔了多少個這種元素

指針與const:

const int* p;
當我們為了提高傳參效率而使用指針時,傳參的效率雖然提高了,但是變量也有被修改的風險,這種寫法就可以保護指針變量指向的內存不被修改int const *p;   效果同上
int* const p;   保護指針變量不被修改const int* const p;   保護指針變量和指針變量指向的內存不被修改
int const * const p;   效果同上const保護誰按照就近原則

指針數組與數組指針:

指針數組:由指針組成的數組,它的成員都是指針變量類型* arr[長度];數組指針:專門指向數組的指針類型 (*arr)[長度];

指針與數組名:

數組名是一種特殊的指針,它是常量,不能改變它的值,它與數組內存是映射關系,沒有自己的內存空間
數組名 == &數組名 == &數組名[0]指針變量它由自己的存儲空間,如果它存儲的是數組的首地址,指針可以當作數組使用數組名[i] == *(數組名+i)*(指針名+i) == 指針名[i]注意:數組作為函數的參數時蛻變成了指針,所以長度丟失了。

二級指針:

二級指針就是指向指針的指針。里面存儲是指針變量的地址。
定義:類型** 變量名_pp;
賦值:變量名_pp = 地址;變量名_pp = &指針變量;
解引用:*變量名_pp <=> 指針變量 p**變量名_pp <=> *指針變量 *p注意:當函數之間需要共享指針變量是必須傳遞二級指針

函數指針:

函數返回值 (*函數指針名p)(參數列表);函數名就是一個地址(整數),它代表了函數在代碼段中的位置可以通過函數指針,把函數作為參數傳遞給另一個函數,這叫回調函數指針就是指向函數的指針,里面存儲的就是該函數在代碼段中的位置。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/443456.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/443456.shtml
英文地址,請注明出處:http://en.pswp.cn/news/443456.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

學習筆記12-C語言-堆內存、字符串

什么是堆內存&#xff1a; 是進程中的一個內存段&#xff08;text\data\bss\heap\stack&#xff09;&#xff0c;由程序猿手動控制。 特點是足夠大&#xff0c;缺點是使用麻煩為什么要使用堆內存&#xff1a; 1、隨著程序的復雜&#xff0c;數據會越來越多。 2、其他的內存段…

學習筆記13-C語言-字符串函數、緩沖區

字符串的常用函數: #include<string.h> size_t strlen(const char* s); 功能&#xff1a;計算字符串長度&#xff0c;但是結果不包括\0 返回值&#xff1a;返回字符串中字符的個數size_t str_len(const char* str) {assert(NULL ! str);const char* tmp str;while(*tmp…

Oracle數據庫里面查詢字符串類型的字段不為空和為空的SQL語句:

摘要&#xff1a;近期項目中&#xff0c;在做高級查詢的時候有個條件是根據選擇的字段&#xff0c;然后再選擇字段的值為空和不為空做查詢&#xff0c;在寫SQL語句的時候費了很長時間&#xff0c;現在記錄一下&#xff0c;方便日后查看&#xff1a; 一&#xff1a;查詢字符串類…

學習筆記14-C語言-小項目-通訊錄

通訊錄&#xff1a; 要求&#xff1a; 姓名&#xff0c;性別、電話&#xff0c;最多儲存50個聯系人 功能&#xff1a;1、添加聯系人2、按名字刪除聯系人3、按姓名修改聯系人信息4、查找聯系人&#xff0c;可通過電話&#xff0c;名字查找&#xff0c;支持模糊查找5、顯示所有聯…

學習筆記15-C語言-預處理指令、條件編譯、頭文件

預處理指令&#xff1a; 程序猿編寫的代碼不是標準C代碼&#xff0c;并不能被真正的編譯器索編譯&#xff0c;需要一段程序把代碼翻譯一下。 翻譯的過程叫做預處理&#xff0c;被翻譯的代碼叫做預處理指令&#xff0c;以#開頭的都是預處理指令查看預處理的過程&#xff1a;gcc…

學習筆記16-C語言-小項目-使用Makefile完成2048

Makefile: Makefile是一系列編譯指令組成的可執行文本&#xff0c;也叫做編譯腳本。 在終端執行make命令會自動執行Makefile腳本中的編譯命令&#xff0c; 而且它還可以根據文件的最后修改時間來判斷哪些文件是否需要重新編譯、哪些文件不需要重新編譯&#xff0c;從而大大提高…

學習筆記17-C語言-結構、聯合、枚舉

結構&#xff1a; struct 結構是由程序猿自己設計的一種數據類型&#xff0c;用于描述一個事務的各項數據&#xff0c;由若干個不同的基礎數據類型組成。設計結構&#xff1a;struct 結構體名{類型 成員名&#xff1b;...}&#xff1b;定義結構體變量struct 結構體名 變量名&a…

Maven 3.0.5 安裝和配置:

摘要&#xff1a;現在的Web項目越來越多的都用maven管理了&#xff0c;所以我也抽時間學習學習&#xff0c;為了趕上時代&#xff01; 一&#xff1a;首先到maven官網&#xff1a;http://maven.apache.org/&#xff0c;然后選擇相應的版本下載&#xff0c;我這里下載的是maven…

學習筆記18-C語言-文件

文件的分類&#xff1a; 文本文件&#xff1a; 存儲的是ASCII碼值的二進制 二進制文件&#xff1a; 存儲的是數據的補碼文件IO&#xff1a; FILE *fopen(const char *path, const char *mode); 功能&#xff1a;打開或者創建文件 path&#xff1a;文件的路徑 mode&#x…

使用INNER JOIN ON 多表關聯查詢,獲取指定用戶下指定權限的資源SQL:

摘要&#xff1a;最近在看一個開源框架&#xff0c;其中用戶&#xff0c;角色&#xff0c;資源&#xff0c;這塊我感覺比較重要&#xff0c;所以就自己也模仿著寫了下&#xff0c;其中在獲取指定用戶下的權限資源的時候遇到問題了&#xff0c;開始時&#xff0c;我首先想到的方…

Maven學習記錄之maven基本操作命令,maven本地工廠的創建,maven骨架的生成,以及在eclipse中創建maven工程:...

摘要&#xff1a;今天又學習了一下maven&#xff0c;之前是下載并安裝和配置好了maven的環境&#xff0c;今天主要學習的內容包括&#xff1a;maven本地工廠的創建&#xff0c;maven骨架的生成命令&#xff0c;maven在dos下創建maven工程&#xff0c;以及在eclipse中創建mavne工…

Oracle中通過游標執行帶參數的存儲過程實現解析CLOB字段內的xml字符串:

摘要&#xff1a;近來之前的項目數據出現了問題&#xff0c;原因是由于之前在設計數據庫的時候把時間字段設置成了字符串格式&#xff0c;所以給后期的數據操作帶來了很大的麻煩&#xff0c;這里提醒一下各位程序猿&#xff0c;以后在開發項目的時候時間字段一定要是時間字段&a…

Eclipse中使用Checkstyle,checkstyle插件檢查java代碼的自定義配置文件:

摘要&#xff1a;近來項目組在搞代碼檢查&#xff0c;所以領導讓把checkstyle這個插件搞明白&#xff0c;現在我把我們寫的自定義的checkstyle.xml文件記錄一下&#xff0c;以便大家可以一起使用&#xff1a; 一&#xff1a;要使用checkstyle插件在eclipse中檢查java代碼&…

Linux 下安裝 jdk-7u75-linux-x64.gz,jdk1.7.0_75,jdk1.7步驟:

摘要&#xff1a;近來又用到了Linux系統&#xff0c;所以就又新裝了一個虛擬機和CentOS 6.4來用&#xff0c;搞開發的程序猿們可能都知道&#xff0c;在現在的很多企業中&#xff0c;生產環境大多都是Linux服務器&#xff0c;并且用的比較多的大都是CentOS&#xff0c;Red hat系…

Win7+VMware10.0+CentOS 6.4+Tomcat,Win7訪問不了CentOS6.4上的Tomcat

摘要&#xff1a;今天在linux下安裝Tomcat后&#xff0c;在虛擬機本地通過:http://localhost:8080/可以訪問安裝好的Tomcat服務器&#xff0c;但是在本機就不能訪問&#xff0c;前提是在本機下可以ping的通虛擬機的IP地址的&#xff0c;最后經過Google&#xff0c;發現說可能是…

Linux下配置OpenLDAP服務記錄

摘要&#xff1a;最近部門需要整合所有的系統&#xff0c;所以領導說要通過OpenLdap數據庫來實現對所有系統的統一管理&#xff0c;所以需要在服務器上配置一下LDAP服務&#xff0c;我們這里選擇的是OpenLdap服務&#xff0c;我在網上搜索了很多&#xff0c;開始都沒有配置成功…

Linux下配置CollabNet Subversion Edge

摘要&#xff1a;最近一直都在搞一下管理員的工作&#xff0c;今天又搞了svn的管理工具CollabNetSubversionEdge&#xff0c;網上也有很多例子&#xff0c;但是很多都是可以訪問到web界面&#xff0c;但是不能啟動版本庫的服務&#xff0c;所以我經過多次嘗試&#xff0c;終于解…

養成讓自己進步的10個習慣

養成讓自己進步的10個習慣 1.永遠不說不可能。"辦法總比問題多" 2.凡事第一反應找方法&#xff0c;不是找借口。"不要推卸責任" 3.養成記錄習慣&#xff0c;不太依賴腦袋。"好記性不如爛筆頭" 4.每天出門照鏡子&#xff0c;給自己自信的微笑。&…

Oracle存儲過程中使用游標來批量解析CLOB字段里面的xml字符串:

摘要&#xff1a;之前在項目中使用到了Oracle數據庫中通過觸發器去調用存儲過程執行數據解析并Update到對應的數據表中&#xff0c;但是&#xff0c;經過一段時間的測試使用發現&#xff0c;如果job那天停掉了&#xff0c;然后你再重新新建job的話&#xff0c;這時候可能會有很…

Maven配置nexus

摘要&#xff1a;近來一直在搭建maven結構的開發框架&#xff0c;其中這個過程中用到了nexus私服&#xff0c;這里我把我經過查詢總結的最終的方式記錄一下&#xff0c;以便后面忘記了&#xff1a; 一&#xff1a;nexus私服的安裝(略) 二&#xff1a;倉庫的講解如下圖: 1、ho…