【学习笔记之我要C】大厂笔试,就这?

简介: 【学习笔记之我要C】大厂笔试,就这?

题一:

//程序的结果是什么?
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; 
}

7c6fa8c00de2491d80450001c5414467.png

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

dc33c1db93a842ef964ab956cbc47f7e.png

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

7aaa3cefb602432e9dda03fe801f64f4.png

题四:

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

143b0e18f1694d68ab463a196f0525a1.png

题五:

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

a1b4168a4f9b488da23af7850db44f19.png

题六:

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

8eba9eadc55043358f507ba08d0c81a0.png

题七:

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

18383a4cffee4734a764523a5c6a7fe8.png

题八:

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

7ae67131b53448cda7d2669d4b8040a8.png

d882ef2dee4a4121894c48aa510bc5be.pnga24a0d1f0fd44d1b85ff73a1164db21e.pngaa2eb5f2f27444378794220aa48b6f5a.png



目录
相关文章
|
13天前
|
网络协议 安全 测试技术
360培训题库9-13
360培训题库9-13
7 0
|
2月前
|
测试技术
蓝桥杯刷题|02入门真题
蓝桥杯刷题|02入门真题
|
2月前
|
测试技术
蓝桥杯刷题|03入门真题
蓝桥杯刷题|03入门真题
|
9月前
|
编译器 C语言
【面试笔试避坑指南】一
【面试笔试避坑指南】一
44 0
|
12月前
|
存储 编解码 关系型数据库
大学计算机基础-题库刷题-精选(一)
大学计算机基础-题库刷题-精选(一)
178 0
|
12月前
|
芯片
大学计算机基础-题库刷题-精选(二)
大学计算机基础-题库刷题-精选(二)
57 0
|
11月前
|
SQL 算法 Java
第一次笔试【面试】
第一次笔试【面试】
86 0
|
12月前
|
缓存 网络协议 网络架构
大学计算机基础-题库刷题-精选(三)
大学计算机基础-题库刷题-精选(三)
112 0
|
12月前
大学计算机基础-题库刷题-精选(四)
大学计算机基础-题库刷题-精选(四)
66 0
|
存储 编解码 安全
题库——“计算机基础”
题库——“计算机基础”