網(wǎng)站首頁 編程語言 正文
1 啥是指針
剛剛接觸指針的同學(xué)肯定會很懵逼,指針是啥?。恐改厢樄?,不和大家開玩笑,我們進行正題吧,指針是本質(zhì)是就是地址,但我們要注意我們口頭上常說的指針并非指針,而是指針變量。
1.1指針與指針變量
指針:內(nèi)存中一個最小單元的編號,也就是地址。
指針變量:是用來存放內(nèi)存地址的變量。
我們可以看下面的這張圖。
為了唯一標(biāo)識一塊內(nèi)存空間,在C語言中就用指針來標(biāo)記,就像我們的寢室的門牌號一樣,假設(shè)張三的寢室門排號是A602,A602就是地址也就是指針,為了讓張三的寢室被人,可以找到,我們我們肯定是要在系統(tǒng)是登記有怎么個寢室,下次來張三寢室也就方便,而在C語言中,就用指針變量來存放我們的地址(通常用&地址操作符來取出地址在存放在指針變量中)
#include<stdio.h>
int main()
{
int a = 0;
int* p = &a;
*p = 1;
return 0;
}
從中我們可以看出,我們可以通過指針變量p解引用(*),來找到a從而更改a的值。
從上面圖中我們知道在內(nèi)存中的每一塊空間的大小都是一個字節(jié),那么對一個32平臺的機器,就有32根地址線,地址線上能產(chǎn)生高電平(1)和低電平(0),這樣的話就能產(chǎn)生2的32次方個地址。
2的32次方個地址
2^32Byte == 2^32/1024KB == 2^32/1024/1024MB==2^32/1024/1024/1024GB == 4GB),4G的空閑進行編址
對于62位平臺
便有2的62地址
2^64Byte == 2^64/1024KB == 2^64/1024/1024MB==2^64/1024/1024/1024GB ==17,179,869,184GB這樣我們可以編碼的空間就會打的多。
1.2總結(jié)
1指針本質(zhì)是地址,指針變量是用來存放地址的。
2指針在32位平臺的大小為,4個字節(jié),在62位平臺為8個字節(jié)
2 指針和指針類型
指針的類型,其實,和變量的類型差不多,就是變量了類型多個*號
常見的指針類型
har *pc = NULL;
int *pi = NULL;
short *ps = NULL;
long *pl = NULL;
float *pf = NULL;
double *pd = NULL;
2.1指針+-整數(shù)
指針的+-整數(shù)其實反應(yīng)的是指針跳過的字節(jié),決定了指針的步長。
#include<stdio.h>
int main()
{
int arr[5] = { 1,2,3,4,5 };
int* p = arr;
printf("%d\n", *p);
printf("%d\n", *(p + 1));
printf("%d\n", *(p + 2));
return 0;
}
arr指的是首元素的地址,存放在指針變量p上,我們*p就可以找到數(shù)組的第一給元素,那么*(p+1)指的又是上面呢,其實他指的是跳過一個4個字節(jié),為什么是4個字節(jié)而不是一個字節(jié)呢,這就跟指針變量的類型有關(guān)系了,因為p是int*s是4個字節(jié),如果是char*我們+1又會發(fā)生什么呢?
這時我們觀察到打印了0,我們*(p+4)才早的數(shù)組的第二個元素,這是因為數(shù)組arr中的每個元素都是4個字節(jié)的,而char*p類型的指針加1只能跳過1個字節(jié),這時候找的首地址就不對了。
3 野指針
概念: 野指針就是指針指向的位置是不可知的(隨機的、不正確的、沒有明確限制的)
3.1 野指針的成因
1指針未初始化
2指針越界訪問
3指針指向的空間釋放
這里雖然可以打印出6來,但這樣的訪問是非法的,因為形參在出函數(shù)就會銷毀。
3.2 如何避免野指針的出現(xiàn)
1. 指針初始化
2. 小心指針越界
3. 指針指向空間釋放即使置NULL
4. 避免返回局部變量的地址
5. 指針使用之前檢查有效性
其中我們可以養(yǎng)成一個習(xí)慣,當(dāng)我們不知道給指針初始化何值時,我們可以初始化指針為NULL(0),在對指針賦值的時候在判斷一下,就可以一定程度上避免野指針。
4 二級指針
簡單的說就是存放一級指針的地址
圖中ppa便是二級指針變量,存的一級指針變量的地址。
5 指針數(shù)組
存放指針的數(shù)組,指針數(shù)組本質(zhì)是數(shù)組。
其中的parr變是指針數(shù)組,其中parr[10]等價于*(parr+10);
指針數(shù)組可以模擬一個二維數(shù)組
6 結(jié)構(gòu)體
結(jié)構(gòu)是一些值的集合,這些值稱為成員變量。結(jié)構(gòu)的每個成員可以是不同類型的變量。
6.1 結(jié)構(gòu)的聲明
struct tag
{
member-list;
}variable-list;
struct:是結(jié)構(gòu)體類型的關(guān)鍵字
struct tag:是用戶定義的結(jié)構(gòu)體類型
member-list:是結(jié)構(gòu)體成員
variable-list:結(jié)構(gòu)體類型變量
其中結(jié)構(gòu)的成員可以是標(biāo)量、數(shù)組、指針,甚至是其他結(jié)構(gòu)體。
6.2 結(jié)構(gòu)體變量的定義和初始化
結(jié)構(gòu)體變量的定義就是給結(jié)構(gòu)體類型取一個變量。
結(jié)構(gòu)體的初始化
6.3 結(jié)構(gòu)體的訪問
結(jié)構(gòu)體變量成員用 .訪問
結(jié)構(gòu)體變量指針->訪問
6.4 結(jié)構(gòu)體傳參
傳參有二種,但對于結(jié)構(gòu)體來說傳址調(diào)用是最好的,
函數(shù)傳參的時候,參數(shù)是需要壓棧的。 如果傳遞一個結(jié)構(gòu)體對象的時候,結(jié)構(gòu)體過大,參數(shù)壓棧的的系統(tǒng)開銷比較大,所以會導(dǎo)致性能的下降。
所以:結(jié)構(gòu)體傳參的時候,要傳結(jié)構(gòu)體的地址。
原文鏈接:https://blog.csdn.net/qq_61552595/article/details/124754011
相關(guān)推薦
- 2022-07-16 SpringMVC基礎(chǔ)工作原理以及實例
- 2022-08-05 react+react-beautiful-dnd實現(xiàn)代辦事項思路詳解_React
- 2022-03-29 python實現(xiàn)k-means算法_python
- 2022-02-19 使用.Net?Core實現(xiàn)的一個圖形驗證碼功能_實用技巧
- 2022-04-20 python數(shù)據(jù)類型中的字符串你了解多少_python
- 2022-09-26 Shell(希爾)排序算法詳解之C語言版
- 2022-06-25 說說react中引入css的方式有哪些并區(qū)別在哪_React
- 2022-12-04 關(guān)于SQL查詢語句關(guān)鍵字方法_MsSql
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支