本文指针数组笔试题可以用来检测你对指针的掌握程度ヽ( ̄▽ ̄)ノ大家自己看看自己对指针掌握怎么样吧!
温馨提示:建议大家先看目录中的题先自行思考一下,再去点击对照(默认32位条件)
文章目录
- 本文指针数组笔试题可以用来检测你对指针的掌握程度ヽ( ̄▽ ̄)ノ大家自己看看自己对指针掌握怎么样吧!
- 一、数组笔试题
-
- 1、一维数组 int a[] = {1,2,3,4};
-
- printf("%d\n",sizeof(a));
- printf("%d\n",sizeof(a+0));
- printf("%d\n",sizeof(*a));
- printf("%d\n",sizeof(a+1));
- printf("%d\n",sizeof(a[1]));
- printf("%d\n",sizeof(&a));
- printf("%d\n",sizeof(*&a));
- printf("%d\n",sizeof(&a+1));
- printf("%d\n",sizeof(&a[0]));
- printf("%d\n",sizeof(&a[0]+1));
- 2、字符数组一:char arr[] = {'a','b','c','d','e','f'};
-
- printf("%d\n", sizeof(arr));
- printf("%d\n", sizeof(arr+0));
- printf("%d\n", sizeof(*arr));
- printf("%d\n", sizeof(arr[1]));
- printf("%d\n", sizeof(&arr));
- printf("%d\n", sizeof(&arr+1));
- printf("%d\n", sizeof(&arr[0]+1));
- printf("%d\n", strlen(arr));
- printf("%d\n", strlen(arr+0));
- printf("%d\n", strlen(*arr));
- printf("%d\n", strlen(arr[1]));
- printf("%d\n", strlen(&arr));
- printf("%d\n", strlen(&arr+1));
- printf("%d\n", strlen(&arr[0]+1));
- 3、字符数组二:char arr[] = "abcdef";
-
- printf("%d\n", sizeof(arr));
- printf("%d\n", sizeof(arr+0));
- printf("%d\n", sizeof(*arr));
- printf("%d\n", sizeof(arr[1]));
- printf("%d\n", sizeof(&arr));
- printf("%d\n", sizeof(&arr+1));
- printf("%d\n", sizeof(&arr[0]+1));
- printf("%d\n", strlen(arr));
- printf("%d\n", strlen(arr+0));
- printf("%d\n", strlen(*arr));
- printf("%d\n", strlen(arr[1]));
- printf("%d\n", strlen(&arr));
- printf("%d\n", strlen(&arr+1));
- printf("%d\n", strlen(&arr[0]+1));
- 4、字符数组三:char *p = "abcdef";
-
- printf("%d\n", sizeof( p ));
- printf("%d\n", sizeof(p+1));
- printf("%d\n", sizeof(*p));
- printf("%d\n", sizeof(p[0]));
- printf("%d\n", sizeof(&p));
- printf("%d\n", sizeof(&p+1));
- printf("%d\n", sizeof(&p[0]+1));
- printf("%d\n", strlen( p ));
- printf("%d\n", strlen(p+1));
- printf("%d\n", strlen(*p));
- printf("%d\n", strlen(p[0]));
- printf("%d\n", strlen(&p));
- printf("%d\n", strlen(&p+1));
- printf("%d\n", strlen(&p[0]+1));
- 5、二维数组:int a[3][4] = {0};
-
- printf("%d\n",sizeof(a));
- printf("%d\n",sizeof(a[0][0]));
- printf("%d\n",sizeof(a[0]));
- printf("%d\n",sizeof(a[0]+1));
- printf("%d\n",sizeof(*(a[0]+1)));
- printf("%d\n",sizeof(a+1));
- printf("%d\n",sizeof(*(a+1)));
- printf("%d\n",sizeof(&a[0]+1));
- printf("%d\n",sizeof(*(&a[0]+1)));
- printf("%d\n",sizeof(*a));
- printf("%d\n",sizeof(a[3]));
- 总结: 数组名的意义:
- 二、指针笔试题
-
- 笔试题1
- 笔试题2
- 笔试题3
- 笔试题4
- 笔试题5
- 笔试题6
- 笔试题7
- 笔试题8
- 如果小伙伴上边的题都能作对,那么我在这里衷心的喊一声666,说明你对指针的掌握已经很好很不错了!!
-
一、数组笔试题
1、一维数组 int a[] = {1,2,3,4};
- 答案:
printf("%d\n",sizeof(a));
- sizeof(数组名),求的是整个数组的大小(单位是字节) 4 × 4 = 16
printf("%d\n",sizeof(a+0));
- 这里注意a表示的是数组首元素的地址,a+0,a并没有变化,a就是地址,也就是求首元素地址(整型指针大小)也就是 4 (字节)(64位 8 字节)
printf("%d\n",sizeof(*a));
- 这里* a就相当于 - *(a+0),也就是a [ 0 ] ,int 型,大小4 (字节)
printf("%d\n",sizeof(a+1));
- 这里a表示首元素地址,a+1表示a [ 1 ]的地址,求一个地址大小:4 (字节)(64位 8 字节)
printf("%d\n",sizeof(a[1]));
printf("%d\n",sizeof(&a));
- &数组名,这里数组名表示整个数组首地址,但是还是地址 :4 (字节)
printf("%d\n",sizeof(*&a));
- &数组名,这里数组名 a 表示整个数组首地址,再解引用得到的是 a。 也就是sizeof(a)求整个数组大小 :16(字节)
printf("%d\n",sizeof(&a+1));
- &a,a表示的是整个数组首地址,+1表示加另一个数组,加到数组后边,但是还是求地址大小:4(字节)(64位 8 字节)
printf("%d\n",sizeof(&a[0]));
printf("%d\n",sizeof(&a[0]+1));
- +1并没有影响,整型元素地址大小:4(字节)(64位 8 字节)
2、字符数组一:char arr[] = {‘a’,‘b’,‘c’,‘d’,‘e’,‘f’};
printf("%d\n", sizeof(arr));
- sizeof(数组名),求的是整个数组的大小(单位是字节) 6 × 1 = 6
printf("%d\n", sizeof(arr+0));
- arr这里表示首元素的地址,arr+0,不变,求地址大小:4(字节)(64位 8 字节)
printf("%d\n", sizeof(*arr));
- arr这里表示首元素的地址,*arr表示 首 元 素 arr[0],char类型大小1字节
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
- &arr,arr表示整个数组首地址,求地址大小:4(字节)(64位 8 字节)
printf("%d\n", sizeof(&arr+1));
- +1调到数组后边,本质还是地址,大小还是:4(字节)(64位 8 字节)
printf("%d\n", sizeof(&arr[0]+1));
printf("%d\n", strlen(arr));
- 这里注意声明的时候arr数组只有6个元素并没有\0结束标志,所以当会从arr开始一直往后找知道遇见 ’ \0 ‘ 才会停止,所以是个随机值。
printf("%d\n", strlen(arr+0));
- 这里arr表示数组首元素的地址,所以还是同上随机值
printf("%d\n", strlen(*arr));
- 这里arr表示数组首元素的地址,* arr 表示 取到首元素 a . 也就是对应ASC码表里的97传递给strlen( ) 函数,strlen函数会从97对应的地址处开始查找,所以会报错!!!
这里十六进制61也就是16 * 6 + 1 = 97
printf("%d\n", strlen(arr[1]));
- 这里arr【1】,表示把 b 也就是 98传给strlen函数,所以还是同上err
printf("%d\n", strlen(&arr));
- 这里arr表示数组首地址,前边加上 & 还是表示地址,所以还是对应的随机值
printf("%d\n", strlen(&arr+1));
- 这里arr表示数组首地址,+1,跳过整个数组,从数组后开始往后寻找\0,所以是随机值 -6
printf("%d\n", strlen(&arr[0]+1));
- 这里 &arr【0】表示首元素地址,+1,只是跳过数组的一个元素,从b开始往后寻找\0,所以是随机值 -1
3、字符数组二:char arr[] = “abcdef”;
printf("%d\n", sizeof(arr));
- sizeof(数组名)表示求数组大小,这里数组有七个元素,大小7*1 = 7
printf("%d\n", sizeof(arr+0));
- 这里arr 表示数组首元素地址 , +0,不变,也就是求地址大小:4(字节)(64位 8 字节)
printf("%d\n", sizeof(*arr));
- 这里arr 表示数组首元素地址 , *arr取到首元素a[0],结果是:1
printf("%d\n", sizeof(arr[1]));
printf("%d\n", sizeof(&arr));
- 这里 &arr表示整个数组首地址,求地址大小:4(字节)(64位 8 字节)
printf("%d\n", sizeof(&arr+1));
- 这里 arr表示整个数组首地址,+1,跳过整个数组,但还是地址,求地址大小:4(字节)(64位 8 字节)
printf("%d\n", sizeof(&arr[0]+1));
- 这里 &arr【0】表示首元素地址,+1,也就是arr[1]的地址,求地址大小:4(字节)(64位 8 字节)
printf("%d\n", strlen(arr));
- 这里 注意 strlen遇到\0停止,不算\0,所以结果是6
printf("%d\n", strlen(arr+0));
- 这里 arr表示数组首元素地址,+0,不变。还是6
printf("%d\n", strlen(*arr));
- 这里 arr表示数组首元素地址,*arr取到数组首元素a,相当于把对应的97当做地址传过去,报错
printf("%d\n", strlen(arr[1]));
printf("%d\n", strlen(&arr));
printf("%d\n", strlen(&arr+1));
- 这里 arr表示数组首地址,&arr+1,跳过整个数组。在\0之后开始寻找\0,随机值
printf("%d\n", strlen(&arr[0]+1));
- 这里&arr【0】+1,也就是arr[1]地址,从b开始往后找\0。是5
4、字符数组三:char *p = “abcdef”;
※注意这里char *p = “abcdef”;的意思是把整个字符串的首地址(也是a的地址)放入到字符型指针 p里
printf("%d\n", sizeof( p ));
- sizeof( p),这里p只是一个指针变量并不是数组名,所以是求地址大小:4(字节)(64位 8 字节)
printf("%d\n", sizeof(p+1));
- 这里p指向的是字符串首地址,也就是 a 的地址,p+1,也就是b 的地址,求地址大小:4(字节)(64位 8 字节)
printf("%d\n", sizeof(*p));
- 这里&p指向的是字符串首地址,也就是 a 的地址,*p也就是a,字符型,大小是1
printf("%d\n", sizeof(p[0]));
- p【0】相当于*( p + 0 ),也就是a,字符型,大小是1
printf("%d\n", sizeof(&p));
- 这里&p,也就是字符变量p地址,求地址大小:4(字节)(64位 8 字节)
printf("%d\n", sizeof(&p+1));
- 这里&p,也就是字符变量p地址,+1越过p。还是个地址,求地址大小:4(字节)(64位 8 字节)
printf("%d\n", sizeof(&p[0]+1));
- 这里&p【0】+1,也就是 a 的地址+1,b的地址。求地址大小:4(字节)(64位 8 字节)
printf("%d\n", strlen( p ));
- 这里p表示字符串首地址也就是 a 的地址,从a开始往后数直到| \ 0 。结果是6
printf("%d\n", strlen(p+1));
- 这里p+1,从a越过一个元素到b开始往后数直到| \ 0 。结果是6-1 = 5
printf("%d\n", strlen(*p));
- 这里p表示字符串首地址也就是 a 的地址,*p表示a,也就是把97传给strlen,报错
printf("%d\n", strlen(p[0]));
printf("%d\n", strlen(&p));
- 这里&p表示p的地址,从p开始往后数直到| \ 0 。结果是随机值
printf("%d\n", strlen(&p+1));
- 同上也是随机值,但是注意!!!这个随机值你无法保证是上一个随机值 – 4 (4是p指针类型的大小),因为你无法保证p的内容4个字节中是否会有\0!!!!
printf("%d\n", strlen(&p[0]+1));
- 这里p【0】,*( p + 0 ) 也就是a,+1也就是调到b。从b开始往后数直到| \ 0 。结果是6-1 = 5
5、二维数组:int a[3][4] = {0};
printf("%d\n",sizeof(a));
- sizeof(数组名),表示求整个数组大小,也就是12*4 = 48
printf("%d\n",sizeof(a[0][0]));
printf("%d\n",sizeof(a[0]));
- 这里a [ 0 ] 单独放在sizeof,可以理解为二维数组第一行
sizeof(a【0】)就是求第一行的一维数组大小,也就是16
printf("%d\n",sizeof(a[0]+1));
- 这里a【0】,并没有单独放在sizeof内部,也没有取地址,所以a[0]表示的就是第一行第一个元素的地址也就是整个数组的首地址,+1跳过一个元素也就是第一行第二个元素的地址,也就是4 (字节)(64位 8 字节)
- 那么实际上二维数组在内存中是连续存放的:::
printf("%d\n",sizeof(*(a[0]+1)));
printf("%d\n",sizeof(a+1));
- 这里二维数组数组名并没有单独放在sizeof里,所以表示的就是二维数组第一行的首地址,+1,越过的是一整行,变成第二行首地址,4(字节)(64位 8 字节)
printf("%d\n",sizeof(*(a+1)));
- 同上(a + 1)表示第二行首地址,解引用就是取得整个第二行,也就是16.
- 并且*(a+1)等价于a【1】,也就是整个第二行大小16
printf("%d\n",sizeof(&a[0]+1));
- 这里&a【0】取得整个第一行一维数组首地址,+1变成第二行地址。求地址大小:4(字节)(64位 8 字节)
printf("%d\n",sizeof(*(&a[0]+1)));
- 同上,对整个第二行一维数组首地址解引用,求得的是整个第二行,大小16
printf("%d\n",sizeof(*a));
- 这里二维数组数组名并没有单独放在sizeof里,这里a表示二维数组首元素地址,二维数组有三个部分,首元素就是第一行,也就是第一行地址。*a表示第一行的地址,大小16
- 或者你也可以这么理解*a也可以写成 *( a + 0 ),也就是a【0】第一行大小16
printf("%d\n",sizeof(a[3]));
总结: 数组名的意义:
- sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。
- &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
- 除此之外所有的数组名都表示首元素的地址。
二、指针笔试题
笔试题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,5
- &a + 1,首先&a,这里的是取得整个数组的首地址,+1跳过的是整个数组!!
- *(a + 1),等价于a [ 1 ]。
笔试题2
代码如下(示例):
struct Test
{
int Num;
char *pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
- 假设p 的值为0x100000 , 那么注意p在这里的类型,p是Test结构体类型指针,指向的是大小是20,+1跳过的是Test大小也就是 20转换成十六进制也就是0x14.结果也就是0x100014
- 这里把p先强转成无符号长整型。再加1也就是变成整型数据+1也就是0x100001
- 这里把p先强转成无符号整型指针,本身类型大小是四字节。这里+1,也就是+4,答案是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
#include
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存进去跟0没有关系!!!!p 指向第一行,p[0]表示取得第一行第一个元素,也就是a[0][0]
笔试题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;
}
-
答案: FFFFFFFC -4
-
首先看类型a是二维数组,p是(指向4个整型数据数组的)指针,数组名a表示二维数组首地址也就是第一行首地址,赋给p。(这里编译器会报错,因为大小p是指向4个Int的,二维数组a每行有5个元素,但是确实可以这么做的)
-
如果以%d形式打印,直接打印出来-4.
-
如果以%p形式打印,首先-4是需要以补码形式储存的
10000000 00000000 0000000 00000100— 原码–4
111111111 111111111 11111111 111111100— 补码–4
FFFFFFFC–%p十六进制–4
笔试题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,5
- (int *)(&aa + 1):&aa表示取得整个数组的首地址,那么+1跳过的是整个数组
- (aa + 1):aa这里表示二维数组首元素的地址,而二维数组的首元素就是第一行,aa也就是第一行的地址,+1表示跳过一整行,就是第二行。*(aa + 1)等价于 aa[1]
笔试题7
char* a[] = {
(char*)"work",(char*)"at",(char*)"alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);
- 答案:at
- 首先a的类型是指针数组,这里a是数组名,表示数组首元素的地址,数组首元素是个一级指针,一级指针的地址需要二级指针来存放,也就是pa存放的a(work字符串的首地址)。pa++,跳过一个元素,也就是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 ER ST EW
-
对应关系如图:
-
printf("%s\n", **++cpp); 首先++cpp,指向c+2,取地址 *,取到c+2,再取地址 *,取到POINT字符串
-
printf("%s\n", * - - *++cpp +3); 注意操作符优先级!!首先++,(这里注意上个语句cpp已经++过了指向c+2),cpp指向c+1,取地址,取到c+1,- -,变成c,再取地址,得到ENTER字符串首地址,此时+3往后越过3个字符,从E地址开始打印结果ER。
-
printf("%s\n", *cpp[-2]+3); cpp已经指向c+1,cpp[-2]相当于 *(p-2)得到c+3,c+3中存放的是FIRST字符串首地址,取地址得到也就是F的地址,+3,到S地址,打印结果ST
-
printf("%s\n", cpp[-1][-1]+1); 第一个【-1】相当于*(p - 1),取得c+2,再来一次【-1】相当于*(c+2-1),也就是NEW首地址也就是N的地址,+1越过N,E的地址,打印出EW
如果小伙伴上边的题都能作对,那么我在这里衷心的喊一声666,说明你对指针的掌握已经很好很不错了!!
写在文尾:
等等,昨天的不开心就让他随昨天过去吧,今天的你要开心哦!!
-----------------------------------------------------------祝你:---------------------------------------------------