C语言: 数组指针/指针数组等相关的选择题目

简介: C语言: 数组指针/指针数组等相关的选择题目

写在前面

本篇总结的是和指针相关的有难度的选择题,并对这些题进行解析和分析

形参和实参

下面程序的运行结果是什么?

#include <stdio.h>
void func(char* p)
{
  p = p + 1;
}
int main()
{
  char s[] = { '1','2','3','4' };
  func(s);
  printf("%c", *s);
  return 0;
}

首先传参是数组名,这里的数组名代表的是首元素的地址,但传过去的并不是数组名的地址,func函数内部对p的改变不改变外部数组s,因此输出的应该为1

二维数组传参

已知数组D的定义是int D[4][8],现在要把这个数组作为实参传递给一个函数处理,下列可以作为形参变量的是

A. int D[4][] B. int *s[8] C. int(*s)[8] D. int D[][8]

这里的数组D是一个二维数组,那么就首先要清楚二维数组传参传的是什么,二维数组传参传递的是二维数组中首元素的地址,也就是第一个一维数组的地址,也就是数组指针

数组指针是一个指向数组的指针

int *s[8] -> 这是指针数组,数组名是s,里面存着8个指针

int (*s)[8] -> 这是数组指针,指针名是s,指针指向一个大小为8的数组

因此这里ABCD中要选一个数组指针,因此选的是C

字符数组

下面程序的运行结果是什么?

#include <stdio.h>
void fun(char** p)
{
  int i;
  for (i = 0; i < 4; i++)
  {
    printf("%s", p[i]);
  }
} 
int main()
{
  char* s[6] = { "ABCD", "EFGH", "IJKL", "MNOP", "QRST", "UVWX" };
  fun(s);
  printf("\n");
  return 0;
}

char类型的数组内只能存储单个字符,这里改成了char*类型的数组,意思就是存储的是这些字符串的地址,因为一个字符串会被编译器看成const char*类型,因此存储到数组中相应的数组的类型就是char*类型的数组

而fun函数传参,传的是数组,数组名代表的是首元素的地址,因此接收函数的形参类型就是char**

而函数中的p[i]又可以看成是*(p+i),因此输出的就是ABCDEFGHIJKLMNOP

二维数组

数组a的定义为int a[3][4],下面哪个不能表示a[1][1]

A. *(&a[0][0]+5) B. *(*(a+1)+1) C. *(&a[1]+1) D. *(a[1]+1)

先看A选项,&a[0][0]表示二维数组中元素的地址,该元素的地址+5表示向后加5个元素的地址,再对该地址进行解引用,得出的就是a[1][1]

再看B选项,*(a+1)表示的就是a[1],而*(a[1]+1)表示的就是a[1][1]

再看C选项,应该改为*(&a[1][0]+1),因为a[1]就表示a[1][0]的地址

D选项,由B选项可知这是正确的

函数指针数组

void (*s[5])(int) 是什么意思?

这里涉及到的是函数指针数组的概念,s首先和[]结合,证明这里的s是一个数组,数组中存储的内容类型是void (*)(int),那这又是什么?这就是函数指针,该指针指向的函数的参数是int,返回类型是void

参数匹配

  1. 下面参数调用匹配的是
void f(int** p);
int a[4] = { 1,2,3,4 };
int b[3][4] = { {1,2,3,4},{5,6,7,8},{9,10,11,12} };
int* q[3] = { b[0],b[1],b[2] };
A.f(a) B.f(b)  C.f(q)  D.f(&a) 

这里需要f函数的参数是int**,意味着传参的参数要和这个匹配

A:如果传参的参数是a,这里的a代表的是首元素的地址,对应的参数应该是int*

B:如果传参的参数是b,由于b是二维数组,传参传的是二维数组中第一个数组的地址,传的是数组指针,对应的参数是int (*)[]

C:这个是符合的,传参首元素的地址,对应的是int**

D:&a表示的取出的是整个数组的地址,和A选项从数值上来看是一样的,区别是+1的问题

  1. 有定义语句:char s[3][10],(*k)[3],*p,下面赋值错误的是

p=s; p=k; p=s[0]; k=s;

因此这里就要看s,k,s[0],p分别代表什么类型了

首先看s:s是二维数组,因此这里s的类型是数组指针->char (*)[]

再看k:k就是数组指针,类型和s相同char (*)[]

再看s[0]:s[0]是二维数组中第一行数组,因此s[0]是一个一维数组,对应类型就是char*

最后是p:p类型是char*,这个很明显

因此赋值等号两边类型得相同,因此第一个第三个第四个都不同

  1. 下面对fun函数调用正确的是:
char fun(char*);
int main()
{
  char* s = "one";
  char a[5] = { 0 };
  char (*f1)(char*) = fun;
  char ch;
  return 0;
}

A: *f1(&a);

B: f1(*s);

C: f1(&ch);

D: ch = *f1(s);要改成(*f1)(s)才正确

首先看函数,定义了一个字符串s,第二个定义了一个字符数组,内的元素都是0,重点看f1:

f1是函数指针,f1指向的函数参数是char*,返回值是char,也就是说f1是函数fun的指针

那么分析选项:

首先要分清楚,(*f1)(&a)f1(&a)*f1(&a)

在函数指针调用中(*f1)(&a)f1(&a)效果是一样的,但是*f1(&a)会被认为是对返回值的解引用

A: *f1(&a);:括号的优先级大于解引用,&a表示的是取出数组a的地址,类型是char*符合函数指针调用参数,因此f1(&a)会返回char类型的数据,但对它解引用这是错误的

B: f1(*s);:*s参数不匹配

C: f1(&ch);:没问题

D: ch = *f1(s);要改成(*f1)(s)才正确:区分清上面的含义这个不难理解

多级指针

下面程序运行结果是?

#include<stdio.h>
int main()
{
  static char* s[] = { "black", "white", "pink", "violet" };
  char** ptr[] = { s + 3, s + 2, s + 1, s }, *** p;
  p = ptr;
  ++p;
  printf("%s", **p + 1);
  return 0;
}

首先定义了s数组,里面存的是字符串首元素的地址

下面的ptr是二级指针,存储的是s数组的,拿其中一个进行分析,ptr数组中存储的s+1,实际上对应的是s数组中下标为1的元素对应的地址,而又由于s数组中下标为1的元素是一个指针,因此这里ptr存储的是一个二级指针

后面又定义了p,ptr表示的是s+3的地址,s+3本身是二级指针,因此ptr就是三级指针

++p表示此时p由原来指向的s+3变成了s+2

在后面输出的部分,p现在指向的是s+2,因此*p就是s+2,再对它解引用*pp也就是*(s+2)也就是s[2],而s[2]对应的是pink,因此这里指向的就是p,再+1指向的就是i,因此打印结果就是ink

相关文章
|
15天前
使用指针访问数组元素
【10月更文挑战第30天】使用指针访问数组元素。
30 3
|
27天前
|
C语言
【c语言】指针就该这么学(1)
本文详细介绍了C语言中的指针概念及其基本操作。首先通过生活中的例子解释了指针的概念,即内存地址。接着,文章逐步讲解了指针变量的定义、取地址操作符`&`、解引用操作符`*`、指针变量的大小以及不同类型的指针变量的意义。此外,还介绍了`const`修饰符在指针中的应用,指针的运算(包括指针加减整数、指针相减和指针的大小比较),以及野指针的概念和如何规避野指针。最后,通过具体的代码示例帮助读者更好地理解和掌握指针的使用方法。
45 0
|
14天前
使用指针访问数组元素
【10月更文挑战第31天】使用指针访问数组元素。
27 2
|
23天前
|
算法 索引
单链表题+数组题(快慢指针和左右指针)
单链表题+数组题(快慢指针和左右指针)
28 1
|
28天前
|
存储 编译器 C语言
【c语言】数组
本文介绍了数组的基本概念及一维和二维数组的创建、初始化、使用方法及其在内存中的存储形式。一维数组通过下标访问元素,支持初始化和动态输入输出。二维数组则通过行和列的下标访问元素,同样支持初始化和动态输入输出。此外,还简要介绍了C99标准中的变长数组,允许在运行时根据变量创建数组,但不能初始化。
37 6
|
25天前
|
C语言
【c语言】指针就该这么学(3)
本文介绍了C语言中的函数指针、typedef关键字及函数指针数组的概念与应用。首先讲解了函数指针的创建与使用,接着通过typedef简化复杂类型定义,最后探讨了函数指针数组及其在转移表中的应用,通过实例展示了如何利用这些特性实现更简洁高效的代码。
15 2
|
26天前
|
C语言
如何避免 C 语言中的野指针问题?
在C语言中,野指针是指向未知内存地址的指针,可能引发程序崩溃或数据损坏。避免野指针的方法包括:初始化指针为NULL、使用完毕后将指针置为NULL、检查指针是否为空以及合理管理动态分配的内存。
|
26天前
|
C语言
C语言:哪些情况下会出现野指针
C语言中,野指针是指指向未知地址的指针,通常由以下情况产生:1) 指针被声明但未初始化;2) 指针指向的内存已被释放或重新分配;3) 指针指向局部变量,而该变量已超出作用域。使用野指针可能导致程序崩溃或不可预测的行为。
|
1月前
|
存储
如何使用指针数组来实现动态二维数组
指针数组可以用来实现动态二维数组。首先,定义一个指向指针的指针变量,并使用 `malloc` 为它分配内存,然后为每个子数组分配内存。通过这种方式,可以灵活地创建和管理不同大小的二维数组。
|
1月前
|
存储
如何通过指针数组来实现二维数组?
介绍了二维数组和指针数组的概念及其区别,详细讲解了如何使用指针数组模拟二维数组,包括定义与分配内存、访问和赋值元素、以及正确释放内存的步骤,适用于需要动态处理二维数据的场景。