指针笔试题讲解

文章目录

  • 题目
  • 答案与解析
    • 1、
    • 2
    • 3
    • 4、
    • 5、
    • 6、
    • 7、
    • 8、


题目

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int *ptr = (int *)(&a + 1);
    printf( "%d,%d", *(a + 1), *(ptr - 1));
    return 0;
}
//由于还没学习结构体,这里告知结构体的大小是20个字节
//由于还没学习结构体,这里告知结构体的大小是20个字节
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;
}
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;
}
int main()
{
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    int *p;
    p = a[0];
    printf( "%d", p[0]);
 return 0;
}
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;
}
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;
}
int main()
{
 char *a[] = {"work","at","alibaba"};
 char**pa = a;
 pa++;
 printf("%s\n", *pa);
 return 0;
}
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)sizeof(数组名),这时表示整个数组的大小
(2)&数组名,这时表示整个数组的地址

1、

答案:
在这里插入图片描述

解析:

int main()
{
    int a[5] = { 1, 2, 3, 4, 5 };
    int* ptr = (int*)(&a + 1);//&a,取出的是整个数组的地址,加一,跳过整个数组的大小
    printf("%d,%d", *(a + 1), *(ptr - 1));//这里两个都是int*类型的指针,且都是普通的加减一,都只跳过4个字节
    return 0;
}

指针笔试题讲解_第1张图片

2

答案:

解析:

int main()
{
    p = (struct Test*)0X100000;
    //这里的p是结构体指针,加一跳过一个结构体大小的字节,跳过20个字节,由于是16进制,所以显示14
    printf("%p\n", p + 0x1);
    //这里将p强制转化为了unsigned long类型,非指针,加一就只是加1个字节
    printf("%p\n", (unsigned long)p + 0x1);
    //这里将p强制转化为了unsigned int* 类型,加一跳过一个Int类型的大小,4个字节
    printf("%p\n", (unsigned int*)p + 0x1);
    return 0;
}

3

答案:
在这里插入图片描述

解析:

int main()
{
    int a[4] = { 1, 2, 3, 4 };
    //&a 取出的是整个数组的地址,加1跳过整个数组的大小(4 * 5 =20个字节)
    int* ptr1 = (int*)(&a + 1);
    //将p转化为Int 类型,加一就只会跳过一个字节
    int* ptr2 = (int*)((int)a + 1);
    printf("%x,%x", ptr1[-1], *ptr2);
    return 0;
}

指针笔试题讲解_第2张图片

4、

答案:
在这里插入图片描述

解析:

int main()
{
    //下面数组中的元素有逗号表达式:例:(0,1),这样只会取到1的值,所以数组元素是(1,3,5)
    int a[3][2] = { (0, 1), (2, 3), (4, 5) };
    int* p;
    //a[0]是二维数组第一行的数组名,其内有1,3 两个元素
    p = a[0];
    //p[0] = 1
    printf("%d", p[0]);
    return 0;
}

5、

答案:
在这里插入图片描述

解析:

int main()
{
    int a[5][5];
    //数组指针类型
    int(*p)[4];
    //类型不一样,但是也可以存储,只是每次存储4个值
    p = a;
    //&p[4][2]-&a[4][2] = -4;将地址转化为16进制
    printf("%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
    return 0;
}

指针笔试题讲解_第3张图片

6、

答案:
在这里插入图片描述

解析:

int main()
{
    int aa[2][5] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    //&aa 是取整个数组的地址,加1跳过整个数组
    int* ptr1 = (int*)(&aa + 1);
    //aa 代表二维数组第一行的值,加1跳过5个元素
    int* ptr2 = (int*)(*(aa + 1));
    printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
    return 0;
}

7、

答案:
在这里插入图片描述

解析:

int main()
{
	//是一个指针数组,存储的是美格字符串的首元素一直
	char* a[] = { "work","at","alibaba" };
	//二级指针来保存a的地址
	char** pa = a;
	//正常的加1,跳过一个元素
	pa++;
	printf("%s\n", *pa);
	return 0;
}

8、

答案:
在这里插入图片描述

解析:
解析:

  1. c[]中存放的数据是每个字符串的首元素
  2. cp[]中存放的数据其实就是c中的反过来
  3. 对1:++cpp执行,指向c+2,解引用,得到c+2,再解引用得到了P的地址,打印出point
  4. 加号的优先级很低,先算其他的;打印的时候会把获得地址到\0之间的地址都打印
  5. 对2:++cpp执行,指向c+1,解应用得到C+1,指向N,–执行,指向E,解引用,得到E的地址,在加3,向后移3未,得到的是ENETR中第二个E的地址
  6. cpp已经经过了两次++,cpp[-2]得到得是跳转到C+3,得到F的地址,在进行解引用,跳到FIRST地址中,+3得到S的地址
  7. 对4:cpp还是指向c+1,cpp[-1]跳转到C+2,指向P,cpp[-1][-1]跳转到P的上一个NEW中,对其+1,得到E的地址
    指针笔试题讲解_第4张图片

你可能感兴趣的:(算法)