什么是`int * userMask [3] [4]`指向?

时间:2008-11-08 16:03:42

标签: c arrays pointers

我正在修改一些代码,并且遇到了一个我无法理解的声明:

int *userMask[3][4] = {0};

究竟是什么指向?它是一个矩阵,每个元素都是指针吗?或者它指向一个大小为[3] [4]的矩阵?

由于


我想我的问题是userMask[2][maskElement][user]在声明为int时如何工作。 userMask不能int[]才能正常工作吗?我不能理解这一点......

在旁注中,感谢您对cdecl Robert的建议。但是,有没有人知道如何在XP命令提示符中使用它?我所能得到的只是语法错误:(

9 个答案:

答案 0 :(得分:36)

简短回答

给定userMask声明为

int *userMask[3][4];

然后userMask的类型为int*[3][4]。这是一个指向int的2d数组。外部维度的大小为3,内部维度的大小为4.实际上,这只不过是一个3元素的1d数组,其中元素类型是另一个4元素1d数组,其元素类型为int*

解释步骤

所以,如果你这样做

userMask[2][maskElement][user]

然后基本上使用前两个索引从二维数组中选择特定指针:

int * p = userMask[2][maskElement];

然后通过执行

选择一个偏离该指针的int
p[user]

现在该代码全部在userMask[2][maskElement][user]

有效C代码

使用有效的c代码逐步完成(如果您还不了解以下所有内容,请不要担心):

int * userMask[3][4] = { { 0 } };
int ** pa = userMask[2]; /* int*[4] becomes int** implicitly */
int * pi = pa[maskElement];
int i = pi[user];

assert(i == userMask[2][maskElement][user]);

数组和指针之间的差异

所以我想我会向你展示一些重要的东西。上面的数组 not 包含指向数组的指针。让我们看看它们的行为有多么不同,这是许多程序员不期望的:

int array[5][4][3];
/* int[4][3] implicitly converts to int(*)[3] (pointer to first element) */
int (*parray)[3] = array[0]; 
int ** pint = (int**) array[0]; /* wrong!! */

现在,如果我们parray[1]pint[1]会怎样?第一个将提前sizeof(int[3])个字节(3 * sizeof(int)),第二个将提前sizeof( int* )个字节。实际上,当第一个为您提供正确的数组array[0][1]时,第二个将为您提供( char * )array[0] + sizeof( int* ),这是我们并不真正想要的地方。但抓住错误的偏移并不是全部。因为它不知道访问了数组,所以它会尝试将pint[1]处的内容解释为int*。假设您的数组已使用0x00初始化。然后它将根据地址0x00(例如,执行pint[1][0])执行下一个索引步骤。哦不 - 完全未定义的行为!因此强调差异非常重要。

结论

这比你要求的要多,但我认为了解这些细节非常重要。特别是如果你想将2d数组传递给函数,那么这些知识非常有用。

答案 1 :(得分:17)

这是一个二维数组,其中每个元素都是指向int的指针,所有指针都初始化为零。

在您的后续工作中,您将显示数组的使用方式如下:

if(userMask[2][maskElement][user] && blah)
    result = true;

在这种情况下,userMask中的每个元素实际上都应指向int s的数组。 (int*可以指向单个intint个数组。要确定这一点,请检查将值分配给userMask的代码。例如,可以写:

int userArray[2] = { 10, 20 };

userMask[0][0] = userArray; // userMask[0][0] points to the
                            // first element of userArray.

然后以下代码索引到userArray

int value = userMask[0][0][1]; // sets value = userArray[1], giving 20.

答案 2 :(得分:10)

int *userMask[3][4] = {0};

是一个二维数组,其中每个成员都是指向int的指针。此外,所有成员都初始化为空指针。

int (*userMask)[3][4];

将是指向二维int数组的指针。 C中的括号比*更紧密,因此需要括号来创建指向数组的指针。

cdecl是一个简单的实用程序,您可以下载它来解释复杂的声明:

cdecl> explain int *userMask[3][4]
declare userMask as array 3 of array 4 of pointer to int

也可以这样做:

cdecl> declare userMask as pointer to array 3 of array 4 of int
int (*userMask)[3][4]

答案 3 :(得分:3)

if(userMask[2][maskElement][user] && blah)
   result = true;

这里的第二部分是C中没有数组;只有指针算术。根据定义,p[i]始终等同于*(p+i)所以

userMask[2][maskElement][user]

相当于

*((userMask[2][maskElement])+user)

代码在某个地方分配一个向量(我把钱从malloc(3c)或类似的调用中下注)到该数组中的指针;现在你的如果说

IF userMask [2] [maskElement]中向量的用户元素为非零

然后 blah非零(由于&&&&&&&&&&n;&n;&n;&n;            EM>

然后设置结果= true。

答案 4 :(得分:2)

应用由内而外的规则。

int *userMask[3][4] = {0};

从宣言的内部部分开始,

userMask

是名称

userMask[3] 

为其中3个(是向量)分配空间

userMask[3][4] 

为4 userMask[3]

分配空间
int *

告诉我们userMask项是int

的类型指针

然后= {0}是一个初始化程序,其中所有元素都是0。所以

int *userMask[3][4] = {0};

是int *的3x4数组,初始化为0。

答案 5 :(得分:0)

我认为该语句访问usermask数组的第三行,然后访问该行中的maskElement'th指针,因为这是一个int指针,它可以指向一个int数组的开头(想想字符串) ,我认为它正在做,并且该数组由用户进行子索引。

答案 6 :(得分:0)

userMask[2]的类型为int*[]
userMask[2][maskElement]的类型为int*
因此userMask[2][maskElement][user]的类型为int

声明

int *userMask[3][4] = {0};

的简写
int *userMask[3][4] = {{0, 0, 0}, {0, 0, 0}, {0, 0, 0}, {0, 0, 0}};

其中每个零都隐式转换为(int*)0

答案 7 :(得分:0)

如果您这样阅读它会有所帮助:

type variablename[array_spec];

在这种情况下:     int * usermask [3] [4];

所以它是一个int *。

的矩阵

现在,由于c不区分指针和数组,因此可以对指针使用数组索引。

int* i;
int the_int_behind_i = *(i+1);
int also_the_int_behind_i = i[1];

这需要我指向一个区域,其中几个整数排列在一起,当然,就像一个数组。

请注意,最后一个示例中使用的索引operator []看起来像第一个中的array_spec,但两者完全不同。

所以:userMask [2] [maskElement] [user]

选择存储在[2] [maskElement]中的usermask指针,并为用户 user

评估它

答案 8 :(得分:-1)

这是一个矩阵,每个元素都是一个指针。

如果它指向一个大小为[3] [4]的矩阵,那么代码就是

int userMask[3][4]={0};