指针和数组简单填空题合集(纯刷题:60道)

简介: 指针和数组简单填空题合集(纯刷题:60道)

前言

本篇文章适合初学指针和数组的朋友,如果您看了前几组题觉得很简单,可以看一看我的另一篇文章。

通过本篇文章,你可以清晰的区分出strlen和sizeof的区别,(题目类型包括一维数组、二维数组)并提高自己做这类题熟练度,题目有点多,建议分成两到三次做,下面让我们开始吧。

小建议:先自己做再对答案,不明白可以看解析,如果你赶时间可以看我注释掉的题目,那些是我认为比较容易出错的

一维数组

题目1组

int main()
{
  int a[] = { 1,2,3,4 };
  printf("%d\n", sizeof(a)); 
  printf("%d\n", sizeof(a + 0)); 
  printf("%d\n", sizeof(*a)); 
  printf("%d\n", sizeof(a + 1)); 
  printf("%d\n", sizeof(a[1]));
  printf("%d\n", sizeof(&a)); 
  printf("%d\n", sizeof(*&a));
  printf("%d\n", sizeof(&a + 1)); 
  printf("%d\n", sizeof(&a[0])); 
  printf("%d\n", sizeof(&a[0] + 1)); 
  return 0;
}

答案

16
4/8
4
4/8
4
4/8
16
4/8
4/8
4/8

解析

说明:题号表示对应的题目

1.计算数组总大小,单位是字节,四个int类型的元素,加在一起就是16个字节

2.a+0此时已经不是数组名了,所以大小是4 补充说明: 只有当&数组名和sizeof(数组名)中的数组名才表示整个数组
3.a是首元素地址,*a就是首元素,*a = 1,整型,大小是4
4.a+1类似于a+0
5.a[1] 是第二个元素
6.&a取出数组地址,但数组地址也是一个地址,而地址的大小在32位平台上就是4个字节
7.*&a,取出数组的地址再解引用,等于没有变化。一个数组的地址解引用等于访问一个数组
8.&a取出数组的地址,+1跳过了整个数组,但它本质上还是一个地址,所以大小是4
9.第一个元素的地址,地址大小是4/8
10.第二个元素的地址,地址大小是4/8

题目2组

#include <string.h>
int main()
{
  char arr[] = { 'a','b','c','d','e','f' };
  printf("%d\n", sizeof(arr)); 
  printf("%d\n", sizeof(arr + 0)); 
  printf("%d\n", sizeof(*arr)); 
  printf("%d\n", sizeof(arr[1])); 
  printf("%d\n", sizeof(&arr)); 
  printf("%d\n", sizeof(&arr + 1)); 
  printf("%d\n", sizeof(&arr[0] + 1)); 
  return 0;
}

答案:

6
4/8
1
1
4/8
4/8
4/8

解析

1.计算的是数组大小,单位是字节

2.此处的arr是首元素地址,大小是4/8

3.解引用之后,是字符a,大小是1

4.第二个元素

5.&arr 是数组的地址,大小是4/8

6.&arr+1跳过一个数组,仍是一个地址,大小是4/8

7.计算完是第二个元素的地址,大小是4/8个字节

题目3组

#include <string.h>
int main()
{
  char arr[] = { 'a','b','c','d','e','f' };
  printf("%d\n", strlen(arr)); 
  printf("%d\n", strlen(arr + 0)); 
  //printf("%d\n", strlen(*arr)); 
  printf("%d\n", strlen(arr[1])); 
  printf("%d\n", strlen(&arr)); 
  printf("%d\n", strlen(&arr + 1));
  printf("%d\n", strlen(&arr[0] + 1)); 
  return 0;
}

答案

随机值
随机值
错误❌
错误❌
随机值
随机值
随机值

解析

1.strlen遇到\0停止读取,arr中无\0,所以输出的是随机值

2.arr+0还是arr,结果仍然是随机值

3.

*arr是第一个元素,字符a,而字符a的ascii码值是97,相当于将97传给strlen,但strlen要求传入的是地址,所以他就认为97是地址,strlen函数就访问97这个地址,我们并不知道在地址97处存储的究竟是什么,所以我们也不知道输出结果是什么。在运行的时候程序会直接崩溃(一般是非法访问)(此处不做过多解释,如果看不懂,可以私信我(但这是作者能解释得最清楚的程度了))

4.arr[1]是第二个元素,字符b,类似于上一题,同样是错误的

5.此处传入的是数组arr的地址,那么传入之后,strlen同样从‘a’开始读取,arr末尾没有\0,所以输出随机值

6.从’f’后开始读取,遇到随机的\0之后停止读取

提示:这题的结果与上一题一起运行时,上面的结果比下面的大6

7.从字符b开始读取,数组末尾没有\0,结果是随机值

题目4组

int main()
{
  char arr[] = "abcdef"; 
  printf("%d\n", sizeof(arr)); 
  printf("%d\n", sizeof(arr + 0)); 
  printf("%d\n", sizeof(*arr)); 
  printf("%d\n", sizeof(arr[1])); 
  printf("%d\n", sizeof(&arr)); 
  printf("%d\n", sizeof(&arr + 1)); 
  printf("%d\n", sizeof(&arr[0] + 1)); 
  return 0;
}

答案

7
4/8
1
1
4/8
4/8
4/8

解析

1.数组在初始化时包含\0,所以大小是7

2.arr+0,是首元素地址,大小是4/8

3.*arr,指向第一个元素,是字符类型,大小是1

4.第二个元素,字符类型,大小是1

5.&arr,是数组的地址,是地址,大小是4/8

6.&arr+1,仍然是地址,大小是4/8

7.指向第二个元素,是地址,大小是4/8

题目5组

int main()
{
  char arr[] = "abcdef"; 
  printf("%d\n", strlen(arr));
  printf("%d\n", strlen(arr + 0)); 
  printf("%d\n", strlen(*arr)); 
  printf("%d\n", strlen(arr[1])); 
  printf("%d\n", strlen(&arr)); 
  printf("%d\n", strlen(&arr + 1)); 
  printf("%d\n", strlen(&arr[0] + 1)); 
  return 0;
}

答案

6
6
错误
错误
6
随机值
5

解析

1.strlen遇到\0停止读取,\0不算在内,\0之前有6个元素,所以输出结果是6

2.arr+0,是首元素的地址,数组中有\0,所以结果是6

3.*arr是第一个元素,字符a,类似于上一组题中的第三题,都是传参类型出错,导致非法访问内存

4.传的是第二个元素,同样是非法访问

5.

从第一个地址开始访问,到\0停止访问,\0之前共有六个元素.

提示:数组的地址应存入数组指针型变量里,写成char(*p) = &arr;

而strlen的参数是const char*

此处会报警告,但是也可以强制运行

6.&arr+1,跳过arr数组,也跳过了数组里面的\0,所以结果是随机值

7.&arr[0] + 1,取出第一个元素的地址再加一,此时指向数组里的第二个元素,

从第二个元素到\0之前有5个元素,所以输出结果是5

题目6组

int main()
{
  const char* p = "abcdef"; 
  printf("%d\n", sizeof(p));
  printf("%d\n", sizeof(p + 1)); 
  printf("%d\n", sizeof(*p)); 
  //printf("%d\n", sizeof(p[0])); 
  printf("%d\n", sizeof(&p)); 
  printf("%d\n", sizeof(&p + 1));  
  //printf("%d\n", sizeof(&p[0] + 1)); 
  return 0;
}

答案

4/8
4/8
1
1
4/8
4/8
4/8

解析

//先做一个简单的解释说明,p中存储的是第一个字符的地址

1.p是指针变量,p中存储的是地址,大小是4/8

2.p+1,得到的是第二个元素的地址,仍然是地址,所以大小是4/8

3.对p进行解引用,就是第一个字符,字符a,是字符类型,大小是1

4.

p[0],指的就是第一个元素,字符a,大小是1

补充说明:之前有讲过:数组名arr指的就是首元素的地址,那么就有下面这个等式:arr[0] == *(arr+0),

而p同样是首元素的地址,所以此处就相当于p[0] == *(p+0),即第一个元素

5.取出p的地址,是地址,地址大小是4/8

6.取出数组的地址,再加一,跳过整个数组,得到一个地址,是地址,地址大小是4/8

7.

看起来比较复杂,拆开来看,p[0]就是p,存的是第一个元素的地址,&p[0],就是取出第一个元素的地址,再加一,得到第二个元素的地址,是地址,地址大小是4/8

题目7组

int main()
{
  const char* p = "abcdef";
  printf("%d\n", strlen(p)); 
  printf("%d\n", strlen(p + 1)); 
  printf("%d\n", strlen(*p)); 
  printf("%d\n", strlen(p[0])); 
  printf("%d\n", strlen(&p)); 
  printf("%d\n", strlen(&p + 1)); 
  printf("%d\n", strlen(&p[0] + 1)); 
  return 0;
}

答案

6
5
错误
错误
随机值
随机值
5

解析

1.传入p,p中存储的是第一个元素的地址,传入strlen函数,输出元素个数:6

2.p+1,相当于&p[1],是第二个元素的地址,输出结果为5

3.*p传入的是a,直接报错

4.p[0]就是*p,程序报错

5.p中存储的是a的地址,取出指针变量p的地址,从变量p的地址处向后读取,而不是在字符串内读取,所以结果是随机值

6.同样是随机值

7.相当于p[1],是第二个元素的地址,结果是5

二维数组

题目

int main()
{
  int a[3][4] = { 0 };
  printf("%d\n", sizeof(a)); 
  printf("%d\n", sizeof(a[0][0])); 
  printf("%d\n", sizeof(a[0])); 
  printf("%d\n", sizeof(a[0] + 1)); 
  printf("%d\n", sizeof(*(a[0] + 1))); 
  //printf("%d\n", sizeof(a + 1)); 
  printf("%d\n", sizeof(*(a + 1))); 
  //printf("%d\n", sizeof(&a[0] + 1));
  printf("%d\n", sizeof(*(&a[0] + 1)));  
  printf("%d\n", sizeof(*a)); 
  //printf("%d\n", sizeof(a[3])); 
  return 0;
}

答案

48
4
16
4
4
4/8
16
4/8
16
16
16

解析

//简单解释:三行四列的二维数组

1.数组里有12个元素,大小是48个字节

2.第一个元素,是int类型,大小是4

3.指的是第一行元素,四个元素,大小是16

补充说明:可以认为该二维数组有三个元素,一行是一个元素,那么a[0]相当于第一行元素的数组名,也就是第一行的元素

4.上面提到a[0]是第一行元素的数组名,那么+1,指向的就是第一行的第二个元素,是int类型,大小是4个字节

补充说明:只有当数组名单独的放在sizeof内部时,数组名才是整个数组

5.对于第一行第二个元素的地址进行解引用,结果就是第二个元素,是int类型,大小是4

6.

a+1是地址,是指向第二行元素的地址,大小是4/8

解释说明:二维数组的数组名是首元素的地址,即第一行元素的地址,那么与整数运算时,单位是第一行元素的大小,所以指向的是第二行元素

7.第二行的地址解引用,是第二行元素,是四个int型,大小是16

8.

第二行的地址,是地址,地址大小是4/8

解释说明:a[0]就相当于第一行的数组名,数组名取地址,取出第一行的地址,再加一,得到第二行的地址

9.第二行的地址进行解引用,得到第二行四个int型的数据,大小是16

10.a是数组首元素地址,即第一行地址,解引用后得到第一行四个int类型的数据,大小是16

11.

a[3],类似于a[0],放入的是具有四个int类型的一维数组,大小是16

补充说明:sizeof中的表达式不参与真实运算,所以他并不会去访问第四行,这道题只是将a[3]放入其中,这类似于放入a[0]

小提示

做这类题,首先要明确数组名在这里究竟代表什么,是首元素地址?还是数组地址,之后再去运算就会方便一些

结语

刷题到这里就结束了,下一篇文章我会整理一些指针的面试题,来帮助大家更好的理解指针。

我们下篇文章见~


相关文章
|
11月前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
127 3
|
11月前
|
存储 程序员 编译器
C 语言数组与指针的深度剖析与应用
在C语言中,数组与指针是核心概念,二者既独立又紧密相连。数组是在连续内存中存储相同类型数据的结构,而指针则存储内存地址,二者结合可在数据处理、函数传参等方面发挥巨大作用。掌握它们的特性和关系,对于优化程序性能、灵活处理数据结构至关重要。
|
11月前
|
存储 NoSQL 编译器
C 语言中指针数组与数组指针的辨析与应用
在C语言中,指针数组和数组指针是两个容易混淆但用途不同的概念。指针数组是一个数组,其元素是指针类型;而数组指针是指向数组的指针。两者在声明、使用及内存布局上各有特点,正确理解它们有助于更高效地编程。
|
11月前
|
存储 C语言 计算机视觉
在C语言中指针数组和数组指针在动态内存分配中的应用
在C语言中,指针数组和数组指针均可用于动态内存分配。指针数组是数组的每个元素都是指针,可用于指向多个动态分配的内存块;数组指针则指向一个数组,可动态分配和管理大型数据结构。两者结合使用,灵活高效地管理内存。
|
11月前
|
容器
在使用指针数组进行动态内存分配时,如何避免内存泄漏
在使用指针数组进行动态内存分配时,避免内存泄漏的关键在于确保每个分配的内存块都能被正确释放。具体做法包括:1. 分配后立即检查是否成功;2. 使用完成后及时释放内存;3. 避免重复释放同一内存地址;4. 尽量使用智能指针或容器类管理内存。
|
11月前
|
存储 人工智能 算法
数据结构实验之C 语言的函数数组指针结构体知识
本实验旨在复习C语言中的函数、数组、指针、结构体与共用体等核心概念,并通过具体编程任务加深理解。任务包括输出100以内所有素数、逆序排列一维数组、查找二维数组中的鞍点、利用指针输出二维数组元素,以及使用结构体和共用体处理教师与学生信息。每个任务不仅强化了基本语法的应用,还涉及到了算法逻辑的设计与优化。实验结果显示,学生能够有效掌握并运用这些知识完成指定任务。
201 4
|
11月前
使用指针访问数组元素
【10月更文挑战第31天】使用指针访问数组元素。
119 2
|
11月前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
106 1
|
12月前
|
存储
如何使用指针数组来实现动态二维数组
指针数组可以用来实现动态二维数组。首先,定义一个指向指针的指针变量,并使用 `malloc` 为它分配内存,然后为每个子数组分配内存。通过这种方式,可以灵活地创建和管理不同大小的二维数组。
|
12月前
|
存储
如何通过指针数组来实现二维数组?
介绍了二维数组和指针数组的概念及其区别,详细讲解了如何使用指针数组模拟二维数组,包括定义与分配内存、访问和赋值元素、以及正确释放内存的步骤,适用于需要动态处理二维数据的场景。