当前位置:网站首页>【数组和进阶指针经典笔试题12道】这些题,满足你对数组和指针的所有幻想,come on !
【数组和进阶指针经典笔试题12道】这些题,满足你对数组和指针的所有幻想,come on !
2022-07-05 14:34:00 【每天都要坚持刷题】
众所周知,指针是C语言的灵魂,很多人就是倒在指针的脚下。今天,我来带大家看一看指针在笔试中是怎么考的吧!(提示:本篇博客测试环境是vs-x64,该环境下指针占8个字节)
练习题1
int main()
{
int a[4] = { 1,2,3,4 };
printf("%u\n", sizeof(a));//16-sizeof(数组名)-整个数组
printf("%u\n", sizeof(a+0));//8-不是单独的数组名-数组首元素的地址
printf("%u\n", sizeof(*a));//4-数组首元素的地址解引用-数组首元素
printf("%u\n", sizeof(a+1));//8-数组第2个元素的地址
printf("%u\n", sizeof(a[1]));//4-数组第2个元素
printf("%u\n", sizeof(&a));//8-整个数组的地址
printf("%u\n", sizeof(*&a));//16-对整个数组的地址解引用,得到的是整个数组-sizeof(数组名)
printf("%u\n", sizeof(&a+1));//8-&a是整个数组的地址,+1跳过一个数组,还是一个数组的地址
printf("%u\n", sizeof(&a[0]));//8-首元素的地址
printf("%u\n", sizeof(&a[0]+1));//8-第2个元素的地址
return 0;
}
练习题2
int main()
{
char str[5] = { 'a','b','c','d','e' };
printf("%d\n", sizeof(str));//5-sizeof(数组名)-整个数组
printf("%d\n", sizeof(str+0));//8-数组首元素的地址
printf("%d\n", sizeof(*str));//1-数组首元素
printf("%d\n", sizeof(str[1]));//1-数组第二个元素
printf("%d\n", sizeof(&str));//8
printf("%d\n", sizeof(&str[0]+1));//8
printf("%d\n", sizeof(str[0]+1));//4-字符和整型相加-整型提升
//等价于printf("%d\n", sizeof('a'+1));//4-整型提升
return 0;
}
练习题3
int main()
{
char str[] = { 'a','b','c','d','e' };
printf("%d\n", strlen(str));//随机值
printf("%d\n", strlen(str+0));//随机值
printf("%d\n", strlen(*str));//strlen('a')-->strlen(97);//野指针
printf("%d\n", strlen(str[1]));//野指针
printf("%d\n", strlen(&str));//随机值
printf("%d\n", strlen(&str+1));//随机值
printf("%d\n", strlen(&str[0]+1));//随机值
return 0;
}
这里的第三个printf处如果调试的话,这个错误代表的意思就是访问了非法内存(有一些内存地址是没有办法访问的,有一些是允许访问,但是也会进行一定的检测)
关于sizeof和strlen:
strlen是求字符串长度的,关注的是字符串中的'\0',计算的是\0之前出现字符的个数
strlen是库函数,只针对字符串
sizeof只关注占用内存的大小,不在乎内存中放的是什么
sizeof是操作符
练习题4
int main()
{
int a[3][4] = { 0 };
printf("%d\n", sizeof(a));//3*4*4=48-整个二维数组
printf("%d\n", sizeof(a[0]));//8错//4*4=16对 sizeof(一维数组数组名)-整个第一个一维数组
printf("%d\n", sizeof(a[0]+1));//8-第2个一维数组的地址
printf("%d\n", sizeof(a[0][0]));//4-第一个一维数组的第1个元素
printf("%d\n", sizeof(*(a[0]+1)));//4-第一个一维数组的第2个元素
printf("%d\n", sizeof(*(a+1)));//8错//4*4=16对 sizeof(一维数组数组名)-整个第2个一维数组
printf("%d\n", sizeof(a+1));//8-第2个一维数组的地址
printf("%d\n", sizeof(&a[0]+1));//8-第一个一维数组的第2个元素
printf("%d\n", sizeof(*a));//4*4=16-整个第一个一维数组
printf("%d\n", sizeof(a[3]));//16-整个第四个一维数组
return 0;
}
练习题5
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;
}
练习题6
struct Test
{
int num1;
char* num2;
short num3;
char num4[2];
short num5[4];
}*p;
//假设p的值为0x100000,如下表达式的值分别是多少?
//已知在当前环境下,Test类型的变量大小是20个字节
//考察:指针/整数+1到底是加了多少
int main()
{
printf("%p\n", p + 0x1);//0x100014
printf("%p\n", (unsigned long)p + 0x1);//0x100001
printf("%p\n", (unsigned int*)p + 0x1);//0x100004
return 0;
}
0x1就是十六进制的1,也就是十进制的1:
对于第一个p+0x1中p是struct Test* 类型的指针,加1,跳过一个sizeof(struct Test)==20,也就是0x00014大小。
同理第二个p是被强制转换为了unsigned long类型,是一个整数,整数=1就是+1,然后按照%p打印出来,加的因为就是1(没有超过16),所以和在原来的0x10000上加1是一样的。
同理第三个p是被强制转换为了unsigned int*类型,加1,加的是4个字节。
练习题7
int main()
{
int a[4] = { 1,2,3,4 };
int* ptr1 = (int*)(&a + 1);
int* ptr2 = (int*)(a + 1);
int* ptr3 = (int*)((int)a + 1);
int* ptr4 = (int*)((char*)a + 1);
printf("%x %x %x %x\n\n", ptr1[-1], *ptr2,*ptr3,*ptr4);//
return 0;
}
ptr3得到的方式是:
通过将整型指针强制转换为整型数值,然后加1,最后再强制转换为整型指针;
ptr4得到的方式是:
通过将整型指针强制转换为字符指针,然后加1,最后再强制转换为整型指针。
两个的效果是一样的。
练习题8
int main()
{
int a[3][2] = { (0,1),(2,3),(3,4) };//坑点:逗号表达式
int* p;
p = a[0];
printf("%d\n", p[0]);
//等价于printf("%d\n", *p);
return 0;
}
练习题9
int main()
{
int a[4][5];
int(*p)[3];//重点在于这里的3,不是5
p = a;
printf("%p %d\n", &p[3][2] - &a[3][2], &p[3][2] - &a[3][2]);
return 0;
}
关于-6变FFFFFA:
练习10
int main()
{
int a[2][5] = { 1,2,3,4,5,6,7,8,9,10 };
int* ptr1 = (int*)(&a + 1);
int* ptr2 = (*(a + 1));
//等价于int* ptr2 = (int*)(a + 1);
printf("%d %d\n", *(ptr1 - 1), *(ptr2 - 1));//10 5
return 0;
}
练习11
int main()
{
char* a[] = { "I will work","at","alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
练习题12
int main()
{
char* c[] = { "ENTRE","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;
}
下面是我自己的理解方式:
[]和*都可以过桥(也就是找到指针所指向的那个目标), cpp[-1]就是指向的*(cpp-1),就是先指针-1(指向发生改变),然后过桥(找到指针指向的那个目标);
然后这里的虚线就是不会有自增++有副作用
a=a+1;有副作用(a变了)
但是a+1;就没有副作用(a没有变)
边栏推荐
- LeetCode_ 3 (longest substring without repeated characters)
- 总量分析 核算方法和势方法 - 分摊分析
- How to deeply understand the design idea of "finite state machine"?
- 超级哇塞的快排,你值得学会!
- R language ggplot2 visualization: use ggplot2 to visualize the scatter diagram, and use the labs parameter to customize the X axis label text (customize X axis labels)
- 网上电子元器件采购商城:打破采购环节信息不对称难题,赋能企业高效协同管理
- How to choose the appropriate certificate brand when applying for code signing certificate?
- 【leetcode周赛总结】LeetCode第 81 场双周赛(6.25)
- 在Pytorch中使用Tensorboard可视化训练过程
- 不相交集
猜你喜欢
Opengauss database source code analysis series articles -- detailed explanation of dense equivalent query technology (Part 2)
ASP. Net large takeout ordering system source code (PC version + mobile version + merchant version)
Loop invariant
Thymeleaf th:with use of local variables
freesurfer运行完recon-all怎么快速查看有没有报错?——核心命令tail重定向
Why do mechanical engineers I know complain about low wages?
Share 20 strange JS expressions and see how many correct answers you can get
世界环境日 | 周大福用心服务推动减碳环保
APR protocol and defense
How can non-technical departments participate in Devops?
随机推荐
freesurfer运行完recon-all怎么快速查看有没有报错?——核心命令tail重定向
TS所有dom元素的类型声明
Thymeleaf 常用函数
矩阵链乘 - 动态规划实例
Topology visual drawing engine
Thymeleaf th:with use of local variables
【leetcode周赛总结】LeetCode第 81 场双周赛(6.25)
【学习笔记】阶段测试1
[learning notes] stage test 1
World Environment Day | Chow Tai Fook serves wholeheartedly to promote carbon reduction and environmental protection
R Language ggplot2 Visualization: visualize linegraph, using Legend in Theme function. Paramètre de position emplacement de la légende personnalisée
Total amount analysis accounting method and potential method - allocation analysis
Security analysis of Web Architecture
Two policemen were shot dead in a "safety accident" in Philadelphia, USA
【招聘岗位】基础设施软件开发人员
R language ggplot2 visualization: visual line graph, using legend in theme function The position parameter defines the position of the legend
Opengauss database source code analysis series articles -- detailed explanation of dense equivalent query technology (Part 2)
What about SSL certificate errors? Solutions to common SSL certificate errors in browsers
openGauss数据库源码解析系列文章—— 密态等值查询技术详解(下)
ASP. Net large takeout ordering system source code (PC version + mobile version + merchant version)