指针笔试题

第一题:

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf( "%d,%d", *(a + 1), *(ptr - 1));
    return 0;
}
//程序的结果是什么?

解析:

1.a有五个元素分别是1,2,3,4,5.

2.将a的地址取出来+1跳过整个数组,再强转成 int*为首元素的地址

3.所以*(a+1)a的地址是首元素的地址+1为第二个元素的地址

4.(*ptr-1)是存放下一个数组的首地址-1便得到了这个数组最后一个元素的地址

所以最后的结果为2   5.

指针笔试题

 第二题:

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);
 printf("%p\n", (unsigned long)p + 0x1);
 printf("%p\n", (unsigned int*)p + 0x1);
 return 0;
}

解析:

1.*p为结构体的指针变量

2.p是指向结构体+1跳过20个字节,0x100014(注意十六进制的转化)

3.先将p强制转化为长整型+1就是加了个整数1 0x100001

4.先将p强制转换成一个int* +1相当于加4 0x100004

注:%p是以地址的形式打印16进制数,不是打印地址。最高有效位前面的0

       %x是以十六进制打印,会省略最高位前面的0。

第三题:

int main()
{
    int a[4] = { 4,3,2,1 };
    int *ptr1 = (int *)(&a + 1);
    int *ptr2 = (int *)((int)a + 1);
    printf( "%x,%x", ptr1[-1], *ptr2);
    return 0;
}

解析:

1.ptr1先将a的地址取出来,+1跳过整个数组,再将这个地址强制转换成int*

2.ptr2先将a的首元素地址强制转换成int型加上数字1再强制转换成int*相当于跳过一个字节

3.打印:ptr1[-1]相当于*(ptr1+(-1)结果跳回4.

4.打印:ptr2由于只跳过去一个字节所以 结果为3 00 00 00指针笔试题

 注意:小端存储的形式是低权重位在低地址处,高权重位在高地址处,但是取得时候要按照正常得排序去取03是这个整形的最高地址为所以取出来的是0x3 0 00 00 00

第四题:

#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.首先数组里面存放的是逗号表达式 0,1取最终值为1,2,3取最终值为3,4,5取最终值为5

2.将数组首元素的地址放入*p中

3打印:p[0]相当于*(p+0)的值为1

注意:

(0,1)这种形式为逗号表达式不是数组元素{ }才是数组元素

第五题:
 

#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;
}

解析:

1.int a为一个五行五列的数组

2.int *p是一个能指向四个元素的数组指针。(*p相结合代表的是指针,指向整形有4个元素的

地址)

3.p等于a相当于p指针指向a(一次跳过四个元素)

4.&p[4][2]相当于*(*(p+4)+2),&a[4][2]相当于(*(*a+4)+2)

指针笔试题

5.所以%d打印为-4,%p是以地址的形式打印十六进制,所以要将-4转化为16进制

6为ff ff ff fC

指针笔试题

 第六题

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;
}

解析:

1.ptr1 为跳过整个数组之后的地址强制转换成int*

2.ptr2 为跳过第一行的地址解引用第二行首元素的地址强制转换为int*

3.ptr1 -1 得到最后一个元素的地址解引用等于10

4.ptr2-1 得到第一行最后一个元素的地址解引用等于5

5.所以输出 10 和 5

第七题

include <stdio.h>
int main()
{
 char *a[] = {"work","at","alibaba"};
 char**pa = a;
 pa++;
 printf("%s\n", *pa);
 return 0;
}

解析:

1.char *a[ ] a先与方块结合表示一个数组,再与指针结合表示是一个指针,表示指针数组

2.将w的地址放入pa

3.pa++跳过一个元素 

4.打印为 at

指针笔试题

 第八题

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.c先于[ ]结合表示是一个数组,再于*结合表示是个指针(指针数组)

    存的是e的地址 n的地址 p的地址 f的地址

2.char **cp[ ]表示存放的是char* 类型的指针

  分别指向f的地址 p的地址 n的地址 c的地址

3.char *** cpp指向的是cp首元素的地址

4.**++cpp,cpp先++得到第二个元素,解引用得到c+2,再解引用得到了p的的地址,%s向后打印得到了point

5.*--*++cpp+3 先++得到了第三个元素,解引用得到了c+1,再-- c+1变为c ,再解引用得到了e的地址,加三得到e的地址向后%s打印er

6.*cpp[-2]+3 cpp[-2]相当于*(cpp-2)得到了第一个元素的内容,再解引用得到了f的地址+3得到了s的地址,向后打印st

7.cpp[-1][-1]+1 cpp[-1][-1]相当于*(*(cpp-1)-1)  cpp-1得到了第二个元素的地址,*得到cpp的内容c+2 再-1为c+1,解引用为n的地址,+1为e的地址,向后打印为ew

注意++ -- 会实际改变原本内容,表达式不会改变原本的内容

上一篇:mysql精华总结


下一篇:#长文链接#超详细解读进程与线程