真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

初階指針詳解?-創(chuàng)新互聯(lián)

目錄
  • 1.內(nèi)存和地址
  • 2.指針變量的大小
  • 3.指針類型的意義
    • 意義1:指針訪問權(quán)限的大小
    • 意義2:指針類型決定指針的步長
  • 4.野指針
    • 野指針成因
    • 如何規(guī)避野指針
  • 5.指針的運算
    • 指針加減整數(shù)
    • 指針減指針
    • 指針的比較運算
  • 6.指針與數(shù)組的關(guān)系
  • 7.二級指針

10年積累的做網(wǎng)站、成都網(wǎng)站制作經(jīng)驗,可以快速應(yīng)對客戶對網(wǎng)站的新想法和需求。提供各種問題對應(yīng)的解決方案。讓選擇我們的客戶得到更好、更有力的網(wǎng)絡(luò)服務(wù)。我雖然不認識你,你也不認識我。但先網(wǎng)站制作后付款的網(wǎng)站建設(shè)流程,更有恩施土家免費網(wǎng)站建設(shè)讓你可以放心的選擇與我們合作。1.內(nèi)存和地址

在這里插入圖片描述

  • 內(nèi)存是電腦上特別重要的存儲器,計算機中程序的運行都是在內(nèi)存中進行的
  • 所以為了有效的使用內(nèi)存,就把內(nèi)存劃分成一個個小塊,這每一個小塊被稱為內(nèi)存單元,每個內(nèi)存單元的大小是1個字節(jié)
  • 為了能夠有效的訪問到內(nèi)存的每個單元,就給內(nèi)存單元進行了編號,這些編號被稱為該內(nèi)存單元的地址,地址在C語言中也被稱為指針,所以以后就可以通過地址找到對應(yīng)的內(nèi)存單元

接下來創(chuàng)建一個變量aint a = 4,int類型占四個字節(jié),所以a在內(nèi)存中占4個內(nèi)存單元:
請?zhí)砑訄D片描述
可以用&a進行取地址:&a,a是一個整形變量,占用4個字節(jié),每個字節(jié)都有自己的地址,這里取出的地址是第一個字節(jié)的地址(較小的地址)

所以這里&a取出值的是0x0012ff44


2.指針變量的大小

通過一下代碼就能得出指針變量的大小

#includeint main()
{printf("%d\n", sizeof(char *));
  printf("%d\n", sizeof(short *));
  printf("%d\n", sizeof(int *));
  printf("%d\n", sizeof(double *));
  return 0;
}

結(jié)論:指針大小在32位平臺是4個字節(jié),64位平臺是8個字節(jié)
以上結(jié)論是根據(jù)程序結(jié)果得到的,接下來我們也可以通過物理層面去得到指針變量大?。?/p>

對于32位機器,它有著32根地址線,每跟線在尋址的時候會產(chǎn)生高電壓和低電壓也就是1或者0,有著32根地址線,也就是地址有著32歌比特位,1字節(jié)等于8比特,所以32位機器中地址占4個字節(jié)
這里我們可以繼續(xù)算下去:32根地址線,就有2的32次方個地址,2^32Byte == 2^32/1024KB ==2^32/1024/1024MB==2^32/1024/1024/1024GB == 4GB,所以在32位機器中,可以給4G的空間進行編址。

這里我們就明白:

  • 在32位的機器上,地址是32個0或者1組成二進制序列,那地址就得用4個字節(jié)的空間來存儲,所以一個指針變量的大小就應(yīng)該是4個字節(jié)。
  • 那如果在64位機器上,如果有64個地址線,那一個指針變量的大小是8個字節(jié),才能存放一個地址。

總結(jié):

  • 指針變量是用來存放地址的,地址是唯一標示一個內(nèi)存單元的
  • 指針的大小在32位平臺是4個字節(jié),在64位平臺是8個字節(jié)

3.指針類型的意義

指針有許多類型,如:int*,short*,char*,float*……
但是從前面得知指針的類型都是4或8字節(jié)大小,它們不會存在像如intchar不同類型有著不同占用空間的問題,既然指針類型大小一樣,那么為什么不把指針設(shè)置成一個同一類型的指針并且可以接收不同的類型變量的地址呢?不同的指針類型都有什么意義呢?

意義1:指針訪問權(quán)限的大小

首先看一下代碼:

#includeint main()
{int a = 0x11223344;
	int* pa = &a;
	*pa = 0;
	return 0;
}

調(diào)試后進入內(nèi)存窗口,找到a的地址后可以看見在內(nèi)存中a中的存儲的值為:44332211,這樣“倒著存放”的原因是在Visual studio這個IDE中采取小端存儲,如不懂大小端存儲,👉可點擊跳轉(zhuǎn)
在這里插入圖片描述
然后繼續(xù)運行下一行代碼,會發(fā)現(xiàn)*pa = 0使內(nèi)存中4個字節(jié)內(nèi)容變?yōu)?
在這里插入圖片描述

接著再看一個代碼:

#includeint main()
{int a = 0x11223344;
	char* pa = &a;
	*pa = 0;
	return 0;

這個代碼與上面代碼不同的一點是這次pa指針變量是char類型的,上一個代碼中的類型為int類型的
還是調(diào)試后進入內(nèi)存窗口,找到a的地址后可以看見在內(nèi)存中a中的存儲的值為:44332211
在這里插入圖片描述

接著運行,會發(fā)現(xiàn),內(nèi)存中只有44變?yōu)榱?code>00,也就是只有一個字節(jié)的內(nèi)容發(fā)生了改變
在這里插入圖片描述

這兩個代碼比較得出結(jié)論:

  • 指針類型決定了,指針進行解引用操作的時候,一次性訪問幾個字節(jié),訪問權(quán)限的大小
  • int*類型的解引用會對4個字節(jié)內(nèi)容進行操作
  • char*類型的解引用會對1個字節(jié)內(nèi)容進行操作
  • float*類型的解引用會對4個字節(jié)內(nèi)容進行操作
  • double類型的解引用會對8個字節(jié)內(nèi)容進行操作

所以,我們可以通過不同的指針變量按需求對不同字節(jié)大小內(nèi)容進行操作


意義2:指針類型決定指針的步長

觀看一下代碼:

int main()
{int a = 0x11223344;
	int* pa = &a;
	char* pc = &a;

	printf("%p\n", pa);
	printf("%p\n", pa+1);

	printf("%p\n", pc);
	printf("%p\n", pc+1);

	return 0;
}

得出結(jié)果:
在這里插入圖片描述
可以看出,前兩個地址大小差4,后兩個地址大小差2
在這里插入圖片描述
pa的類型為int*,pa+1的地址增加了4,pc的類型為char*,pc+1的地址增加了1

得出結(jié)論:

  • 指針類型決定指針的步長(指針+1到底跳過幾個字節(jié))
  • 字符指針+1,跳過1個字節(jié)
  • 整型指針+1,跳過4個字節(jié)指針初階指針初階

4.野指針

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

野指針成因
  1. 指針未初始化
#includeint main()
{int *p;
	*p = 20;
	return 0;
}

這里的指針p在定義的時候沒有初始化,默認為隨機值,也就是指針指向位置不可知。

以隨機值為地址,解引用時需要找到那個地址處,是很危險的

此程序在編譯器里不會被編譯成功,會警告:使用了未被初始化的內(nèi)存p

  1. 指針越界訪問
#includeint main()
{int arr[10] = {0};
  int *p = arr;
  int i = 0;
  for(i=0; i<=11; i++)
 {*(p++) = i;
 }
  return 0;
}

arr數(shù)組內(nèi)有10個元素,循環(huán)時,到下標為10的時候,指針指針指向的范圍超出數(shù)組arr的范圍時,p就是野指針

3.指針指向的空間釋放

int* test()
{int a = 10;
	return &a;
}
int main()
{int* p = test();
	printf("%d\n", *p);
	return 0;
}

test函數(shù)中,返回int類型a的地址,在主函數(shù)中用p接受這個地址,但是當test運行完return語句后,在test函數(shù)中對于變量開辟的空間就會歸還給系統(tǒng),此時&a已經(jīng)不存在了,所以p為野指針

如何規(guī)避野指針
  • 1.指針初始化
  • 2.小心指針越界
  • 3.指針指向空間釋放,及時置NULLp = NULL
  • 4.避免返回局部變量的地址
  • 5.指針使用之前檢查有效性:if(p!=NULL)

5.指針的運算 指針加減整數(shù)

指針加減整數(shù)在前面指針類型意義里提到,這里不多說

這里看一個代碼:

int main()
{int values[5];
	int * vp;
	for(vp = &values[0]; vp< &values[5];)
	{*vp++ = 0;
	}
}

這個代碼很簡單,就是通過指針,逐步把數(shù)組中元素值賦值為0

這里有一點值得注意的:*vp++ = 0;,++優(yōu)先級比*高,又由于++是后置,先用再加加。

vp的初始值為&values[0],所以才會從values[0]開始賦值,接著++,再對下一個位置賦值。

若改為前置++,則會先加加,再賦值,就會倒置values[0]位置處未被賦值。


指針減指針

指針-指針,前提是:兩個指針要指向同一塊空間,得到的結(jié)果的絕對值是兩個指針之間元素個數(shù)

int main()
{int arr[10] = {0 };
	printf("%d", &arr[9] - &arr[0]);
	return 0;
}

輸出結(jié)果:
在這里插入圖片描述
在這里插入圖片描述

這里我們可以利用指針減指針來模擬strlen函數(shù)

假設(shè)有一個字符串abcdefghi,在內(nèi)存中實際存儲的是a b c d e f g h i \0,所以只要找到首元素的地址和\0的地址,相減就能得到字符串的長度
在這里插入圖片描述

代碼如下:

int my_strlen(char* s)
{char* begin = s;
	while (*s!='\0')
	{s++;
	}
	return s - begin;
}

int main()
{char arr[] = "abcdefghi";
	int len = my_strlen(arr);
	printf("%d\n", len);
	return 0;
}

指針的比較運算

以數(shù)組為例,數(shù)組首元素地址是小于數(shù)組除首元素其他元素地址

但是標準規(guī)定:

允許指向數(shù)組元素的指針與指向數(shù)組最后一個元素后面的那個內(nèi)存位置的指針比較,但是不允許與
指向第一個元素之前的那個內(nèi)存位置的指針進行比較。

數(shù)組尾部的地址不是最后一個元素的地址,而是下標為數(shù)組長度處的地址
在這里插入圖片描述

如上圖:可以用&arr[6]和指針vpp與數(shù)組中其他地址進行比較,但是不可以用指針vp進行比較

通俗來講就是:可以用數(shù)組后邊的地址比較,但是不可以用數(shù)組前面的地址比較。


6.指針與數(shù)組的關(guān)系

指針與數(shù)組的關(guān)系主要在這篇文章里👉數(shù)組與地址,數(shù)組名到底是什么?

我們觀察以下代碼

int main()
{int arr[10] = {1,2,3,4,5,6,7,8,9,10 };
	
	//用數(shù)組下標遍歷數(shù)組元素
	for (int i = 0; i< 10; i++)
	{printf("%d ", arr[i]);
	}

	printf("\n");

	//利用指針遍歷數(shù)組元素
	int* p = arr;
	for (int i = 0; i< 10; i++)
	{printf("%d ", *(p + i));
	}
}

因為數(shù)組名就是數(shù)組元素首地址,所以在這個程序里arrp是完全相同的。
同時這里可以發(fā)現(xiàn)用數(shù)組下標遍歷數(shù)組和利用指針遍歷數(shù)組都可以遍歷,所以arr[i]*(p+i)是等價的

也就是有一個指針p,p[i]<=>*(p+i)

并且我們還可以推理:因為加法有交換律,所以*(p+i)*(i+p)肯定是是等價的,通過*(i+p)又可以推出i[p]
所以p[i]是可以寫成i[p]的,只是因為i[p]這種寫法太過于逆天,所以不常見。


7.二級指針

指針變量也是變量,是變量就有地址,那指針變量的地址存放在哪里?
這就是二級指針。

int main()
{int a = 10;
	int* pa = &a;    //一級指針
	int** ppa = &pa; //二級指針
	return 0;
}

上面代碼中的ppa就是二級指針

在這里插入圖片描述

二級指針有兩個*,怎么理解呢?

先看一級指針 ,int* pa = &a,一級指針中的那個*就表示pa是一個指針,剩下的那個int表示指針pa指向一個int類型變量
二級指針也同理
int** ppa = &pa,離ppa近的那個*表示ppa是一個指針變量,剩下的int*表示ppa這個指針指向int*類型
在這里插入圖片描述

二級指針的解引用也和一級指針一樣:**ppa


指針的內(nèi)容還有很多
還有 字符指針 ~ 指針數(shù)組 ~ 數(shù)組指針 ~ 函數(shù)指針 ~~~~ 等等
~Coming soon~
🎸🎸🎸

你是否還在尋找穩(wěn)定的海外服務(wù)器提供商?創(chuàng)新互聯(lián)www.cdcxhl.cn海外機房具備T級流量清洗系統(tǒng)配攻擊溯源,準確流量調(diào)度確保服務(wù)器高可用性,企業(yè)級服務(wù)器適合批量采購,新人活動首月15元起,快前往官網(wǎng)查看詳情吧


本文標題:初階指針詳解?-創(chuàng)新互聯(lián)
轉(zhuǎn)載注明:http://weahome.cn/article/esigj.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部