当前位置:网站首页>【学习笔记之菜Dog学C】大厂笔试,就这?
【学习笔记之菜Dog学C】大厂笔试,就这?
2022-07-22 20:10:00 【姜君竹】
题一:
//程序的结果是什么?
int main(){
int a[5] = {
1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
printf( "%d,%d", *(a + 1), *(ptr - 1));
return 0;
}
int main(){
int a[5] = {
1, 2, 3, 4, 5 };
int *ptr = (int *)(&a + 1);
//&a取到整个数组的地址,+1跳过这个数组指向下一个地址
//(int *)强转类型
printf( "%d,%d", *(a + 1), *(ptr - 1));
//a+1表示第二个元素的地址,解引用得到第二个元素,也就是2
//ptr - 1得到第五个元素的地址,解引用得到第五个元素,也就是5
return 0;
}

题二:
struct Test
{
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
//假设p 的值为0x100000。 如下表表达式的值分别为多少?
int main()
{
printf("%p\n", p + 0x1);
printf("%p\n", (unsigned long)p + 0x1);
printf("%p\n", (unsigned int*)p + 0x1);
return 0;
}
struct Test
{
int Num;
char* pcName;
short sDate;
char cha[2];
short sBa[4];
}*p;
//1个int4字节,1个char*4字节,1个short2字节
//1个存放两元素的char数组2字节,1个存放四元素的short数组8字节
//所以这个结构体的大小为4+4+2+2+8=20字节
int main()
{
printf("%p\n", p + 0x1);
//0x1表示十六进制下的1
//p是一个结构体指针,p的值为0x100000
//加一就相当于加了20,20换成十六进制就为14
//所以结果为0x100014
printf("%p\n", (unsigned long)p + 0x1);
//(unsigned long)把p的类型强转了,加一就是加一
//结果为0x100001
printf("%p\n", (unsigned int*)p + 0x1);
//(unsigned int*)把p强转成一个int类型的指针
//加一相当于加四
//结果为0x100004
return 0;
}

题三:
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;
}
int main()
{
int a[4] = {
1, 2, 3, 4 };
int* ptr1 = (int*)(&a + 1);
//&a取到整个数组的地址,+1跳过整个数组
//int*强转类型,ptr1每次加减只跳过四个字节
int* ptr2 = (int*)((int)a + 1);
//a代表首元素地址,被强转为int类型,就是一串二进制数
//+1,就是这串二进制数+1,相当于变动了一个字节
//int*强转类型,长度编程4个字节
printf("%x,%x", ptr1[-1], *ptr2);
//ptr[-1]相当于*(ptr1-1),得到结果是4,以十六进制打印还是4
//*ptr2得到的十六进制是2000000
return 0;
}

题四:
int main()
{
int a[3][2] = {
(0, 1), (2, 3), (4, 5) };
int* p;
p = a[0];
printf("%d", p[0]);
return 0;
}
int main()
{
int a[3][2] = {
(0, 1), (2, 3), (4, 5) };
//注意!!!这里是()不是{},有谁上当了我不说话(doge)
//所以a[3][2]实际存放的是{ 1, 3, 5}
int* p;
p = a[0];
//p存放的是数组a[3][2]的第一行地址
printf("%d", p[0]);
//p[0]相当于*p,即*a[0],得到第一行第一个元素,也就是1
return 0;
}

题五:
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;
}
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]);
//两个指针相减得到的是它们之间的元素个数,&p[4][2]与&a[4][2]之间的元素个数为4
//但是地址是从低到高排的,所以结果为-4
//负数在内存中以补码存放
//-4补码:11111111 11111111 11111111 11111100
//%p以指针的形式打印,不会管什么补码原码会
//直接把这串二进制以十六进制的形式打印出来,结果为FF FF FF FC
//%d打印出来的值才是-4
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));
return 0;
}
int main()
{
int aa[2][5] = {
1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
int* ptr1 = (int*)(&aa + 1);
//&aa取到整个数组的地址,+1跳过这个数组
//int*强转类型,ptr1长度为4个字节
int* ptr2 = (int*)(*(aa + 1));
//aa表示第一行地址,+1得到第二行地址
//解引用得到第二行第一个元素的地址
//(int*)是个烟雾弹,有没有它结果都一样
printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));
//ptr1-1得到第二行第五个元素的地址,解引用得到10
//ptr2-1得到第一行第五个元素的地址,解引用得到5
return 0;
}

题七:
int main()
{
char* a[] = {
"work","at","alibaba" };
char** pa = a;
pa++;
printf("%s\n", *pa);
return 0;
}
int main()
{
char* a[] = {
"work","at","alibaba" };
//"alibaba"划重点,说明这是阿里的题(doge)
//char*类型,所以存放的是三个单词的首字母的地址
char** pa = a;
//a表示首元素的地址,一个char*的地址,用二级指针存放
pa++;
//pa++,指向第二个元素
printf("%s\n", *pa);
//pa解引用得到字符串“at”首字母“a”的地址
//%s,从“a”开始打印,遇到“\0”停止
//字符串会自动在末尾加上一个“\0”
//所以打印结果为“at”
//阿里?就这?我,会做!明天,offer!懂?
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);
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" };
//char*类型,所以存放的是三个单词的首字母的地址
char** cp[] = {
c + 3,c + 2,c + 1,c };
char*** cpp = cp;
//cpp存放cp首元素地址
printf("%s\n", **++cpp);
//++cpp存放cp第二个元素的地址,cpp已存放的值已经发生改变
//解引用得到c+2即c第三个元素的地址
//再次解引用得到‘P’的地址
//则%s打印出"POINT"
printf("%s\n", *-- * ++cpp + 3);
//cpp存放的是cp[1]的地址,++cpp则指向cp[2]
//解引用得到“c+1”,--(c+1)得到c,指向‘E’的地址
//‘E’+3得到第二个‘E’的地址
//%s从第二个‘E’开始打印,结果为“ER”
printf("%s\n", *cpp[-2] + 3);
//cpp存放的是cp[2]的地址,cpp[-2]即*(cpp-2),得到“c+3”
//再次解引用,得到‘F’的地址
//‘F’+3得到‘S’的地址
//%s从‘S’开始打印,结果为“ST”
printf("%s\n", cpp[-1][-1] + 1);
//cpp[-1][-1]相当于*(*(cpp-1)-1)
//*(cpp-1)得到“c+2”,c+2-1 == c+1
//*(c+1)得到‘N’的地址
//‘N’+1得到‘E’的地址
//%s从‘E’开始打印,结果为‘EW’
return 0;
}




边栏推荐
- 【计网实验报告】Cisco局域网模拟组建、简单网络测试
- How to delete non system files on disk C. summary of files that can be deleted when disk C is popular
- -bash: wget: 未找到命令
- 用于图像语义分割的GAU与PPM
- 动作活体检测能力,构建安全可靠的支付级“刷脸”体验
- 电脑一拖二显示器分辨率怎么调? 两个显示器设置不同分辨率的技巧
- SQL Server中的STRING_SPLIT函数的实现
- How to restore the computer screen display zoom tutorial when the computer screen becomes larger
- 图像处理解决方案 veImageX 技术演进之路
- redis的持久化
猜你喜欢

Unity 笔记——Addressables的使用

深度学习模型的版权保护研究综述

【JDBC】报错Exception in thread “main”com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communica

postman “status“: 500, “error“: “Internal Server Error“, “message“: “The request was rejecte“

Gb28181 summary of common problems in the use and secondary development of livegbs streaming media service

LUR caching algorithm

标签平滑(label smoothing)

奇瑞艾瑞泽8产品力超能打,“全优”可不是白叫的

浅析缓存的读写策略

在项目开发中的Logback日志框架技术
随机推荐
小黑leetcode之旅:590. N 叉树的后序遍历
Livegbs design document of security camera internet live broadcast scheme
redis常用基础配置文件
再学电商项目之谷粒商城之ES6新特性
怎样删除c盘非系统文件 c盘爆红了可以删除的文件汇总
如何把网站添加为可信任 可信任站点设置教程
Q6ui布局操作
W25Q128FV译文(二)
What does DNS mean? What is the function of DNS
vim文本编辑器
Computer CMD reset network settings CMD command to reset the network
Database system design: partition
LAN SDN technology hard core insider - what's in the prequel CPU?
[matlab project practice] analysis of spatial and temporal characteristics of drought in a region based on SPI index
postman “status“: 500, “error“: “Internal Server Error“, “message“: “The request was rejecte“
电脑如何快速关机 电脑关机命令分享
What key should I press to release the computer from sleep mode when the computer is standby
Q6ui layout operation
用于图像语义分割的GAU与PPM
How to quickly shut down the computer shut down command sharing