Chr*_*bax 27 c arrays pointers
我知道有几个问题可以提供良好(和工作)的解决方案,但没有恕我直言,这清楚地说明了实现这一目标的最佳方法.所以,假设我们有一些2D数组:
int tab1[100][280];
Run Code Online (Sandbox Code Playgroud)
我们想要制作一个指向这个2D数组的指针.为实现这一目标,我们可以做到:
int (*pointer)[280]; // pointer creation
pointer = tab1; //assignation
pointer[5][12] = 517; // use
int myint = pointer[5][12]; // use
Run Code Online (Sandbox Code Playgroud)
或者,或者:
int (*pointer)[100][280]; // pointer creation
pointer = &tab1; //assignation
(*pointer)[5][12] = 517; // use
int myint = (*pointer)[5][12]; // use
Run Code Online (Sandbox Code Playgroud)
好的,两者似乎都运作良好.现在我想知道:
oli*_*bre 26
//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
Run Code Online (Sandbox Code Playgroud)
使用pointer2或pointer3生成相同的二进制文件,除了操作,++pointer2如WhozCraig所指出的那样.
我建议使用typedef(产生与上面相同的二进制代码pointer3)
typedef int myType[100][280];
myType *pointer3;
Run Code Online (Sandbox Code Playgroud)
注意:从C++ 11开始,您也可以使用关键字using代替typedef
using myType = int[100][280];
myType *pointer3;
Run Code Online (Sandbox Code Playgroud)
在你的例子中:
myType *pointer; // pointer creation
pointer = &tab1; // assignation
(*pointer)[5][12] = 517; // set (write)
int myint = (*pointer)[5][12]; // get (read)
Run Code Online (Sandbox Code Playgroud)
注意:如果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;
}
Run Code Online (Sandbox Code Playgroud)
int *pointer[280]; //创建280个int类型的指针.
在32位操作系统中,每个指针有4个字节.所以4*280 = 1120字节.
int (*pointer)[100][280]; //仅创建一个指针,用于指向[100] [280]整数的数组.
这里只有4个字节.
来你的问题,int (*pointer)[280];并且int (*pointer)[100][280];是不同的,虽然它指向[100] [280]的相同2D阵列.
因为如果int (*pointer)[280];递增,那么它将指向下一个1D数组,但是在其中int (*pointer)[100][280];穿过整个2D数组并指向下一个字节.如果该内存不属于您的进程,则访问该字节可能会导致问题.
你的例子都是等价的.然而,第一个不太明显,更"hacky",而第二个明确表明你的意图.
int (*pointer)[280];
pointer = tab1;
Run Code Online (Sandbox Code Playgroud)
pointer指向280个整数的1D数组.在你的任务,你实际上分配第一排的tab1.这是有效的,因为您可以隐式地将数组转换为指针(到第一个元素).
在使用时pointer[5][12],C将其pointer视为数组数组(pointer[5]属于类型int[280]),因此这里有另一个隐式转换(至少在语义上).
在第二个示例中,您显式创建了一个指向2D数组的指针:
int (*pointer)[100][280];
pointer = &tab1;
Run Code Online (Sandbox Code Playgroud)
这里的语义更清晰:*pointer是一个2D数组,所以你需要使用它来访问它(*pointer)[i][j].
两种解决方案都使用相同数量的内存(1个指针),并且很可能同样快速运行.在引擎盖下,两个指针甚至会指向相同的内存位置(tab1数组的第一个元素),并且您的编译器甚至可能生成相同的代码.
第一个解决方案是"更高级",因为人们需要非常深入地了解数组和指针如何在C中工作以了解正在发生的事情.第二个更明确.