C语言 指针的一些题目(2)

本文章承接上一篇博客

C语言 指针的一些题目(1)_Naion的博客-CSDN博客https://blog.csdn.net/Naion/article/details/122548523我们再来继续做一些题目.

笔试题1:

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

解析:

2.a是数组首元素的地址, +1就拿到这个数组的第二个元素的地址,在*,就拿到这个元素2;

5.&a,就拿到数组的地址,再+1,跳过整个数组.强制转换后,ptr的位置在这个数组的后面.-1,它就指向了5,也就是说,它-1后是5的地址,在*,就拿到了5;

笔试题2:

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

解析:

在这里,我们假设这个结构体的大小是20个字节,同时告知p值为0x100000.由于是假设的,所以运行的时候,结果可能不一样,不过它们的差是一样的.

0x100014.p这里是结构体的地址,它+1,就是跳过整个结构体的大小20个字节,然后再将20转换成16进制就是0x100014;

0x100001.p被强制转换成无符号长整形,再+1,就是它的值+1,也就是0x100000;

扫描二维码关注公众号,回复: 13732659 查看本文章

0x100004.p被强制转换成无符号int型指针,再+1,就跳过这个int指针的大小,也就是0x100004;

笔试题3:

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

解析:

4.&a,是这个数组的地址,再+1,跳过这个数组,这里的ptr1[-1],写成指针形式就是*(ptr1 - 1),就是4;

2000000(小端模式)a,是数组首元素的地址,再(int),强制类型转换成十进制,+1,就是再十进制上+1,再转换成16进制.要注意int是一次跳过4个字节.

笔试题4:

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

 解析:

 ff ff ff fc.如图,将-4转换成16进制就可以了.

-4.如图.

笔试题5:

#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.注意这里面的括号,不是{},这是逗号表达式,所以整个二维数组的元素是1,3,5.p=a[0],拿到这第一行,再p[0],就是这第一行的第一个元素;

笔试题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.&aa拿到这个二维数组的地址,再+1,跳过这个二维数组,转换成int*类型,用ptr1指针来接收.ptr1-1,就是元素10的地址,再*,就是元素10;

5.aa是数组首元素的地址对于二维数组来说,就是它的第一行.再+1,跳过第一行,来到第二行,这个地址用ptr2指针来接收.-1,就是5的地址,再*,就拿出了元素5;

笔试题7:

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

解析:

at.如图:

 笔试题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;
}

解析:

 指针指向如图:(注意优先级!)

POINT.cpp++,就到了c+2,再*,就拿到里面的值POINT;

ER.cpp继承上一个打印的地址,再++,就到了c+1的地址,再*,就拿到了c+1的地址,再--,说明把c+1改变成c,也就是说,它的指向不在是NEW,而是ENTER,+3,就到了E的地址,再*,就是ER;

ST.*cpp[-2]+3,就等价于* *(cpp-2)+3.cpp-2,就到了c+3处,再*,就拿到c+3的地址,再*,就拿到FIRST,再+3,就到了S处,就拿出了ST;

EW.等价于*(*(cpp-1)-1)+1,-1,就到了c+2,再*,就是拿到c+2,再-1,就把c+2变成c+1,再*,就拿到NEW,再+1,就拿到了EW;

猜你喜欢

转载自blog.csdn.net/Naion/article/details/122590308