指針和數組相關的一些題目---(3)

在(2)中分析了題目3,題目4和題目5,這篇博客來分析題目6,題目7和題目8,也是最後的3道題目。

題目6.

//練習6
int main()
{
	int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
	int *ptr1 = (int*)(&aa + 1);
	int *ptr2 = (int*)(*(aa + 1));
	printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
	return 0;
}

我們將這個代碼中的aa[2][5]數組在內存中的儲存形式用圖模擬出來:

現在我們來分析這個代碼:

“int *ptr1 = (int*)(&aa + 1);”:

“&aa”就是aa數組整體的地址,“&aa+1”表示aa數組最後一位元素的下一位地址。再將它強轉爲int型指針,賦給ptr1。

“int *ptr2 = (int*)(*(aa + 1));”:

“(aa+1)”就是給aa數組的首元素地址加一,它就是aa數組的第二位元素的地址。aa數組是一個二維數組,第二位元素的地址就是它的元素6的地址。在將它強轉爲int型指針,賦給ptr2。

結果:所以*(ptr1-1)就是aa數組的元素10,*(ptr2-1)就是aa數組的元素5。

我們來看看程序的結果:

題目7.

//練習7
int main()
{
	char *a[] = { "work", "at", "alibaba" };
	char **pa = a;
	pa++;
	printf("%s\n", *pa);
	return 0;
}

我們將這個代碼中的a[]數組在內存中的儲存形式用圖模擬出來:

我們來分析一下代碼:

“char **pa = a”:

pa是一個二級指針,它指向a這個指針數組,具體來說此時它指向a數組的首元素地址,即指向“work”字符串的指針的地址。所以“pa++;”後pa就指向指針數組的第二個元素的地址,所以“*pa”就是“at”

我們來看一下代碼運行的結果:

練習8.

//練習8
int main()
{
	char *c[] = { "ENTER", "NEW", "POINT", "FIRST" };
	char **cp[] = {c+3,c+2,c+1,c};
	char ***cpp = cp;
	printf("%s\n",**++cpp);
	printf("%s\n",*--*++cpp+3);
	printf("%s\n",*cpp[-2]+3);
	printf("%s\n",cpp[-1][-1]+1);
	return 0;
}

我們將這個代碼中的各個變量在內存中的儲存形式用圖模擬出來:

接下來我們對這個代碼進行分析:

1:“**++cpp”:

其中“cpp”先與“++”結合,此時的cpp指向cp[1]。接着“++cpp”在和“**”結合,就得到了“POINT”字符串首元素的地址。

cpp的初始指向變化如圖:

2:“*--*++cpp+3”:

1的基礎上,此時“cpp”“++”先結合,指向“cp[2]”;在與“*”結合,此時得到“c[1]”,即“*++cpp”爲“cp[2]”;與“--”結合,此時指針指向“ENTER”;在與“*”結合,此時得到“ENTER”首字符的地址,最後“+3”得到了“ENTER”第四個字符的地址

cpp的初始指向變化如圖:

3:“*cpp[-2]+3”:

“2”的基礎上,“cpp[-2]”就等於“*(cpp-2)”,得到了c[3];接着在與“*”結合,得到了“FIRST”的首字符地址;在與“+3”結合得到“FIRST”的第四個字符的地址。

此次cpp的初始指向未發生變化,如圖:

 

4:“cpp[-1][-1]+1”:

“3”的基礎上,“cpp[-1]”就等價於“*(cpp-1)”,此時得到c[2]地址;再次與“[-1]”結合等價於“*(cpp[-1])-1)”,得到“NEW”的首字符的地址;在與“-1”結合,得到“NEW”的第二個字符的地址

cpp的初始指向未發生變化,如圖:

由1,2,3,4得到結果:屏幕打印:“POINT”  “ER”  “ST”  “EW”

再來看一下程序運行的結果:

以上的理解有什麼問題歡迎大家指正!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章