1. 程式人生 > >c語言指標相關面試題

c語言指標相關面試題

例1

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf("%d %d\n", *(a + 1), *(ptr - 1));
    system("pause");
    return 0;
}

程式結果:2 5
分析:陣列名在sizeof內部單獨出現和&(陣列名)這兩種情況下,陣列名錶示整個陣列。
其他情況下,陣列名均表示首元素的地址。
所以這裡的(a+1)的a表示首元素的地址,+1表示下一個元素的地址,解引用表示下一個下一個元素2.
(&a+1)對a取地址,取得是首元素的地址,+1是指向下一個陣列的起始地址。所以ptr-1指向該陣列的在最後一個元素,解引用表示該元素5.

這裡區分一下:
(a+1):即陣列名+1,指向該陣列內下一個元素。
(&a+1):即&(陣列名)+1,指向下一個陣列的起始。
例2:

struct Test
{
    int num;
    char *p;
    short s;
    char c[2];
    short sd[4];
}*p;
int main()
{
    printf("%#x\n", p);
    printf("%#x\n", p + 0x1);
    printf("%#x\n", (unsigned long)p + 0x1);
    printf("%#x", (unsigned
int *)p + 0x1); system("pause"); return 0; }

先來看結果:
這裡寫圖片描述
分析:p是一個結構體指標,他的地址我們其實並不關心。這道題考察了對不同型別的+1,到底是加多少。
對p+1:p是一個指標,對指標+1,加其指向型別的大小。該結構體大小由於記憶體對齊我們可以得到是20,所以16進位制運算得如圖結果。
將p強轉為無符號長整形,對p+1,就是+1。
將p強轉為無符號整形指標型別,對p+1就是加其指向型別的大小,即就是4。
例3:

int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4
, 5) }; int *p; p = a[0]; printf("%d", p[0]); system("pause"); return 0; }

這道題有一個很容易出錯的陷阱,在定義二維陣列時用了逗號表示式,所以這個二維陣列並不是題目上的資料,而是{1,3,5,0,0,0};
所以p[0]就是該陣列第一個元素1.

例4

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


    system("pause");
    return 0;
}

分析:這道題考察了對二維陣列的理解,我們知道陣列在記憶體中是線性連續存放的,所以二維陣列也是如此。
&a+1:與一維陣列同理,所以此時+1指向了下一個陣列的起始位置,*(ptr1-1)即就是該陣列的最後一個元素10。
(a+1):指向下一個元素,這裡需要我們將二維陣列看作一維陣列(該陣列有兩個元素,每個元素是一個一維陣列),所以a此時表示第一個元素,+1指向下一個元素即就是第二個一維陣列的起始,*(ptr2-1)即就是上一個一維陣列的最後一個元素5;

例5


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

這道題主要考察了二級指標,首先a中的字串串都在字元常量區儲存,a指向該區域的起始地址。pa++,指向了下一個字串的地址,所以結果是:at。