首頁 > 軟體

C語言深入講解指標與結構體的使用

2022-05-30 14:02:01

1 啥是指標

剛剛接觸指標的同學肯定會很懵逼,指標是啥啊?指南針哈哈,不和大家開玩笑,我們進行正題吧,指標是本質是就是地址,但我們要注意我們口頭上常說的指標並非指標,而是指標變數。

1.1指標與指標變數

指標:記憶體中一個最小單元的編號,也就是地址。

指標變數:是用來存放記憶體地址的變數。

我們可以看下面的這張圖。

為了唯一標識一塊記憶體空間,在C語言中就用指標來標記,就像我們的寢室的門牌號一樣,假設張三的寢室門排號是A602,A602就是地址也就是指標,為了讓張三的寢室被人,可以找到,我們我們肯定是要在系統是登記有怎麼個寢室,下次來張三寢室也就方便,而在C語言中,就用指標變數來存放我們的地址(通常用&地址操作符來取出地址在存放在指標變數中)

#include<stdio.h>
int main()
{
	int a = 0;
	int* p = &a;
	*p = 1;
	return 0;
}

從中我們可以看出,我們可以通過指標變數p解除參照(*),來找到a從而更改a的值。

從上面圖中我們知道在記憶體中的每一塊空間的大小都是一個位元組,那麼對一個32平臺的機器,就有32根地址線,地址線上能產生高電平(1)和低電平(0),這樣的話就能產生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總結

1指標本質是地址,指標變數是用來存放地址的。

2指標在32位元平臺的大小為,4個位元組,在62位平臺為8個位元組

2 指標和指標型別

指標的型別,其實,和變數的型別差不多,就是變數了型別多個*號

常見的指標型別

har *pc = NULL;

int *pi = NULL;

short *ps = NULL;

long *pl = NULL;

float *pf = NULL;

double *pd = NULL;

2.1指標+-整數

指標的+-整數其實反應的是指標跳過的位元組,決定了指標的步長。

#include<stdio.h>
int main()
{
	int arr[5] = { 1,2,3,4,5 };
	int* p = arr;
	printf("%dn", *p);
	printf("%dn", *(p + 1));
	printf("%dn", *(p + 2));
	return 0;
}

arr指的是首元素的地址,存放在指標變數p上,我們*p就可以找到陣列的第一給元素,那麼*(p+1)指的又是上面呢,其實他指的是跳過一個4個位元組,為什麼是4個位元組而不是一個位元組呢,這就跟指標變數的型別有關係了,因為p是int*s是4個位元組,如果是char*我們+1又會發生什麼呢?

這時我們觀察到列印了0,我們*(p+4)才早的陣列的第二個元素,這是因為陣列arr中的每個元素都是4個位元組的,而char*p型別的指標加1只能跳過1個位元組,這時候找的首地址就不對了。

3 野指標

概念: 野指標就是指標指向的位置是不可知的(隨機的、不正確的、沒有明確限制的)

3.1 野指標的成因

1指標未初始化

2指標越界存取

3指標指向的空間釋放

這裡雖然可以列印出6來,但這樣的存取是非法的,因為形參在出函數就會銷燬。

3.2 如何避免野指標的出現

1. 指標初始化

2. 小心指標越界

3. 指標指向空間釋放即使置NULL

4. 避免返回區域性變數的地址

5. 指標使用之前檢查有效性

其中我們可以養成一個習慣,當我們不知道給指標初始化何值時,我們可以初始化指標為NULL(0),在對指標賦值的時候在判斷一下,就可以一定程度上避免野指標。

4 二級指標

簡單的說就是存放一級指標的地址

圖中ppa便是二級指標變數,存的一級指標變數的地址。

5 指標陣列

存放指標的陣列,指標陣列本質是陣列。

其中的parr變是指標陣列,其中parr[10]等價於*(parr+10);

指標陣列可以模擬一個二維陣列

6 結構體

結構是一些值的集合,這些值稱為成員變數。結構的每個成員可以是不同型別的變數。

6.1 結構的宣告

struct tag

{

member-list;

}variable-list;

struct:是結構體型別的關鍵字

struct tag:是使用者定義的結構體型別

member-list:是結構體成員

variable-list:結構體型別變數

其中結構的成員可以是標量、陣列、指標,甚至是其他結構體。

6.2 結構體變數的定義和初始化

結構體變數的定義就是給結構體型別取一個變數。

結構體的初始化

6.3 結構體的存取

結構體變數成員用 .存取

結構體變數指標->存取

6.4 結構體傳參

傳參有二種,但對於結構體來說傳址呼叫是最好的,

函數傳參的時候,引數是需要壓棧的。 如果傳遞一個結構體物件的時候,結構體過大,引數壓棧的的系統開銷比較大,所以會導致效能的下降。

所以:結構體傳參的時候,要傳結構體的地址。

到此這篇關於C語言深入講解指標與結構體的使用的文章就介紹到這了,更多相關C語言指標與結構體內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com