首页 > 试题广场 >

假设函数原型和变量说明如下: void f3(int(*p

[单选题]
假设函数原型和变量说明如下:
void f3(int(*p)[4]);
int a[4]={1,2,3,4},
int b[3][4]={{1,2,3,4},{5,6,7,8},{9,10,11,12}};
下面调用非法的是()

  • f3(&a);
  • f3(b[1]);
  • f3(&b[1]);
  • f3(b);
推荐
B。根据题目结合选项来看考察的是对函数的传参调用,其中参数涉及到数组指针 。
void f3(int(*p)[4]);    其参数是数组指针 指向数组p的指针
  • 选项A:f3(&a);  参数为一个地址,符合指针定义。
  • 选项B:f3(b[1]); 参数为一个数组的具体元素,不符合指针定义。所以B是非法的调用。
  • 选项C:f3(&b[1]); 参数为一个数组元素的地址,符合指针定义。
  • 选项D:f3(b);  参数为数组名,表示该数组的首地址,符合指针定义。




编辑于 2019-08-20 14:12:56 回复(13)

先给出结论,便于以后查阅:

首先给出几个定义:

typedef int (*p1x4)[4];//定义数据类型,p1x4这种类型为指向含4个int元素的1维数组的指针

typedef int (*p3x4)[3][4];//定义数据类型,p3x4这种类型为指向含3x4个int元素的2维数组的指针

 

下面从一维数组说起:(定义:int a[4])

(1)一维数组名a是个地址,地址类型为:int *

(2)一维数组名取地址&a是个地址,地址类型同:int (*p)[4], 也即&a指向含4个int元素的一维数组

 

再看二维数组b[3][4],这个二维数组也可以可以看成一个含3个成员的一维数组,每一个成员含有4个int元素,依次,仿照一维数组的结论,有:

(1)b[0]是个一维数组名,也是个地址,地址类型为:int *

(2)&b[0]是个地址,地址类型同:int (*p)[4], 也即&b[0]指向含4个int元素的一维数组

更进一步:

(3)b是个地址,地址类型同:int (*p)[4],也即b指向含4个int元素的一维数组

(4)&b是个地址,地址类型同:int (*p)[3][4],也即&b指向含3x4个int元素的2维数组

注意:尤其注意上面的(3),这条结论指出了:
二维数组名实际上是一维数组的地址!b==&b[0]
b[0]又是b[0][0]的地址(类比a是a[0]的地址), b= &(&b[0][0])

 

总结:

① 数组名,是指向它的第一个一级成员的指针

② 数组名取地址,是指向整个数组的指针

PS:所谓一级成员,举个例子,int a[5],那么数组a的一级成员就是int型变量;int b[10][5],数组b的一级成员是int [5]的一维数组



****************************************************************************************************
b[0]是个一维数组名,也是个地址,地址类型为:int *
&b[0]是个地址,地址类型同:int (*p)[4], 也即&b[0]指向含4个int元素的一维数组

b[0]相当于一维数组中的数组名a
int(*p)[4]指向含4个int元素的1维数组的指针 ,相当于二级指针(*p)[4]=&a,就是说&b[0]==(*p)[4]

例题:
int a[3];
int *b=a;
int *c=&a; //错误
int (*c)[3]=&a; //正确
int *d=&a[0];
int *e=&a[1];
int *f=&a[2];

例子解析:

1. 定义一维数组a[3],在例子中,a、&a、&a[0]的值虽然都是一样,但是意义不一样。a代表a[3]这个数组,也是a[3]的起始地址。&a就是取a[3]的起始地址。&a[0]就是取数组第一个元素的地址。

2. 例子中,使用int *c=&a是错误的,因为a的数据类型是int (*)[3],而不是int *,所以必须以int (*c)[3]=&a。

3. 定义了int (*c)[3]=&a,可以使用(*c)[0]取得a[0],(*c)[1]取得a[1],(*c)[2]取得a[2]。



编辑于 2020-08-06 11:44:27 回复(7)
b[1]和&b[1]虽然值相等,但是含义不一样,&b[1]是行指针,类型是int (*)[4],和a的类型相同;而b[1]是个int *,和&b[1][0]等价。
发表于 2020-04-28 21:02:56 回复(3)
int *a[]和int (*a)[]是有区别的。 第一个表示定义一个数组a,这个数组的类型是int指针型(即这个数组用来存储int型指针),a是一个数组名 第二个表示定义一个指针a,这个指针指向一个int数组
发表于 2020-04-13 15:42:46 回复(2)

int(*p)[4]数组指针,意思是一个指向含有四个整数的数组的指针

int* p[4]才是指针数组,意思是一个存放着4个int*型元素的数组

现在来看选项:

  • Af3(&a);:a为数组的首元素的地址,&a为整个数组的地址,因为a有四个元素,所以&a返回的就是int(*p)[4],可以在vs中使用auto变量来验证:

    图片说明

  • Bf3(b[1]);:b[1]可以看成*(b + 1),即返回b中第二个四元素数组({5,6,7,8})的首地址,也就是返回int*,因此错误

    或者这样理解,b其实就是一个int(*p)[4]指针,b[1]对这个指针解引用变成了int*

  • Cf3(&b[1]);:同上,对这个四元素数组取地址,获得一个指向四个元素的数组的指针int(*p)[4],正确

  • Df3(b);:b是第一个四元素数组的地址,其实就是一个int(*p)[4]指针

编辑于 2022-03-10 09:59:20 回复(1)
答案为B
发表于 2019-08-19 17:28:04 回复(0)
考察知识点:数组作为函数参数会退化为指向下一层第一个元素的指针。
void f3(int(*p)[4]);    其参数是数组指针 ,是指向数组(大小为4个int )的指针.
A: f(&a)  如如果直接传值,f(a) 那么就相当于传了a[0]的地址,其中只指向了一个元素,是错的。取址后,步长变为4*(int),是满足条件的

B:f3(b[1]);  就和A中解析一样,b[1]大小为4,传入函数中,退化为b[1][0]的地址 ,是不满足条件的

C:f3(&b[1]); 在B的基础上,取地址后,步长变为4*(int),满足条件

D:f3(b); 直接传b,指针退化为b[0]的首地址,步长为4*(int),满足条件
发表于 2022-04-18 19:06:47 回复(0)
数组名是指向它第一个元素的地址
数组名取地址,是指向整个数组的指针
发表于 2021-07-03 15:50:56 回复(0)
首先,理解一下数组指针和指针数组这两个名词: “数组指针”和“指针数组”,只要在名词中间加上“的”字,就知道中心了—— 数组的指针:是一个指针,什么样的指针呢?指向数组的指针。 指针的数组:是一个数组,什么样的数组呢?装着指针的数组。 然后,需要明确一个优先级顺序:()>[]>*,所以: (*p)[n]:根据优先级,先看括号内,则p是一个指针,这个指针指向一个一维数组,数组长度为n,这是“数组的指针”,即数组指针; *p[n]:根据优先级,先看[],则p是一个数组,再结合*,这个数组的元素是指针类型,共n个元素,这是“指针的数组”,即指针数组。 根据上面两个分析,可以看出,p是什么,则词组的中心词就是什么,即数组“指针”和指针“数组”。 内容来自 https://blog.csdn.net/mick_hu/article/details/100931034?utm_source=app&app_version=4.5.2
发表于 2021-03-15 11:13:56 回复(0)




发表于 2020-11-30 11:07:06 回复(0)
因为是二级数组指针所以是指向二维数组(每二维数组元素均为个数为4的一位数组地址)的地址,只有b选项是一位数组的地址,所以选b;a选项是在一维数组地址之上去地址,所以也相当于二维数组的地址
发表于 2020-08-18 15:45:14 回复(0)
选B。
int (*p)[4] 其实是相当于一个n行4列的二维数组,B选项的b[1]只是一个一维的数组,类型不符合,需要在前面加 ‘&’ 。同理,如果实参是a也是类型不符合。
发表于 2020-04-13 13:36:36 回复(1)
  • f3(&a);
  • f3(b[1]);
  • f3(&b[1]);
  • f3(b);
首先形参是一个数组指针类型,保存的是一个数组的地址。
A选项,&a是数组的地址,正确
D选项,二维数组的数组名表示首元素的地址,也就是第一维的整个数组的地址,正确
B选项,b[i]代表的是每一维的数组名,该数组名表示该一维数组的首元素的地址,也就是具体整型的地址,不符合。
C选项,&b[i],该数组名表示整个一维数组,所以取地址,表示整个一维数组的地址,正确。
也可以这么理解:
二维数组的行列指针的概念及关系:*行指针 == 列指针  &列指针 == 行指针
b是行指针,b[i] = *(b+i)是列指针,&b[i]是行指针
发表于 2023-05-03 22:26:08 回复(0)
int(*p)[4]是一个数组指针,指针p为int *[4]类型。
a是int *类型,&a是int *[4]类型--这里是取值还是取址的问题,取值是看成一维数组后每个元素的大小,取址是整个数组的大小
b是一个二维数组的组名,按一维数组来看,b是该一维数组int [3]的第一个元素b[0]的地址,而b[0]又是一维数组int [4]的第一个元素b[0][0]的地址
所以,有b=b[0]=b[0][0],故b既可以看成是int *类型,也可以是int *[4]类型
而b[0]只能是int *类型,&b[0]是int *[4]类型
所以B是错误的
编辑于 2022-11-14 20:26:39 回复(0)
首先,指针数组、数组指针我就不说了,评论有详解
int(*p)[4]:数组指针,某种意义上算是二级地址,再看选项
&a:一维数组取地址便二维,某种意义上算二维(c++的引用除外)
b[1]:二维数组的第二行的首地址,某种意义上算一维
&b[1]:一维取地址变二维
b:二维数组名,算二维
所以说据我的理解这道题应该是考察的地址维度,但是说句实话哈,这种转我觉得没意义,就单说强转这一点,都不一定行的通,不信的读者可以试试随意类型强转,部分的会语法没错,但肯定达不到想要的效果,还有就是个人感觉这题看看就好,了解考察点即可,没必要深究
还有一点就是,觉得可以的点个赞,上个推荐,推荐的啥丫
最后一点就是,上面纯属个人理解,欢迎指正

发表于 2022-10-19 00:01:43 回复(0)
最简单理解: 函数的参数是 ”指针“的“指针“,相当于两层指针。 而B中b【1】只是一层指针
发表于 2022-08-15 16:09:11 回复(0)
函数形参是指向容纳4个int型元素数组的指针,a,c都符合要求,b中数组名被编译器转换为数组元素类型的指针,为int*,d中同样为数组元素类型,二维数组的元素是数组,数组名转换为指向一维数组的指针
发表于 2020-09-20 11:56:03 回复(0)
要传入的是数组行地址,而b[1]是数组元素b[1][0]的地址,其他三个均为行地址
发表于 2022-11-15 09:34:16 回复(0)
b[1]是第一行第0列元素的列地址,是一个int类型的地址;
 &b[1]是第一行的行地址,是一个int tmp[4] 数组的首地址。
发表于 2022-08-23 07:26:46 回复(0)
a存放是数组的起始地址,&a即变量a本身的地址,相当于一个指针
发表于 2022-03-30 00:23:09 回复(0)
b[1]是地址,但是b[1]是指向int的指针;b也是指针,但b是指向int数组的指针,而f3函数的形参也是数组指针(指向int数组的指针),所以选B
发表于 2022-03-28 23:41:04 回复(0)