经典指针和数组面试题详解

指针和数组笔试题

1.

	int main(){
    
    
		int a[5] = {
    
     1, 2, 3, 4, 5 };
		int *ptr =(int*) (&a + 1);
		printf("%d,%d", *(a + 1), *(ptr - 1));
		system("pause");
		return 0;
}

(a+1)就是a[1]的地址,对他解引用就是2
ptr指向5的下一个元素,减一之后再解引用就是5

在这里插入图片描述

2.

struct Test
{
    
    
	int num;
	char *ap;
	short a;
	char aa[2];
	short aaa[4];
}*p;  //设p的值为0x100000
	int main(){
    
    
		printf("%p\n", p + 0x1);
		printf("%p\n",(unsigned long) p + 0x1);
		printf("%p\n", (int *)p + 0x1);
		system("pause");
		return 0;
	}

对指针加一就等于加上其所指向类型的大小,所以第一问明显加了20个字节,转换为16进制就是100014
第二个直接就是单纯的给地址+1,100001;
第三个因为强转成了无符号指针类型,加1就要加上无符号指针类型的大小,所以转为16进制之后就变成了100004

在这里插入图片描述

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);
		system("pause");
		return 0;
	}

ptr1指向4的下一个元素,ptr1[-1]=*(ptr1+(-1)),所以他就是4;
第二问我们是将a强转为了int型加了一个1.相当于ptr2向后移动了一个字节,小端存储从高权值位读取,所以地址是0x2000000。

在这里插入图片描述

在这里插入图片描述
4.

int main(){
    
    
	int a[3][2] = {
    
     (0, 1), (2, 3), (4, 5) };
	int * p;
	int *q;
	q = a[1];
	p = a[0];
	printf("%d\n", q[1]);
	printf("%d", p[0]);
	system("pause");
	return 0;
}

这里有个小坑,我们再二维数组开辟空间的时候要以花括号隔开,这里的是小括号,里面是逗号表达式,实际开辟的数组内的值为 {1,3},{5,0},{0,0};
所以我们很容易得出q[1]实际就是a[1][1],也就是0;
p[0]是a[0][0],也就是1;

在这里插入图片描述
5.

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));
	system("pause");
	return 0;
}

第一问非常简单,我们第三题有说过,答案是10;
第二问我们的ptr2指向的是aa的第二个元素也就是6,所以ptr2-1再解引用就是5了;
在这里插入图片描述
6.`

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

char* *pa : pa前面的 代表他是指针,char * 代表他指向的是char * 类型的,当pa++的时候他就要跳过一个char,这时他指向at的址,解引用pa就是拿出来他指向的内容就是at的地址,%s输出就是从at中a的地址开始输出整个字符串。
在这里插入图片描述

在这里插入图片描述
7.`

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

system("pause");
return 0;
}

内存图:
在这里插入图片描述
第一问:cpp先自增,这时候他指向c+2解引用两次拿到了POINT的地址,%s输出就是POINT;
第二问:先++然后解引用,再–然后解引用,最后加三;cpp先指向c+1,解引用拿到c+1的地址,- - 之后c+1指向ENTER,解引用拿到ENTER的地址,然后对他加了三,也就是从第四个元素开始取,结果为ER;
第三问:cpp[-2]=*(cpp-2)也就是cpp指向c+3,c+3指向FIRST,解引用拿到他的地址,再+3,结果为ST;
第四问:cpp指向c+2,c+2指向POINT减一之后指向NEW;解引用拿到NEW地址,+1之后从E开始读,答案为EW;
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_50302770/article/details/121129580