如何在C语言中声明一个指针的二维数组?

6

...不使用typedef。

我的老板声称他曾在面试中被问到这个问题,当他回答时,面试官告诉他不能使用typedef,因为这是一种糟糕的风格。

不管怎样,他喜欢向人们提出这个问题,只是想看看他们能否得到正确的答案,通常在新程序员午餐时进行。没有人能得到正确答案 (尤其是没有笔和纸或电脑方便的情况下)。我希望下次他再尝试用这个问题考验别人时,我能够做好准备>:D


1
那么,自从何时起,typedef成为了不好的风格?我想看到负责这个想法的人的名字明天放在我的桌子上。 - Tamas Czinege
1
avakar只是正确的,我不明白这个问题的意义。也许你的老板已经有10多年没有用C编程了,他模糊地记得这很困难吗?或者你漏掉了“挑战”的某些部分? - unwind
@DrJokepu: typedef 无法进行前向声明。在 C 中通常不是问题,但在 C++ 中却是。这对于模块化来说是不好的。 - OregonGhost
我终于明白了,他要求一个指向指针数组的指针数组,指向某个东西:T *(*a[N])[M]。请参见下面的答案,以获取主题的变化。 - John Bode
@John Bode,是的,我明白。这就是为什么我笑了 :) - Johannes Schaub - litb
显示剩余3条评论
5个回答

11

二维指针数组指向什么?

T *p[N][M];     // N-element array of M-element array of pointer to T
T (*p[N][M])(); // N-element array of M-element array of pointer to 
                // function returning T

如果我们谈论的是指向二维数组的指针,那么事情只会稍微有点有趣:
T a[N][M];            // N-element array of M-element array of T
T (*p)[M] = a;        // Pointer to M-element array of T
T (**p2)[M] = &p;     // Pointer to pointer to M-element array of T
T (*p3)[N][M] = &a;   // Pointer to N-element array of M-element 
                      // array of T
T (**p4)[N][M] = &p3; // Pointer to pointer to N-element array of 
                      // M-element array of T

编辑:等一下,我想我可能明白你想要什么了。


(该段文字已经为您翻译完成,保留原有的HTML标签)
T *(*a[N])[M];        // a is an N-element array of pointer to M-element
                      // array of pointer to T

编辑:现在我们变得非常愚蠢:

T *(*(*a)[N])[M];     // a is a pointer to an N-element array of 
                      // pointer to M-element array of pointer to T

T *(*(*(*f)())[N])[M];  // f is a pointer to a function returning
                        // a pointer to an N-element array of pointer
                        // to M-element array of pointer to T

T *(*(*f[N])())[M];     // f is an N-element array of pointer to 
                        // function returning pointer to M-element 
                        // array of pointer to T

对于病态的疯子们:

T *(*(*(*(*(*f)())[N])())[M])(); // f is a pointer to a function 
                                 // returning a pointer to a N-element
                                 // array of pointer to function 
                                 // returning M-element array of
                                 // pointer to function returning
                                 // pointer to T

类型定义是给懦夫的。


2
类型定义是给懦弱者用的。哈哈哈 - Johannes Schaub - litb
仅因上述引用而点赞。 - RedLeader

8
void* array[m][n];

这将给你一个二维的void指针数组。除非我误解了你的问题,否则我不确定为什么会有什么困惑。


2
void*** p2DArray = (void***)malloc( numAxis1 * sizeof( void** ) );

int count = 0;
while( count < numAxis1 )
{
    p2DArray[count] = (void**)malloc( numAxis2 * sizeof( void* ) );
    count++;
}

现在你可以通过p2DArray[n][m]访问数组并获取存储在其中的void*。

不知道为什么你需要使用typedefs...

编辑:哈哈哈哈或者像avakar建议的那样;)


1
在C语言中,你不应该对malloc()的返回值进行强制类型转换。 - unwind
1
@unwind:你永远不应该强制转换malloc的返回值?这样你就不能分配除void之外的任何东西,而void本身是无用的? - OregonGhost
如果我没有记错的话,Nah char* pChar = malloc( 1 );是有效的代码。 我似乎记不起来强制转换 malloc 返回值是否有害... 但是我使用 C++ 比使用 C 更多。 - Goz
危害在于,如果您忘记包含malloc()的定义,强制转换将隐藏您的错误。由于它没有实际用途... - caf
3
无类型指针可以隐式地转换为其他对象指针类型,无需进行强制转换。在C语言中,使用以下语句是惯用的方式来动态分配内存: T *x = malloc(sizeof *x * num_elements);在C89之前,malloc() 返回的是 char* 类型,因此需要进行强制转换,但现在很少有人使用20年以上的旧实现。 - John Bode

0

C/C++中是行主序,Matlab/Fortran中是列主序,而对于某些未知原因的C#/本地交互多维数组,则不确定。

int x = 4;
int y = 4;
void** data = malloc(x * y * sizeof(void*));

0
typedef和函数指针的好处在于它们可以减轻程序员的心理压力。
我想问题就出在这里,使用void指针可以解决这个问题,但是每次使用时都需要转换FP以消除所有警告。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接