指向C中的2D数组的指针 [英] Pointer to 2D arrays in C

查看:88
本文介绍了指向C中的2D数组的指针的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道有几个问题可以提供良好的(可行的)解决方案,但是恕我直言,没有一个明确说明实现此目标的最佳方法的问题. 因此,假设我们有一些2D数组:

int tab1[100][280];

我们要创建一个指向此2D数组的指针. 为此,我们可以这样做:

int (*pointer)[280]; // pointer creation
pointer = tab1; //assignation
pointer[5][12] = 517; // use
int myint = pointer[5][12]; // use

或者,或者:

int (*pointer)[100][280]; // pointer creation
pointer = &tab1; //assignation
(*pointer)[5][12] = 517; // use
int myint = (*pointer)[5][12]; // use 

好的,两者似乎都运作良好.现在我想知道:

  • 第一种还是第二种是最好的方法?
  • 对于编译器来说是否相等? (速度,性能...)
  • 这些解决方案中的一种是比其他解决方案消耗更多的内存吗?
  • 开发人员更常使用什么?

解决方案

//defines an array of 280 pointers (1120 or 2240 bytes)
int  *pointer1 [280];

//defines a pointer (4 or 8 bytes depending on 32/64 bits platform)
int (*pointer2)[280];      //pointer to an array of 280 integers
int (*pointer3)[100][280]; //pointer to an 2D array of 100*280 integers

使用pointer2pointer3会产生相同的二进制文件,但 WhozCraig 指出的操作与++pointer2相同. /p>

我建议使用typedef(产生与上述pointer3相同的二进制代码)

typedef int myType[100][280];
myType *pointer3;

注意:从C ++ 11开始,您还可以使用关键字using代替typedef

using myType = int[100][280];
myType *pointer3;

在您的示例中:

myType *pointer;                // pointer creation
pointer = &tab1;                // assignation
(*pointer)[5][12] = 517;        // set (write)
int myint = (*pointer)[5][12];  // get (read)

注意:如果在函数正文中使用数组tab1 =>,则此数组将放置在调用堆栈内存中.但是堆栈大小是有限的.使用大于可用内存堆栈的数组会产生 堆栈溢出崩溃.

完整的代码段可在线编译,网址为 gcc.godbolt.org

int main()
{
    //defines an array of 280 pointers (1120 or 2240 bytes)
    int  *pointer1 [280];
    static_assert( sizeof(pointer1) == 2240, "" );

    //defines a pointer (4 or 8 bytes depending on 32/64 bits platform)
    int (*pointer2)[280];      //pointer to an array of 280 integers
    int (*pointer3)[100][280]; //pointer to an 2D array of 100*280 integers  
    static_assert( sizeof(pointer2) == 8, "" );
    static_assert( sizeof(pointer3) == 8, "" );

    // Use 'typedef' (or 'using' if you use a modern C++ compiler)
    typedef int myType[100][280];
    //using myType = int[100][280];

    int tab1[100][280];

    myType *pointer;                // pointer creation
    pointer = &tab1;                // assignation
    (*pointer)[5][12] = 517;        // set (write)
    int myint = (*pointer)[5][12];  // get (read)

    return myint;
}

I know there is several questions about that which gives good (and working) solutions, but none IMHO which says clearly what is the best way to achieve this. So, suppose we have some 2D array :

int tab1[100][280];

We want to make a pointer that points to this 2D array. To achieve this, we can do :

int (*pointer)[280]; // pointer creation
pointer = tab1; //assignation
pointer[5][12] = 517; // use
int myint = pointer[5][12]; // use

or, alternatively :

int (*pointer)[100][280]; // pointer creation
pointer = &tab1; //assignation
(*pointer)[5][12] = 517; // use
int myint = (*pointer)[5][12]; // use 

OK, both seems to work well. Now I would like to know :

  • what is the best way, the 1st or the 2nd ?
  • are both equals for the compiler ? (speed, perf...)
  • is one of these solutions eating more memory than the other ?
  • what is the more frequently used by developers ?

解决方案

//defines an array of 280 pointers (1120 or 2240 bytes)
int  *pointer1 [280];

//defines a pointer (4 or 8 bytes depending on 32/64 bits platform)
int (*pointer2)[280];      //pointer to an array of 280 integers
int (*pointer3)[100][280]; //pointer to an 2D array of 100*280 integers

Using pointer2 or pointer3 produce the same binary except manipulations as ++pointer2 as pointed out by WhozCraig.

I recommend using typedef (producing same binary code as above pointer3)

typedef int myType[100][280];
myType *pointer3;

Note: Since C++11, you can also use keyword using instead of typedef

using myType = int[100][280];
myType *pointer3;

in your example:

myType *pointer;                // pointer creation
pointer = &tab1;                // assignation
(*pointer)[5][12] = 517;        // set (write)
int myint = (*pointer)[5][12];  // get (read)

Note: If the array tab1 is used within a function body => this array will be placed within the call stack memory. But the stack size is limited. Using arrays bigger than the free memory stack produces a stack overflow crash.

The full snippet is online-compilable at gcc.godbolt.org

int main()
{
    //defines an array of 280 pointers (1120 or 2240 bytes)
    int  *pointer1 [280];
    static_assert( sizeof(pointer1) == 2240, "" );

    //defines a pointer (4 or 8 bytes depending on 32/64 bits platform)
    int (*pointer2)[280];      //pointer to an array of 280 integers
    int (*pointer3)[100][280]; //pointer to an 2D array of 100*280 integers  
    static_assert( sizeof(pointer2) == 8, "" );
    static_assert( sizeof(pointer3) == 8, "" );

    // Use 'typedef' (or 'using' if you use a modern C++ compiler)
    typedef int myType[100][280];
    //using myType = int[100][280];

    int tab1[100][280];

    myType *pointer;                // pointer creation
    pointer = &tab1;                // assignation
    (*pointer)[5][12] = 517;        // set (write)
    int myint = (*pointer)[5][12];  // get (read)

    return myint;
}

这篇关于指向C中的2D数组的指针的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆