指针和数组笔试题解析(最详细解析,没有之一)

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: 指针和数组笔试题解析(最详细解析,没有之一)

前言

指针和数组在许多编程场景中经常结合使用,比如通过指针来访问数组的元素、通过指针来遍历数组等。指针和数组的灵活应用可以帮助我们更好地处理和操作数据,提高程序的性能和效率,指针和数组在C语言中具有重要的地位和作用,它们是程序设计中不可或缺的重要概念。本文将详细解析指针和数组相关笔试题!!

1. 一维数组和指针相关笔试题

题目及解析:

int main()
{
  int a[] = { 1,2,3,4 };

  printf("%d\n", sizeof(a));  //数组名单独放在sizeof内部,这里a表示整个数组,计算的是整个数组,为16(4*4)个字节
  printf("%d\n", sizeof(a + 0));//a表示首元素的地址,a+0还是表示首元素地址,是地址就是4/8个字节
  printf("%d\n", sizeof(*a)); //a表示首元素地址,*a表示首元素,大小为4个字节
  printf("%d\n", sizeof(a + 1));//a表示首元素地址,arr+1跳过一个整型长度指向第二个元素(2)的地址,是地址大小就是4/8个字节
  printf("%d\n", sizeof(a[1]));//a[1]取出的是第二个元素2,为int类型,大小为4个字节
  printf("%d\n", sizeof(&a)); //&a取出的是整个数组的地址,但只要是地址,大小都是4/8个字节

  printf("%d\n", sizeof(*&a));  
  //解读一:sizeof(*&a) ---> sizeof(a) ---> 同第一个为16字节
  //解读二:由于我们熟知对整型指针进行解引用得到的是整型;对字符指针进行接引用得到的是一个字符
  //      这里&a表示数组指针,类型为int (*)[4],对它进行解引用操作得到的是一个数组,即*&a表示整个数组,大小为4*4即16个字节

  printf("%d\n", sizeof(&a + 1));
  //&a取出的是整个数组,&a+1跳过整个数组,指向的是第四个元素4的下一个元素的地址
  //但是地址大小就是4/8个字节

  printf("%d\n", sizeof(&a[0]));//&a[0]取出的是第一个元素1的地址,大小为4/8个字节
  printf("%d\n", sizeof(&a[0] + 1));//&a[0]+1表示取出首元素地址后向后移动一个整型字长,指向第二个元素2的地址,为4/8个字节

  return 0;
}

x64环境下运行结果:

2. 字符数组和指针相关笔试题

2.1 题型一:

题目及解析:

int main()
{
  char arr[] = { 'a','b','c','d','e','f' };
  
  printf("%d\n", sizeof(arr));//数组名单独放在sizeof内部,这里的arr表示整个数组,计算的是整个数组的大小,单位是字节,总共6个字节
  printf("%d\n", sizeof(arr + 0));//arr表示数组首元素的地址,arr+0还是数组首元素的地址,是地址就是4/8个字节
  printf("%d\n", sizeof(*arr));//arr表示数组首元素的地址,*arr就是首元素,大小1个字节
  printf("%d\n", sizeof(arr[1]));//arr[1]就是第二个元素,大小是1个字节

  printf("%d\n", sizeof(&arr));//&arr是数组的地址,但是数组的地址也是地址,是地址就是4/8

  printf("%d\n", sizeof(&arr + 1));//&arr + 1是跳过整个数组后的地址,是地址就是4/8个字节
  printf("%d\n", sizeof(&arr[0] + 1));//第二个元素的地址,是4/8个字节
  return 0;
}

x64环境下运行结果:

2.2 题型二:

题目及解析:

int main()
{
  char arr[] = { 'a','b','c','d','e','f' };
  printf("%d\n", strlen(arr));//因为字符数组arr中没有\0,所以在求字符串长度的时候,会一直往后找,产生的结果就是随机值
  printf("%d\n", strlen(arr + 0));//arr + 0是首元素的地址,和第一个一样,也是随机值

  //printf("%d\n", strlen(*arr));//err, arr是数组首元素的地址,*arr就是数组首元素,就是'a'-97
  //strlen函数参数的部分需要传一个地址,当我们传递的是'a'时,'a'的ascii码值是97,那就是将97作为地址传参
  //strlen就会从97这个地址开始统计字符串长度,这就非法访问内存了
  //printf("%d\n", strlen(arr[1]));//err

  printf("%d\n", strlen(&arr));//&arr是数组的地址,数组的地址和数组首元素的地址,值是一样的
                 //那么传递给strlen函数后,依然是从数组的第一个元素的位置开始往后统计,结果为随机值

  printf("%d\n", strlen(&arr + 1));//&arr+1,跳过整个数组,结果为随机值
  printf("%d\n", strlen(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址,结果为随机值
  return 0;
}

x64环境下运行结果:

2.3 题型三:

题目及解析:

int main()
{
  char arr[] = "abcdef";//[a b c d e f \0]
  printf("%d\n", sizeof(arr));//数组中共有7个元素,结果为7

  printf("%d\n", sizeof(arr + 0));//arr + 0是首元素的地址,结果为4/8
  printf("%d\n", sizeof(*arr));//*arr其实就是首元素,1个字节
  //*arr--> *(arr+0) -- arr[0]

  printf("%d\n", sizeof(arr[1]));//arr[1]是第二个元素,1个字节
  printf("%d\n", sizeof(&arr));//&arr是数组的地址,是地址就是4/8个字节
  printf("%d\n", sizeof(&arr + 1));//&arr + 1是跳过一个数组的地址,4/8
  printf("%d\n", sizeof(&arr[0] + 1));//&arr[0] + 1是第二个元素的地址 4/8
  return 0;
}

x64环境下运行结果:

2.4 题型四:

题目及解析:

int main()
{
  char arr[] = "abcdef";//[a b c d e f \0]

  printf("%d\n", strlen(arr));//6
  printf("%d\n", strlen(arr + 0));//6

  //printf("%d\n", strlen(*arr));//err,传的是首元素a
  //printf("%d\n", strlen(arr[1]));//err,传的是第二个元素b
  //strlen需要传过去的是指针,如果传字符会造成非法访问内存,报错

  printf("%d\n", strlen(&arr));//6
  printf("%d\n", strlen(&arr + 1));//&arr+1跳过整个数组,导致数组后面\0没有明确位置,导致结果为随机值
  printf("%d\n", strlen(&arr[0] + 1));//从第二个元素开始向后访问,结果为5
  return 0;
}

x64环境下运行结果:

3. 指针和字符串相关面试题

3.1 题型一:

题目及解析:

int main()
{
  char* p = "abcdef";
  
  printf("%d\n", sizeof(p));//p是一个指针变量,大小就是4/8个字节
  printf("%d\n", sizeof(p + 1));//p+1是'b'的地址,是地址大小就是4/8个字节
  
  printf("%d\n", sizeof(*p));//*p 就是'a',就是1个字节
  printf("%d\n", sizeof(p[0]));//p[0]--> *(p+0) --> *p ,大小为1个字节

  printf("%d\n", sizeof(&p));//&p -- char**,二级指针也是指针大小为4/8个字节
  printf("%d\n", sizeof(&p + 1));//*p+1本质上还是一个指针,大小为4/8个字节
  printf("%d\n", sizeof(&p[0] + 1));//4/8 , &p[0] + 1得到是'b'的地址 

  return 0;
}

x64环境下运行结果:

3.2 题型二:

**题目及解析:

//由于原理和上面完全一样,所以在此就不再累赘了
int main()
{
  char* p = "abcdef";

  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));//随机值
  printf("%d\n", strlen(&p + 1));//随机值
  printf("%d\n", strlen(&p[0] + 1));//5
  return 0;
}

x64环境下运行结果:

4. 二位数组和指针相关面试题

**题目及解析:

int main()
{
  int a[3][4] = { 0 };

  printf("%d\n", sizeof(a));//sizeof(数组名)不管是一维数组还是二维数组都是表示整个数组,结果为3*4*4 = 48
  printf("%d\n", sizeof(a[0][0]));//大小为4

  printf("%d\n", sizeof(a[0]));//a[0]是第一行这个一维数组的数组名
  //数组名算是单独放在sizeof内部了,计算的是整个数组的大小,大小是16个字节

  printf("%d\n", sizeof(a[0] + 1));
  //a[0]作为第一行的数组名,没有单独放在sizeo内部,没有&
  //a[0]表示数组首元素的地址,也就是a[0][0]的地址
  //所以a[0]+1是第一行第二个元素的地址,是地址就是4/8个字节
  //
  printf("%d\n", sizeof(*(a[0] + 1)));//4
  //计算的是就是第一行第2个元素的大小

  printf("%d\n", sizeof(a + 1));//4 / 8
  //a是数组首元素的地址,是第一行的地址 int(*)[4]
  //a+1 就是第二行的地址

  printf("%d\n", sizeof(*(a + 1)));//16
  //*(a+1) --> a[1] -> sizeof(*(a+1))->sizeof(a[1]) 计算的是第二行的大小
  //a+1 --> 是第二行的地址,int(*)[4]
  //*(a+1) 访问的第二行的数组

  printf("%d\n", sizeof(&a[0] + 1));//4/8
  //&a[0]是第一行的地址 int(*)[4]
  //&a[0]+1 是第二行的地址 int(*)[4]

  printf("%d\n", sizeof(*(&a[0] + 1)));//16 计算的是第二行的大小

  printf("%d\n", sizeof(*a));//计算的是第一行的大小-16
  //a是数组首元素的地址,就是第一行的地址
  //*a 就是第一行
  //*a --> *(a+0) --> a[0]

  printf("%d\n", sizeof(a[3]));//16
  //sizeof在计算其大小时,其背后原理是sizeof操作符只关心其类型,根据类型来计算大小
  //并不会真正的访问内存,所以在此所谓的数组越界对sizeof计算其大小并没有太大关系
  return 0;
}

x64环境下运行结果:

5. 总结

1. sizeof(数组名),这里的数组表示的是整个数组,不管是一维数组还是二维数组计算的都是整个数组的大小。

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

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

4. sizeof计算大小时,其工作原理是根据其类型来判断的,并不会真正访问内存来计算大小。所以在计算数组大小过程中,即使出现数组越界,但对sizeof来说没有影响,依然可以计算其大小。

6. 结尾

本篇文章到此就结束了。创作不易,如果对你有帮助记得点赞加收藏哦。感谢您的支持!!


相关文章
|
1月前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
35 3
|
17天前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
21天前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
21天前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
21天前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
25天前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
44 4
|
1月前
使用指针访问数组元素
【10月更文挑战第31天】使用指针访问数组元素。
40 2
|
1月前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
39 1
|
2月前
|
人工智能 前端开发 JavaScript
拿下奇怪的前端报错(一):报错信息是一个看不懂的数字数组Buffer(475) [Uint8Array],让AI大模型帮忙解析
本文介绍了前端开发中遇到的奇怪报错问题,特别是当错误信息不明确时的处理方法。作者分享了自己通过还原代码、试错等方式解决问题的经验,并以一个Vue3+TypeScript项目的构建失败为例,详细解析了如何从错误信息中定位问题,最终通过解读错误信息中的ASCII码找到了具体的错误文件。文章强调了基础知识的重要性,并鼓励读者遇到类似问题时不要慌张,耐心分析。
|
2月前
|
存储
如何使用指针数组来实现动态二维数组
指针数组可以用来实现动态二维数组。首先,定义一个指向指针的指针变量,并使用 `malloc` 为它分配内存,然后为每个子数组分配内存。通过这种方式,可以灵活地创建和管理不同大小的二维数组。

推荐镜像

更多