1. 程式人生 > >c語言指標探祕

c語言指標探祕

今天寫AVL樹的時候突然出了個bug,死活找不出來,後來百度了一下發現是用指標傳當形參的時候指標指向的內容不會變化的,有點類似於直接傳值,所以打算好好總結一下c語言指標的知識。

首先,我們一起來看一下指標的基本知識

int main()
{
	int *p;
	int a = 666;
	p = &a;
	printf("指標的佔用記憶體大小為:%d位元組\n", sizeof(p));
	printf("指標本身的地址為:%x\n", &p);
	printf("指標的內容為:%x\n", p);
	printf("變數a的地址為:%x\n", &a);
	return 0;
}

其結果為

也就是說當我們申請一個指標變數的時候要帶*,將指標指向變數的時候我們要用&來取變數的地址

佔用4個位元組記憶體的指標有32位,假如記憶體是以位元組編制的話那麼指標可以索引約4GB的記憶體空間

接著談指向指標的指標

指向指標的指標用**表示,也就是說有兩級內容,第一級內容是指向的指標的記憶體地址,然後再是那個指標記憶體的內容指向的記憶體地址,可以把* 看成是一個將該變數記憶體裡存的值作為索引得到的記憶體空間的值,比如變數a存放的是0x0001,那麼然後地址為1的記憶體存放的數是666,那麼*a得到的便是666

int main()
{
	int **p;
	int *t;
	int a = 666;
	t = &a;
	p = &t;
	printf("指標t記憶體空間本身的內容是:%x\n", t);
	printf("變數a的地址是:%x\n", &a);
	printf("指標p最終指向的內容是:%d\n", **p);
	//**p也可以看成 *(&t),即t這個地址的記憶體空間指向的記憶體空間的值
	printf("指標t的地址是:%x\n", &t);
	printf("指標p指向的地址是:%x\n", p);
	printf("*p所表示的內容是:%x\n", *p);
	return 0;
}

其結果為:

最後來看如果要在函式中改變指標指向的內容該怎麼寫

如果用指標的話,可以改變指標指向的記憶體單元的值,但是沒法改變指標的指向

void test(int *i) {
	*i = *i + 666;
	i += 1;
}

int main()
{
	int a[] = { 666,888 };
	int *p = a;
	printf("指標p指向的內容為:%d\n", *p);
	printf("指標p本身的內容為:%x\n", p);
	test(p);
	printf("此時指標p指向的內容為:%d\n", *p);
	printf("指標p本身的內容為:%x\n", p);
	p += 1;
	printf("加1後指標p的內容為:%d\n", *p);
	printf("加1後指標p本身的內容為:%x\n", p);
	return 0;
}

執行結果為

但是如果用指向指標的指標那麼就可以改變指標的指向了

void test(int **i) {
	**i += 666;
	*i += 1;
}

int main()
{
	int a[] = { 666,888 };
	int *p = a;
	printf("指標p指向的內容:%d\n", *p);
	test(&p);
	printf("此時指標p指向的內容:%d\n", *p);
	return 0;
}

其結果為