C ++多维数组和指向指针表的指针 [英] C++ multidimensional array and pointers to table of pointers

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

问题描述

这是东西. 我可以完全理解多维数组的概念(让我们考虑一下二维),这是由指向数组的指针等构成的.

Here is the thing. I can completely understand a concept of a multidimensional array (let's consider 2D for a while) made by pointer to array to pointers and so on...

我们这样做:

// we can use dynamically defined size n and m
int n = 3, m = 5 ;
int **T = new int *[n];
for (int i = 0 ; i < n ; ++i)
    T[i] = new int[m];

我们得到的是: (检查我是否在这里)

What we got is: (Check if I'm right here)

  • 5个整数的3个内存块,放置在内存中的某个地方
  • 一个额外的内存块,其大小与整数块的数量(行数)相同.该块是一个指向这些int行的指针(通常为4个字节,用于类似int的指针)的数组.
  • 我们最感兴趣的是-指针(T),它是(** T)类型的指针. 这正是指向指针数组的指针,因为在C ++中,数组实际上是指向内存块的指针,因此t []或t [0]表示* t,t [x]表示*(t + X).
  • 3 blocks of memory of 5 ints, placed somewhere in memory
  • One additional block of memory of same size as number of the blocks of ints (number of rows). This block is an array of pointers (usually 4 bytes for pointer like int) to those int rows.
  • What we are interested in most - that is T which is of type (**T) - a pointer to pointer. Which is exactly a pointer to an array of pointer, because in C++ an array is in fact a pointer pointing to a block of memory so t[] or t[0] means *t, and t[x] means *(t+x).

现在的问题是,当我们这样做时:

Now the problem is when we do sth like this:

int n = 3, m = 5 ;
int T[n][m] ;

我们所能做的不是我以前展示过的事情. 我们有些奇怪.什么是T?当打印T时,我们得到与T [0]相同的值. 似乎我们保留了一个大小为n * m的整数块,而没有指向行的附加指针数组.

What we've got is not what w could have doing the thing I showed before. We get sth strange. What is T? When printfing T, we get the same value as T[0]. It looks like we reserved a block of ints sized n*m without additional array of pointers to rows.

我的问题是:编译器会记住数组的维数以及行和列的数量吗?当要求T [i] [j]时,实际上要求的是*(T + i * n + j),所以这个n存储在某个地方吗? 问题是当我们试图将此东西(T)传递给函数时.我不知道为什么,但是如果n和m是常量,则有可能将T作为指向此数组的指针传递,以使其在此程序中起作用:

My question is: does the compiler remembers the dimension of the array and number of rows and columns? And when asking for T[i][j] it actually asks for *(T+i*n+j) so this n is stored somewhere? The problem is when we are trying to pass this thing (T) to a function. I dont know why but if n and m were constants its possible to pass T as a pointer to this array to function like in this program:

#include <stdio.h>
const int n = 3, m = 4 ; // this is constant!
void add_5(int K[][m])
{
    for (int i = 0 ; i < n ; ++i)
        for (int j = 0 ; j < m ; j++)
            K[i][j] += 5 ;
}
int main()
{
    // n x m array the most straight forward method
    int T[n][m] ;
    for (int i = 0 ; i < n ; ++i)
        for (int j = 0 ; j < m ; ++j)
            T[i][j] = i*m + j ;

    for (int i = 0 ; i < n ; ++i)
    {
        for (int j = 0 ; j < m ; j++)
            printf("%d ",T[i][j]) ;
        printf("\n") ;
    }
    printf("\n") ;

    // adding 5 to all cells
    add_5(T) ;
    printf("it worked!!\n") ;

    for (int i = 0 ; i < n ; ++i)
    {
        for (int j = 0 ; j < m ; j++)
            printf("%d ",T[i][j]) ;
        printf("\n") ;
    }

    int ss ;
    scanf("%d",&ss) ;
}

但是如果n和m不是常数,我们就不能. 因此,我需要的是将动态创建的多维数组的指针传递给函数,而无需为此手动分配内存. 该怎么做?

But if n and m aren't constant we cant. So what I need is to pass dynamically created multidimensional array's pointer to a function without manually allocating memory for that. How to do this?

推荐答案

在C ++中,数组实际上是指向内存块的指针

in C++ an array is in fact a pointer pointing to a block of memory

绝对不是.数组与指针完全分开.您可能会感到困惑的原因是由于称为数组到指针转换的标准转换.考虑:

Absolutely not. An array is entirely separate from a pointer. The reason you might have this confusion is because of a standard conversion called array-to-pointer conversion. Consider:

int arr[10];

变量arr表示一个数组.根本不是指针.碰巧的是,在许多情况下,数组的名称将转换为指向其第一个元素的指针.也就是说,转换将其转换为int*.

The variable arr denotes an array. It's not a pointer at all. It just so happens that in many circumstances, the name of an array will be converted to a pointer to its first element. That is, the conversion turns it into an int*.

int T[n][m] ;

在这种情况下,T是"m int s的n数组的数组".您提到打印TT[0]都会得到相同的结果,这是由于数组到指针的转换所致.

In this case, T is an "array of n array of m ints". You mentioned that printing both T and T[0] give the same result, and this is due to array-to-pointer conversion.

  1. 表达式T可以转换为指向第一个元素的指针;即int (*)[m],因为T的第一个元素本身就是具有m个元素的数组.

  1. The expression T can be converted to a pointer to the first element; that is, an int (*)[m], because the first element of T is itself an array with m elements.

表达式T[0]可以转换为指向第一个子数组的第一个元素的指针.因此,您获得了一个指向类型为int*的元素T[0][0]的指针.

The expression T[0] can be converted to a pointer to the first element of the first subarray. So you get a pointer to the element T[0][0] of type int*.

由于数组在内存中的布局方式,这些指针具有相同的地址.数组开始的地址与该数组的第一个元素的地址相同.但是,指针的行为不同.如果您增加从T得到的指针,则将移至下一个子数组.如果您增加由T[0]产生的指针,则移至下一个int.

These pointers hold the same address because of the way an array is laid out in memory. The address that an array begins at is the same address as the first element of that array. However, the pointers do not behave in the same way. If you increment the pointer resulting from T, you move along to the next subarray. If you increment the pointer resulting from T[0], you move along to the next int.

与动态分配的"2D数组"相比,它可能有助于您查看内存中2D数组的布局图.一个3×3的2D数组如下所示:

It might help you to look at a diagram of how a 2D array is laid out in memory compared to a dynamically allocated "2D array". A 3-by-3 2D array would look like this:

  0,0   0,1   0,2   1,0   1,1   1,2   2,0   2,1   2,2
┌─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┬─────┐
│ int │ int │ int │ int │ int │ int │ int │ int │ int │
└─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┴─────┘

如果您动态分配了一个3×3的"2D数组":

Whereas if you dynamically allocated a 3-by-3 "2D array":

┌─────┐
│     │ // The int**
└──╂──┘
   ┃
   ▼
┌─────┬─────┬─────┐
│     │     │     ┿━━━━━━━━━━━━━━━━━━━━━━━━━━━━┓  // An array of int*
└──╂──┴──╂──┴─────┘                            ┃
   ┃     ┗━━━━━━━━━━━━━━━┓                     ┃
   ▼                     ▼                     ▼
┌─────┬─────┬─────┐   ┌─────┬─────┬─────┐   ┌─────┬─────┬─────┐
│ int │ int │ int │   │ int │ int │ int │   │ int │ int │ int │ // Arrays of ints
└─────┴─────┴─────┘   └─────┴─────┴─────┘   └─────┴─────┴─────┘
  0,0   0,1   0,2       1,0   1,1   1,2       2,0   2,1   2,2

编译器还记得数组的维数以及行和列的数量吗?

does the compiler remembers the dimension of the array and number of rows and columns?

是的,如果您具有数组类型的变量,则数组的大小就是该类型的一部分.编译器始终知道变量的类型.

Yes, if you have a variable with array type, the size of the array is part of that type. The compiler always knows the type of a variable.

当要求T [i] [j]时,实际上要求的是*(T + i * n + j),所以这n存储在某个地方吗?

And when asking for T[i][j] it actually asks for *(T+i*n+j) so this n is stored somewhere?

表达式T[i][j]等效于*(*(T + i) + j).让我们了解它的作用.首先,T进行数组到指针的转换,得到int (*)[m].然后,我们向其中添加i以指向第i个子数组.然后,将其取消引用以获取子数组.接下来,此子数组也将进行数组到指针的转换,得到int*.然后,向其中添加j以获得指向该子数组中第jint对象的指针.取消引用以给出int.

The expression T[i][j] is equivalent to *(*(T + i) + j). Let's understand what this does. First, array-to-pointer conversion is undergone by T, giving an int (*)[m]. We then add i to this to move along to point at the ith subarray. This is then dereferenced to get the subarray. Next, this subarray also undergoes array-to-pointer conversion, giving an int*. You then add j to this to get a pointer to the jth int object in that subarray. This is dereferenced to give that int.

问题是当我们试图将此东西(T)传递给函数时.我不知道为什么,但是如果n和m是常量,则可以将T作为指向该数组的指针进行传递

The problem is when we are trying to pass this thing (T) to a function. I dont know why but if n and m were constants its possible to pass T as a pointer to this array to function

这实际上是一个谎言.您没有将2D数组传递给该函数.实际上,没有像数组类型这样的参数.您的参数int K[][m]实际上等效于int (*K)[m].也就是说,所有数组类型参数都将转换为指针.

It's actually a lie. You're not passing the 2D array to the function. In fact, there's no such thing as an array type argument. Your argument int K[][m] is actually equivalent to int (*K)[m]. That is, all array type arguments are transformed into pointers.

因此,当您使用add_5(T)调用此函数时,不会传递T表示的数组. T实际上正在进行数组到指针的转换,从而为您提供int (*)[m],并且 this 指针正在传递给函数.

So when you call this function with add_5(T), you're not passing the array denoted by T. T is actually undergoing array-to-pointer conversion to give you an int (*)[m] and this pointer is being passed into the function.

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

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