網站首頁 編程語言 正文
C語言的精華就是熟練的對指針進行運用
????????指針就是就是指向變量的地址,指針變量中存儲著地址,而指針本身也會被分配一片內存空間進行其地址的存儲。在32os下其所占字節為4,也就是32位,而64os下所占字節為8,也就是64位。熟練的運用指針對地址進行操作可以解決許多問題。
指針的定義
????????定義指針變量的格式為:存儲類型 ??數據類型 * ?指針變量名。存儲類型:指針變量名在內存空間中開辟的位置;數據類型:指針所指向的數據類型;數據類型*:指針的數據類型;指針變量名:分配連續空間的名字。指針就是內存地址,指針變量中存儲的就是地址,可以通過對地址進行操作實現地址中值發生改變。同時指針變量也可以進行賦值,改變其指針的指向。
取值符和取址符
????????*在C語言中有許多的用途,可以作為運算符參與運算,在定義指針的時候作為標識符,在linux下的命令窗口中作為通配符進行使用,同時還可以作為取址符,如:
?????????指針變量p中存儲的是a的地址,而利用取值符對p取*后,就可以得到對應地址中的值,p指向的是a的地址,所以取值后顯示的是變量a的值。利用取址符對a進行&后,就得到了a的地址。也就是p=&a,兩邊同時取*后得到*p=a。
案例
1、試著寫出指針數組中四個指針元素的值
int main()
{
char *str[4] = {"welcome","to"," I ew","beijing"};
char **p = str+1;
str[0] = (*p++)+1;
str[1]= *(p+1); .
str[2]= p[1]+3; .
str[3] = p[0] + (str[2]- str[1]);
}
?str[0] = (*p++)+1;
????????數組名str等價于數組首元素的地址,而str+1表示數組中第二個元素的地址&str[1],因此指針p指向數組str中的第二個元素str[1],而str[1]本身也是指針,指向字符串“to”的首字符t,因此指針p是一個指向指針的指針。*p指向字符串“to”的首字符t。此外 *p++ 中的 *p沒有括號并且是后++,因此賦值語句相當于執行了str[0] = *p + 1后再執行p++,而 *p+1指向字符串“to”的第二個字符o,因此str[0]指向了字符o,p++后p指向指針數租str的第三個元素str[2]。
str[1] = * (p + 1);
str[2] = p[1] + 3;
????????此時,p指向str[2],p + 1指向str[3],也就是p + 1 = &str[3],解引用可得*(p+1)= str[3],因此str[1] = str[3]。由于str[3]指向字符串“Beijing”的首字母B,因此str[1]也指向同樣的位置。在分析str[2]時,首先應該明確p[1]等價于*(p+1),這是訪問數組元素的兩種方式。根據對str[1]的分析可知,*(p+1)指向字符串“Beijing”的首字符B,也就是p[1]指向字符串“Beijing”的首字符B,p[1]+3就指向字符串“Beijing”的第四個字符j,因此str[2]就指向字符串“Beijing”的第四個字符j。
str[3] = p[0] + (str[2] - str[1]);
????????表達式str[2]-str[1]表示兩個指針之間元素的個數,str[2]指向字符串“Beijing”的第四個字符j,而str[1]指向字符串“Beijing”的首字符B,相差3個字符,因此str[2]-str[1]=3。此外,p[0]等價于*(p+0),也就是*p,而 *p=str[2],因此p[0]同樣指向字符串“Beijing”的第4個字符j,而p[0]+3就指向字符串“Beijing”的第7個字符g。
指針可以和許多東西進行結合,如一維數組,二維數組,函數 。
指針對數組的一些操作
指針操作 |
數組操作 |
說明 |
array |
&array[0] |
數組首地址 |
*array |
array[0] |
數組的首元素 |
array + i |
&array[i] |
數組第i個元素的地址 |
*(array + i) |
array[i] |
數組的第i個元素 |
*array+ b |
array[0] + b |
數組首元素的值加b |
*(array+i)+b |
array[i] + b |
數組第i個元素的值加b |
*array++ (當前指向第i個元素) |
array[i++] |
先取得第i個元素的值,i再加1 |
*++array(當前指向第i個元素) |
array[++i] |
先將i加1,再取得第i個元素的值 |
*array--(當前指向第i個元素) |
array[i--] |
先取得第i個元素的值,i再減1 |
*--array(當前指向第i個元素) |
array[--i] |
先將i減1,再取得第i個元素的值 |
子函數和指針的結合
????????利用函數可以對功能進行封裝,實現模塊化。而大部分函數需要進行輸入參數的傳遞,這就涉及到實參和形參。通過將值傳入的方式將參數進行輸入的方式為形參,在子函數執行完成后其空間就會被釋放。這種傳遞方式就相當于把傳入的值進行就拷貝,無論在子函數里面怎么進行操作,都不會引起主函數參數發生改變。
????????如圖,銷毀順序表子函數,想要通過在函數內對函數外申請的空間進行釋放的話就要將指向順序表首地址的地址傳入函數內。順序表首地址為一級指針,傳入指針的地址,那么就要定義二級指針進行接收。
????????假如光傳入指針變量的話,就只是一種拷貝,在函數體內又定義了一個指針指向順序表,這樣同時有兩個指針指向順序表。函數體內空間當然可以釋放空間和指針置空。但是主函數的指針在空間完成釋放后失去了指向,本來好好地指向順序表的首地址,但是這片空間沒了,那指向誰呢?這就成了野指針。野指針是非常危險的,它不像空指針一樣,可以被判斷,它指向隨機,所以要盡量避免野指針的出現。
????????所以,參數傳入的是順序表首地址的地址,也就是二級指針,二級指針存的是一級指針的地址,通過取值符*得到順序表的首地址,對首地址進行操作,就實現了對主函數內的指針進行操作,從而引起實參的改變。這樣在函數體內部操作的指針與主函數內指針為同一個。
原文鏈接:https://blog.csdn.net/qq_64407987/article/details/126335239
- 上一篇:C語言排序算法實現
- 下一篇:棧(Stack)和隊列(Queue)的基本操作
相關推薦
- 2022-12-15 Golang控制協程執行順序方法詳解_Golang
- 2023-04-24 numpy?產生隨機數的幾種方法_python
- 2022-06-13 Python自動化辦公之圖片轉PDF的實現_python
- 2022-03-26 C++?Primer學習記錄之變量_C 語言
- 2023-11-14 樹莓派上如何安裝anaconda/miniconda環境配置
- 2023-07-27 el-select下拉框處理分頁數據,觸底加載更多
- 2022-05-25 yarn : 無法加載文件
- 2022-07-08 C#跨PC遠程調用程序并顯示UI界面_C#教程
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支