玩轉指標重難點(3)
阿新 • • 發佈:2021-02-11
習題篇
1.
#include<stdio.h>
int main()
{
int a[5] = { 1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
這道題*(a+1)簡單,就是陣列首元素地址+1算出來的就是2。關鍵是第二個題,用來存放&a的是陣列指標也就是int (*)[5],但前面有個整型指標的強轉,所以&a+1由下圖表示。
由於ptr-1,此時已經被轉化為整型指標,減一就是往前移動一個整型。也就是5.
2.
#include<stdio.h>
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}* p;
//假設p 的值為0x100000。 如下表表示式的值分別為多少?
//已知,結構體Test型別的變數大小是20個位元組
int main()
{
p = (struct Test*)0x100000;
printf("%p\n", p + 0x1); // 0x100014
printf("%p\n" , (unsigned long)p + 0x1); // 0x100001
printf("%p\n", (unsigned int*)p + 0x1); // 0x100004
return 0;
}
①這裡p被轉化為了結構體指標,0x1是十六進位制的1也是1,+1跳過一個結構體的指標的位元組數也就是20,20轉化為16進位制加上0x100000也是就是答案了。
②這裡的p被轉化為整型+1就是+1。
③這裡的p被轉化為整型指標+1跳過4個位元組。
3.
#include<stdio.h>
int main()
{
int a[4] = { 1, 2, 3, 4 };
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
printf("%x,%x", ptr1[-1], *ptr2);
return 0;
}
地址在記憶體中的儲存都是以小端位元組序來儲存的,如果有人不懂小端位元組序的話可以看看這篇部落格整型在記憶體中的儲存
ptr1[-1]的意思是*(ptr1+(-1)),-1移動一個整型,也就是記憶體中04000000,以十六進位制列印就是4。
(int)a + 1是一個整數跳過一個位元組
4.
#include <stdio.h>
int main()
{
int a[3][2] = { 1, 3, 5 };
int *p;
p = a[0];
printf("%d", p[0]);
return 0;
}
// 輸出結果是什麼?
a的排列
a[0],a[1],a[2] 分別是每一行的陣列名,即每一行首元素的地址p[0]相當於對a解引用答案就是1。
5.
#include<stdio.h>
int main()
{
int a[5][5];
int(*p)[4];
p = a;
printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
return 0;
}
p[4][2]相當於*(*(p+4)+2),兩個指標相減得到是元素之間的個數也就是-4,在記憶體中的儲存為
轉化為16進位制是ffffffc。
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;
}
這道題和第三道題的思路一樣,大家可以自己感受一下。
答案是10和5.
7.
#include <stdio.h>
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };
int *p;
p = a[0];
printf( "%d", p[0]);
return 0;
}
// 輸出結果為多少?
逗號表示式得出來的是後面那個數,所以該題答案為1。
8.
#include<stdio.h>
int main()
{
char *c[] = {"work","at","alibaba"};
char**pa=a;
pa++;
printf("%s ",*pa);
return 0;
}