指针进阶练习题

目录

数组名的意义:

 练习一

 练习二 

 练习三

 练习四

 练习五

 练习六

 练习七

 练习八

 练习九

 练习十 



数组名的意义:

1. sizeof(数组名),这里的数组名表示整个数组,计算的是整个数组的大小。

2. &数组名,这里的数组名表示整个数组,取出的是整个数组的地址。

3. 除此之外所有的数组名都表示首元素的地址。

每道题都可以先忽视旁边注释,自行做题后再对照答案

由于后面部分题都是画图来理解,所以文字描述很少,但只要学会这两篇文章, 理解起来应该不难:

指针初级篇-CSDN博客

数组及指针进阶篇-CSDN博客

练习一

一维数组

//思考这里的sizeof里面代表什么,最终输出是什么?
#include<stdio.h>
int main()
{
	int a[] = { 1,2,3,4 };
	printf("%d\n", sizeof(a));        //这里的a在sizeof里面单独出现,
                                        所以表示整个数组,所以输出为16
	printf("%d\n", sizeof(a + 0));    //这里的a不在sizeof中单独出现,
                                        代表的是首元素的地址,加0相当于每当,
                                        所以还是首元素的地址,输出为4/8
	printf("%d\n", sizeof(*a));       //这里的a不在sizeof里面单独出现,
                                        所以这里的a代表首元素的地址,*解引用后,
                                        相当于首元素,所以是int类型的元素,输出为4
	printf("%d\n", sizeof(a + 1));    //这里的a不在sizeof里面单独出现,
                                        所以表示的首元素的代表的是首元素的地址,
                                        加1后代表地址加1,
                                        也就是加该指针所指向的类型的大小,
                                        也就是指向下一个元素的指针,
                                        所以输出为4/8
	printf("%d\n", sizeof(a[1]));     //a[1]其实就是元素里第二个元素,也就是2,
                                        大小是int类型,也就是4
	printf("%d\n", sizeof(&a));       //这里的a是&a,也就是整个数组的地址,
                                        输出为4/8
	printf("%d\n", sizeof(*&a));      //这里的a是&a,也就是整个数组地址,
                                        解引用后代表的是整个数组,也就是4个int
                                        输出为16
	printf("%d\n", sizeof(&a + 1));   //这里的a是&a,代表的是整个数组的地址,
                                        加1代表的是跳过整个数组,
                                        虽然指向的下一个数组是位置的,
                                        但只要是指针,大小就为4/8
	printf("%d\n", sizeof(&a[0]));    //这里相当于取出a[0]的地址,也就是4/8
	printf("%d\n", sizeof(&a[0] + 1));//这里相当于取出a[0]的地址,
                                        加1也就是加其所指向类型的大小,
                                        也就是指向a[1]的指针
	return 0;
}

指针大小为4是因为在32位平台下测试的,如果是64位平台下测试,答案如下:

 

练习二 

字符数组

//先自行做题,做完再看右侧的注释解析
#include<stdio.h>
int main()
{
	char arr[] = { 'a','b','c','d','e','f' };
	printf("%d\n", sizeof(arr));                 //这里的arr在sizeof里单独出现
                                                   代表的是整个数组,
                                                   所以输出为6
	printf("%d\n", sizeof(arr + 0));             //这里的arr不在sizeof里单独出现,
                                                   代表的是首元素的地址,
                                                   加0相当于没加,所以输出为4/8
	printf("%d\n", sizeof(*arr));                //这里的arr在sizeof里单独出现,
                                                   代表的是首元素的地址,
                                                   解引用也就是代表第一个元素,
                                                   所以输出为1
	printf("%d\n", sizeof(arr[1]));              //这里的arr[1]代表的是
                                                   数组第二个元素,输出为1
	printf("%d\n", sizeof(&arr));                //这里的arr是&arr,
                                                   代表的是整个数组的地址,
                                                   输出为4/8
	printf("%d\n", sizeof(&arr + 1));            //这里的arr是&arr,
                                                   代表的是整个数组的地址,
                                                   加1表示跳过整个数组,
                                                   指向下一个数组的地址,
                                                   所以输出为4/8
	printf("%d\n", sizeof(&arr[0] + 1));         //这里是取出arr[0]的地址,
                                                   加一表示变成指向arr[1]的指针,
                                                   所以输出为4/8
	return 0; 
}

 练习三

⼆维数组

#include<stdio.h>
int main()
{
	int a[3][4] = { 0 };
	printf("%d\n", sizeof(a));              //这里的a代表整个数组,
                                              所以输出为48     
	printf("%d\n", sizeof(a[0][0]));        //这里的a相于整个数组的第一个元素,
                                              所以输出为4
	printf("%d\n", sizeof(a[0]));           //这里的a[0]相当于整个二维数组的第一个
                                              元素,第一个元素是一个由四个元素的
                                              一维数组所以输出为16
	printf("%d\n", sizeof(a[0] + 1));       //这里的a[0]相当于整个数组的
                                              第一个a[0][0]元素d地址
                                              加1相当于是这个数组的第二个元素,
                                              的地址,所以输出为4/8
	printf("%d\n", sizeof(*(a[0] + 1)));    //这里的同上,也就是a[0][1]那个元素
                                              输出为4
	printf("%d\n", sizeof(a + 1));          //这里的a表示首元素地址,也就是一个
                                              含有四个元素的一维数组
                                              加1表示跳过一个一维数组,指向了下一个
                                              数组的地址,所以输出为4/8
	printf("%d\n", sizeof(*(a + 1)));       //这里解引用也就是第二个一维数组的全部元素
                                              输出为16
	printf("%d\n", sizeof(&a[0] + 1));      //&a[0]也就是对第一行的数组名取地址
                                              &a[0]+1得到的是第二行的地址
                                              输出为4/8
	printf("%d\n", sizeof(*(&a[0] + 1)));   //同时解引用后也就是第二行的元素
                                              输出为16
	printf("%d\n", sizeof(*a));             //这里a表示首元素的地址也就是第一行的地址
                                              *解引用也就是第一行的元素,输出为16
	printf("%d\n", sizeof(a[3]));           //这里虽然没有a[3]的存在,
                                              但a[3]同样也是一个一维数组,
                                              所以输出的是16
                                              这里没有越界访问,没有真的去访问第四行
	return 0;
}

 练习四

#include <stdio.h>
int main()
{
     int a[5] = { 1, 2, 3, 4, 5 };
     int *ptr = (int *)(&a + 1);
     printf( "%d,%d", *(a + 1), *(ptr - 1));
     return 0;
}

练习五

#include<stdio.h>
struct Test
{
	int Num;
	char* pcName;
	short sDate;
	char cha[2];
	short sBa[4];
}*p = (struct Test*)0x100000;
//假设结构体Test类型的变量大小是20个字节
int main()
{
		printf("%p\n", p + 0x1);                    //这里指针+1也就是加一个
                                                      结构体大小20,单输出为16进制
                                                      所以最终输出为0X100014
		printf("%p\n", (unsigned long)p + 0x1);     //这时候p强制类型转换成了
                                                      无符号长整形,加1说白了
                                                      也就是+1,输出为0X100001
		printf("%p\n", (unsigned int*)p + 0x1);     //这里p强制转化成一个int*类型的
                                                      指针,加1也就是加一个int类型
                                                      的大小,所以输出为0X100004
		return 0;
	
}

 练习六

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

 a[0]表示首元素的地址,即a[0][0]的地址,&a[0][0]赋值给了p,p[0]其实就相当于*(p+0)也就是第一个元素,也就是1。

练习七

#include <stdio.h>
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[4][2]和a[4][2]相差了4个元素,相减也就是-4, -4要%p也就是16进制打印

最终也就是FF FF FF FC

练习八

#include <stdio.h>
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

练习九

#include <stdio.h>
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;
}

练习十 

#include<stdio.h>
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;
}

取出来为02 00 00 00. 

这题考察的是数据在内存的存储,如果不能理解,可以了解完这篇文章在做一遍:

数据的存储-CSDN博客

  • 14
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值