指针与数组笔试题详解

本章带给大家一些指针与数组的笔试题并且附有解析

目录

数组

第一题

解析

运行结果

第二题

解析

运行结果

第三题

解析

运行结果

 第四题

解析

运行结果

第五题

解析

运行结果

指针

第一题

解析

运行结果

 第二题

解析

运行结果

第三题

解析

运行结果

第四题

解析

运行结果

 第五题

解析

运行

 第六题

解析

运行结果

第七题

解析

运行结果


数组

第一题

在64位的平台下,下面程序运行结果为:

int main()
{

	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));
	return 0;
}

解析

数组名的意义:
1. sizeof( 数组名 ) ,这里的数组名表示整个数组,计算的是整个数组的大小。
2. & 数组名,这里的数组名表示整个数组,取出的是整个数组的地址。
3. 除此之外所有的数组名都表示首元素的地址。
int main()
{
	//数组名是首元素地址(除了两种特殊情况)
	//1.sizeof(数组名 )--- 数组名表示整个数组
	//2.&数组名 --- 数组名表示整个数组

	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));//符合我们的第一种情况,数组名代表整个数组,所以大小就是4*4=16个字节
	printf("%d\n", sizeof(a + 0));//此时a代表的是首元素地址,那么首元素地址+0还是首元素地址,地址占8个字节
	printf("%d\n", sizeof(*a));//对首元素地址进行解引用就是数组里的1,所以占4个字节
	printf("%d\n", sizeof(a + 1));//此时a代表的是首元素地址,那么首元素地址+1就是第2个元素的地址,地址占8个字节
	printf("%d\n", sizeof(a[1]));//第2个元素的大小,也就是2的大小占4个字节
	printf("%d\n", sizeof(&a));//符合第2种情况,a表示整个数组,&然后取整个数组的地址,地址占8个字节
	printf("%d\n", sizeof(*&a));//符合第2种情况,a表示整个数组,&然后取整个数组的地址,再对其解引用就是整个数组的大小16个字节
	printf("%d\n", sizeof(&a + 1));//符合第2种情况,a表示整个数组,&然后取整个数组的地址,再+1就是跳过数组之后的地址占8个字节
	printf("%d\n", sizeof(&a[0]));//第一个元素的地址占8个字节
	printf("%d\n", sizeof(&a[0] + 1));//第2个元素的地址占8个字节
	return 0;
}

运行结果

第二题

在64位的平台下,下面程序运行结果为:

int main()
{
	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));
	return 0;
}

解析

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));//整个数组的大小6*1=6个字节
	printf("%d\n", sizeof(arr + 0));//首元素地址的大小,占8个字节
	printf("%d\n", sizeof(*arr));//对首元素的地址解引用就是a的大小为1个字节
	printf("%d\n", sizeof(arr[1]));//第二个元素的大小为1个字节
	printf("%d\n", sizeof(&arr));//整个数组的地址占8个字节
	printf("%d\n", sizeof(&arr + 1));//跳过整个数组后的地址,占8个字节
	printf("%d\n", sizeof(&arr[0] + 1));//第二个元素的地址,占8个字节
	
	return 0;
}

运行结果

第三题

在64位的平台下,下面程序运行结果为:

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	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));
	return 0;
}

解析

int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", strlen(arr));//传进来的是arr的首地址,向后搜索一直搜索到‘\0’位置,所以是个随机值
	printf("%d\n", strlen(arr + 0));//随机值
	printf("%d\n", strlen(*arr));//传进来的是字符‘a’而不是地址,此时相当于非法访问97的地址
	printf("%d\n", strlen(arr[1]));//同理非法访问
	printf("%d\n", strlen(&arr));//整个数组的地址,答案也是随机值
	printf("%d\n", strlen(&arr + 1));//从整个数组之后开始搜索‘\0’,答案是随机值-6
	printf("%d\n", strlen(&arr[0] + 1));//从第2个位置开始向后搜索‘\0’,结果为随机值-1
	return 0;
}

运行结果

 第四题

在64位的平台下,下面程序运行结果为:

int main()
{
	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));
	return 0;
}

解析

int main()
{
	char arr[] = "abcdef";
	printf("%d\n", sizeof(arr));//整个数组的大小包含‘\0’7*1=7个字节
	printf("%d\n", sizeof(arr + 0));//计算的是首地址的大小也就是8个字节
	printf("%d\n", sizeof(*arr));//计算的是第1个元素的大小也就是1个字节
	printf("%d\n", sizeof(arr[1]));//第2个元素的大小也就是1个字节
	printf("%d\n", sizeof(&arr));//整个数组的地址也就是8个字节
	printf("%d\n", sizeof(&arr + 1));//跳过数组之后的地址,8个字节
	printf("%d\n", sizeof(&arr[0] + 1));//第二个元素的地址,8个字节
	printf("\n");

	printf("%d\n", strlen(arr));//传入数组首地址向后找‘\0’,结果为6
	printf("%d\n", strlen(arr + 0));//传入数组首地址+1向后找‘\0’,结果为6
	//printf("%d\n", strlen(*arr));//传入的是字符a相当于地址97,会显示非法访问
	//printf("%d\n", strlen(arr[1]));//传入的是第二个元素字符b相当于地址98,会显示非法访问
	printf("%d\n", strlen(&arr));//整个数组的地址,结果为6
	printf("%d\n", strlen(&arr + 1));//跳过整个数组之后的地址,结果为一个随机值
	printf("%d\n", strlen(&arr[0] + 1));//从第二个元素后面开始找‘\0’,结果为5
	return 0;
}

运行结果

第五题

在64位的平台下,下面程序运行结果为:

int main()
{
	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]));
	return 0;
}

解析

int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));//此时计算整个数组的大小也就是3*4*4=48个字节
	printf("%d\n", sizeof(a[0][0]));//第一行第一个元素的大小4个字节
	printf("%d\n", sizeof(a[0]));//a[0]表示第一行的地址,第一行元素的大小4*4=16个字节
	printf("%d\n", sizeof(a[0] + 1));//a[0]在此时表示第一行的首地址,计算第一行第二个元素的地址占8个字节
	printf("%d\n", sizeof(*(a[0] + 1)));//第一行第二个元素的大小4个字节
	printf("%d\n", sizeof(a + 1));//a表示第一行的地址,此时计算第二行的地址占8个字节
	printf("%d\n", sizeof(*(a + 1)));//第二行的大小占4*4=16个字节
	printf("%d\n", sizeof(&a[0] + 1));//第二行的地址占8个字节
	printf("%d\n", sizeof(*(&a[0] + 1)));//第二行的大小占4*4=16个字节
	printf("%d\n", sizeof(*a));//第一行元素的地址然后解引用就是第一行的大小4*4=16个字节
	printf("%d\n", sizeof(a[3]));//只是一个数组名sizeof里面的表达式不计算所以也是16个字节
	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;
}

解析

ptr是一个指针指向的是数组a后面的地址,ptr-1就是数组a最后一个元素的地址,解引用就是5,a+1是第二个元素的地址,解引用就是2.

运行结果

 第二题

32位平台下程序的结果是什么?

struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
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+1,p是结构体指针类型,结构体大小是20个字节,所以+1就跳过20个字节再转换为16进制就是00100014。

第二个强制转换为一个无符号的长整型,+1之后就是00100001。

第三个强制转换为无符号整型指针,+1就向后跳过4个字节结果就为00100004

运行结果

第三题

在32为平台下下面程序的运行结果为

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

解析

ptr1是一个指针,&a为整个数组的地址,+1就是跳过整个数组之后的首地址,ptr1[-1]等同于

*(ptr1-1)也就是数组中最后一个元素的地址。所以ptr[-1]的值就是2。

 (int)a + 1就相当于把地址给+1了此时就是01后面的地址,

 如图,存进去就是02000000.

运行结果

 

第四题

在32为平台下下面程序的运行结果为

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

解析

p的类型是int(*)[4]而a要传的是int(*)[5],这就使得

 p每加一只能拿4个字节使得p[4][2]的地址比a[4][2]少4个,以十进制整型输出就是-4,以16进制输出,-4的16进制结果是FFFFFFFC

运行结果

 第五题

在32为平台下下面程序的运行结果为

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

解析

aa数组第一行存放的是1,2,3,4,5第二行存放的是6,7,8,9,10。&aa+1是整个数组之后的首地址,(aa+1)是a[1]的地址,所以*(ptr1 - 1)的结果是10,*(ptr2 - 1)的结果是5.

运行

 第六题

在32为平台下下面程序的运行结果为

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

解析

a是一个指针数组,里面分别存放work,at,alibaba,的首地址,pa是一个指针,类型是char*,pa++就是指向at的首地址,解引用之后就是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;
}

解析

int main()
{
	char* c[] = { "ENTER","NEW","POINT","FIRST" };//E,N,P,F
	char** cp[] = { c + 3,c + 2,c + 1,c };//F,P,N,E
	char*** cpp = cp;//F
	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是一个数组里面放着E,N,P,F的地址,cp也是一个数组F,P,N,E地址的地址,cpp放着F地址的地址的地址。

1.++cpp为P的地址的地址的地址,两次解引用就是p向后找\0,输出结果为POINT

2.++cpp为N的地址的地址的地址,解引用就是N的地址的地址,--之后就是E的地址的地址,然后再解引用就是E的地址,+3之后就是E的地址向后搜索\0就是ER

3.cpp[-2]=*(cpp-2)得到F的地址的地址*之后得到F的地址+3得到S的地址输出ST

4.cpp[-1][-1]=*(*(cpp-1)-1)得到的是N的地址+1就是E的地址输出EW

运行结果

  • 25
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 28
    评论
评论 28
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值