指针与数组笔试题解析
发布日期:2021-06-28 16:38:50 浏览次数:2 分类:技术文章

本文共 5856 字,大约阅读时间需要 19 分钟。

指针与数组笔试题解析

一维数组

int main(){
int a[]={
1,2,3,4}; printf("%d\n",sizeof(a));//16 printf("%d\n",sizeof(a+0));//16(第一次的答案) -4 数组名这里表示首元素地址,a+0还是首元素地址 printf("%d\n",sizeof(*a));//4 printf("%d\n",sizeof(a+1));//4 printf("%d\n",sizeof(a[1]));//4 printf("%d\n",sizeof(&a));//16 -4 &a取出的是数组的地址,但是数组的地址也是地址,答案4 printf("%d\n",sizeof(*&a));//4 -16 &a是数组的地址,数组的地址解引用访问的数组,sizeof计算就是数组的大小 printf("%d\n",sizeof(&a+1));//1 -4 &a+1也是一个地址,跳过了一个数组。 printf("%d\n",sizeof(&a[0]));//4 printf("%d\n",sizeof(&a[0]+1));//4 return 0;}

字符串

int main(){
char arr[]={
'a','b','c','d','e','f'}; printf("%d\n",sizeof(arr));//7 -6//sizeof计算的是数组大小,6*1=6字节 printf("%d\n",sizeof(arr+0));//1 -4//首元素地址 printf("%d\n",sizeof(*arr));//1 printf("%d\n",sizeof(arr[1]));//1 printf("%d\n",sizeof(&arr));//4 printf("%d\n",sizeof(&arr+1));//4 printf("%d\n",sizeof(&arr[0]+1));//4 printf("%d\n",strlen(arr));//6 //随机值,stelen需要遇到\0才停止计数 printf("%d\n",strlen(arr+0));//1 //随机值 //printf("%d\n",strlen(*arr));//err strlen(地址) *arr 首元素'a' a的ASCII的值为97,strlen就会将97作为地址,进行访问,此时已经非法访问了 //printf("%d\n",strlen(arr[1]));//err //printf("%d\n",strlen(&arr));// 随机值 //printf("%d\n",strlen(&arr+1));// 随机值-6 printf("%d\n",strlen(&arr[0]+1));//1 //随机值-1 return 0;}
int main(){
char arr[]="abcdef"; printf("%d\n",sizeof(arr));//6 -7 sizeof计算的数组大小,单位是字节:7 printf("%d\n",sizeof(arr+0));//4 计算是地址的大小-arr,0是首元素地址 printf("%d\n",sizeof(*arr));//1 *arr是首元素,sizeof(*arr)计算首元素的大小 printf("%d\n",sizeof(arr[1]));//1 arr[1]是第二个元素,sizeof(arr[1])计算第二个元素的大小 printf("%d\n",sizeof(&arr));//4 &arr虽然是数组的地址,但也是地址,大小是4/8字节 printf("%d\n",sizeof(&arr+1));//4 &arr+1是跳过整个数组的地址,但也是地址 printf("%d\n",sizeof(&arr[0]+1));//4 &arr[0]+1是第二个元素的地址 printf("%d\n",strlen(arr));//6 printf("%d\n",strlen(arr+0));//6 //printf("%d\n",strlen(*arr));//err //printf("%d\n",strlen(arr[1]));//err //printf("%d\n",strlen(&arr));//6 &arr 数组的地址-数组指针 char(*p)[7] =&arr; strlen的参数是const char* //printf("%d\n",strlen(&arr+1));//随机值 printf("%d\n",strlen(&arr[0]+1));//5 return 0;}
int main(){
char *p="abcdef"; printf("%d\n",sizeof(p));//4 计算指针变量的大小 printf("%d\n",sizeof(p+1));//4 p+1得到的字符b的地址 printf("%d\n",sizeof(*p));//1 *p就是字符串的第一个字符--a printf("%d\n",sizeof(p[0]));//1 p[0]==*(p+0) =='a' printf("%d\n",sizeof(&p));//4 是取出p的地址,而不是计算数组的大小 printf("%d\n",sizeof(&p+1));//4 取出跳过一个p的地址 printf("%d\n",sizeof(&p[0]+1));//4 取出b的地址 printf("%d\n",strlen(p));//6 printf("%d\n",strlen(p+1));//5 printf("%d\n",strlen(*p));//err printf("%d\n",strlen(p[0]));//err printf("%d\n",strlen(&p));//随机值 取出的是p的地址,p后面\0位置不可知 printf("%d\n",strlen(&p+1));//随机值 printf("%d\n",strlen(&p[0]+1));//5 取出的b的地址

二维数组

int main(){
int a[3][4]={
0}; printf("%d\n",sizeof(a));//48 printf("%d\n",sizeof(a[0][0]));//4 printf("%d\n",sizeof(a[0]));//16 printf("%d\n",sizeof(a[0]+1));//16 -4 a[0]是第一行数组名,数组名此时代表的是首元素地址,a[0]+1 是第二个元素地址 printf("%d\n",sizeof(*(a[0]+1)));//4 printf("%d\n",sizeof(a+1));//4 a是二维数组的数组名,没有sizeof(数组名),也没有&(数组名),所以a是首元素地址,而把二维数组看成一维数组时,二维数组的首元素就是它的第一行,a就是第一行地址,a+1就是第二行地址 printf("%d\n",sizeof(*(a+1)));//4 -16 *(a+1)就是对第二行解引用 printf("%d\n",sizeof(&a[0]+1));//4 printf("%d\n",sizeof(*(&a[0]+1)));//4 -16 &(数组名)代表是第一行数组的地址,&a[0]+1就是第二行地址,对其解引用就是对第二行解引用 printf("%d\n",sizeof(*a));//4 -16 a是首元素地址-第一行地址,*a就是第一行 printf("%d\n",sizeof(a[3]));//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));//2,5 return 0;}

*(a+1),a是数组名,代表的是首元素的地址,a+1就是第二个元素的地址, * (a+1)就是第二个元素。

&a+1 ,&a是取出整个数组的地址,&a+1就是跳过一个数组,指向数组的后一个位置。ptr-1就是指向了数组最后一个元素,解引用得到了数组最后一个元素5
因为a是数组,a的地址类型是char * 所以需要强制类型转化为 int * 才可以存储到ptr中。

第二题

//假设p的值为0x100000,如下表达式的值分别为多少?//已知结构体Test类型的变量大小为20个字节struct Test	{
int Num; char *pcName; short sDate; char cha[2]; short sBa[4]; }*p;int main(){
printf("%p\n",p + 0x1);//0x100014 p是结构体指针,p+0x1 就是p+1,所以就是跳过一个结构体变量大小,就是跳过20个字节,十六进制就是0x100014 printf("%p\n",(unsigned long)p + 0x1);//0x100001 p的类型强制转化为(ungined long),p+1就是加上1。 printf("%p\n",(unsigned int*)p + 0x1);//0x100004 p的类型强制转化为(ungined int*),p+1就是跳过一个指针,大小是4 return 0;}

第三题

int main(){
int a[4] = {
1,2,3,4}; int *ptr1 = (int*)(&a+1);// int *ptr2 = (int*)((int)a+1);//a作为数组名,在这个代表首元素地址,强制转化为int类型,a+1就是往后加一个字节数组内每一个元素都是4个字节,向后加一个字节,00 00 00 02 又因为内存是小端存储,所以以16进制打印,就为0x02000000 printf("%x,%x",ptr1[-1],*ptr2);//4 , 200000 return 0;}

第四题

int main(){
int a[3][2] = {
(0,1),(2,3),(4,5)};//!!!!注意数组内是(0,1)(2,3)(4,5)这是逗号表达式,逗号表达式的结果是最后一个表达式的结果,所以二维数组存的其实是 1 3 5 0 0 0 int *p; p =a[0];//p拿到的是a[0] 也就是数组第一行的地址 printf("%d",p[0]);//1 p[0]就是第一行第一个元素 return 0;}

第五题

int main(){
int a[5][5]; int(*p)[4]; p = a;// p的类型为int(*)[4] a的类型为 int(*)[5] a强制赋值给p,p指向第一行第一个元素 &p[4][2]就是 *((*(p+4))+2) 地址相减就是中间元素的个数,又因为是低地址减去高地址,所以得出的结果是负数 printf("%p,%d\n",&p[4][2]-&a[4][2],&p[4][2]-&a[4][2]);// FFFFFFFC , -4 //-4的原码: 10000000000000000000000000000100 // 反码:11111111111111111111111111111011 // 补码: 1111 1111 1111 1111 1111 1111 1111 1100 // f f f f f f f c 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 //&aa+1 跳过了一整个二维数组,ptr1-1 就指向了10 // *(aa+1) ,aa+1相当于aa[1],ptr2指向了6的地址,ptr2-1就指向5 return 0;}

第七题

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

在这里插入图片描述

最复杂的一道题

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

在这里插入图片描述

注意的一点是 ++cpp 时cpp的值已经加了1,在后续的计算中 不能使用cpp的原始值,而应该是运算后的值。

转载地址:https://blog.csdn.net/xiaotangyu7dong/article/details/116215154 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:入门学习计算机第十七天—字符串函数使用和剖析
下一篇:入门学习计算机第十六天—指针进阶(二)

发表评论

最新留言

感谢大佬
[***.8.128.20]2024年04月03日 15时33分38秒

关于作者

    喝酒易醉,品茶养心,人生如梦,品茶悟道,何以解忧?唯有杜康!
-- 愿君每日到此一游!

推荐文章

02-初始数据库 2019-04-29
03-基础查询和排序 2019-04-29
字节跳动Android金三银四解析:插件化框架解读之android系统服务实现原理,讲的明明白白! 2019-04-29
农民工看完都会了!GitHub上标星13k的《Android面试突击版》,吊打面试官系列! 2019-04-29
升职加薪必看!读完我这份《Android开发核心源码精编解析》面试至少多要3K!附答案 2019-04-29
华为架构师深入讲解Android开发!为什么Flutter能最好地改变移动开发?吐血整理 2019-04-29
基于安卓的兼职app开发!万字长文轻松彻底入门Flutter,终获offer 2019-04-29
大牛深入讲解!2021年Android网络编程总结篇,书籍+视频+学习笔记+技能提升资源库 2019-04-29
大牛深入讲解!算法题+JVM+自定义View,大厂内部资料 2019-04-29
太厉害了!记录一次腾讯Android岗面试笔试总结,全套教学资料 2019-04-29
如何成为杰出的程序员?阿里P8架构师的Android大厂面试题总结,已拿到offer 2019-04-29
字节跳动社招面试记录,关于网络优化你必须要知道的重点,附面试题答案 2019-04-29
大牛手把手带你!宅家36天咸鱼翻身入职腾讯,经典好文 2019-04-29
大牛深入讲解!Android高级工程师面试实战,一线互联网公司面经总结 2019-04-29
如何成为杰出的程序员?2021年Android高级面试题,2年以上经验必看 2019-04-29
字节跳动社招面试记录,2021年上半年最接地气的Android面经,实战解析 2019-04-29
安卓3d游戏开发视频!春招我借这份PDF的复习思路,完整版开放下载 2019-04-29
安卓app开发!大厂Offer拿到手软啊!年薪超过80万! 2019-04-29
安卓ndk开发!高级Android晋升之View渲染机制,附答案 2019-04-29
安卓开发交流!Android程序员架构之路该如何继续学习?含爱奇艺,小米,腾讯,阿里 2019-04-29