指针笔试题
笔试题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;
}
//程序的结果是什么?
解析:
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,5
笔试题2
//已知结构体的大小是20个字节
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}* p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int)p + 0x1);
return 0;
}
解析:
指针+-整数
//结构体的大小是20个字节
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}* p;//结构体指针
//假设p 的值为0x100000。
int main()
{
printf("%p\n", p + 0x1);
// 123456789abcdefg
// 0x1==1
// 20->16+4->14
// 0x100014
printf("%p\n", (unsigned long)p + 0x1);
// 整数+1=整数
// 0x00100014->1048576
// 1048576+1==1048577==0x00100001
// 0x100001
printf("%p\n", (unsigned int)p + 0x1);
// 整形跳过4
// 0x00100004
return 0;
}
笔试题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;
}
解析:
内存(小端存储)
01 00 00 00 | 02 00 00 00 | 03 00 00 00 | 04 00 00 00
低地址 高地址
//%x意思是16进制输出( 以16进制输出变量地址)
int main()
{
int a[4] = { 1, 2, 3, 4 };
int *ptr1 = (int *)(&a + 1);
int *ptr2 = (int *)((int)a + 1);
//(int)a-->首元素地址转整形,例如0x00000005
//(int)a+1-->整形+1=整形(向后访问一个字节),例如5+1=6
//地址,例如0x00000006
printf( "%x,%x", ptr1[-1], *ptr2);
//ptr1[-1]==*(ptr1+(-1))=*(ptr1-1)
//4->0x00 00 00 04
//00 00 00 | 02
//0x02000000
//0x02 00 00 00
return 0;
}
笔试题4
#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;
}
解析:
#include <stdio.h>
int main()
{
int a[3][2] = { (0, 1), (2, 3), (4, 5) };//逗号表达式{1,3,5}
int *p;
p = a[0];//1 3
printf( "%d", p[0]);//1
return 0;
}
// right
// 1 3
// 5 0
// 0 0
//err idea
// 0 1 --p--p[0]==0
// 2 3
// 4 5
笔试题5
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 a[5][5];
int(*p)[4];//指向四个元素数组的指针
p = a;//首元素a[0]的地址
printf( "%p,%d\n", &p[4][2] - &a[4][2], &p[4][2] - &a[4][2]);
//结果FFFFFFFC和-4
return 0;
}
a[0] a[1] a[2] a[3] a[4]
|****|* ***|** **|*** *|**|** **|***
| | | | | | |
P p+1 p+2 p+3 p+4 p[4][2] a[4][2]
p[4][2]==*(*(p+4)+2)
&p[4][2] - &a[4][2]//指针相减==指针中间有几个元素==4
//小-大==-4
//%d打印-4原码10000000 00000000 00000000 00000100
10000000 00000000 00000000 00000100原码
11111111 11111111 11111111 11111011反码
11111111 11111111 11111111 11111100补码
//%p打印地址,-4在内存中用补码存储,直接看成地址打印
11111111 11111111 11111111 11111100
F F F F F F F C
FFFFFFFC
笔试题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;
}
解析:
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));
//10和5
return 0;
}
1 2 3 4 5 |6 7 8 9 10|
| |
| &aa+1
aa+1
*(aa + 1)==aa[1]第二行首元素的地址
第二行的地址 解引用 等于 第二行的数组名aa[1]
笔试题7
#include <stdio.h>
int main()
{
char *a[] = {"work","at","alibaba"};
char**pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
解析:
#include <stdio.h>
int main()
{
char *a[] = {"work","at","alibaba"};
//char* p="abcdef";//存的是a的地址
//a
// char* "work"
// char* "at"
// char* "alibaba"
char* *pa = a;
//a == 首元素的地址 == 首元素是指针是"work"的地址 == 指针的地址是二级指针
//*pa表明是指针
//char*是指向的类型
pa++;
//跳过一个char*的字节数
//指向"at"的指针
printf("%s\n", *pa);
//at
return 0;
}
笔试题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;
}
解析:
//%s在C语言中代表字符串型格式符。
int main()
{
char *c[] = {"ENTER","NEW","POINT","FIRST"};
char* *cp[] = {c+3,c+2,c+1,c};
char** *cpp = cp;
printf("%s\n", **++cpp);//打印POINT
printf("%s\n", *--*++cpp+3);//打印出ER
printf("%s\n", *cpp[-2]+3);//打印出ST
printf("%s\n", cpp[-1][-1]+1);//打印出EW
return 0;
}
c数组
char* 存放"ENTER"首字符地址
char* 存放"NEW"首字符地址
char* 存放"POINT"首字符地址
char* 存放"FIRST"首字符地址
cp[]数组
char**指针 c+3"FIRST"
char**指针 c+2"POINT"
char**指针 c+1"NEW"
char**指针 c"ENTER"
cpp指针指向cp[]数组
cpp指向cp首元素的地址
**++cpp
++cpp//c+2的地址
*++cpp//拿到c+2的内容
**++cpp//通过c+2的内容,拿到"POINT"
//打印POINT
*--*++cpp+3
cpp//c+2的地址
++cpp//指向c+1的地址(由于上一条语句已经改变了)
*++cpp//拿到c+1的内容
--*++cpp//拿到c的内容
*--*++cpp//拿到ENTER的内容
*--*++cpp+3//拿到E的地址
//打印出ER
*cpp[-2]+3
cpp//c+1的地址
cpp-2//c+3的地址
cpp[-2] == *(cpp+(-2)) == *(cpp-2)//拿到c+3
*cpp[-2]+3//拿到S的地址
//打印出ST
cpp[-1][-1]+1
cpp[-1] == *(cpp-1)
cpp[-1][-1] == *(*(cpp-1)-1)
cpp[-1][-1]+1 == *(*(cpp-1)-1)+1
cpp//c+1的地址
cpp-1//c+2的地址
*(cpp-1)//拿到c+2
*(cpp-1)-1//拿到c+1
*(*(cpp-1)-1)//拿到NEW,就是N的地址
*(*(cpp-1)-1)+1//拿到E的地址
//打印出EW