Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/59.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 通过指针的二维数组_C_Pointers - Fatal编程技术网

C 通过指针的二维数组

C 通过指针的二维数组,c,pointers,C,Pointers,我想创建一个动态数组来存储置换序列,这样 order[0][]={1,2,3} order[1][]={2,1,3} order[2][]={2,3,1} 假设顺序[m][n],m=排列数,n=项数,m和n被实时识别 我做了以下操作,发现指针地址重叠,导致不正确的值存储。如何通过双指针正确使用动态数组 void permute(int num_permute, int num_term, int** order) { int x, y; int term[5]; /*

我想创建一个动态数组来存储置换序列,这样

order[0][]={1,2,3}
order[1][]={2,1,3}
order[2][]={2,3,1}
假设顺序[m][n],m=排列数,n=项数,m和n被实时识别

我做了以下操作,发现指针地址重叠,导致不正确的值存储。如何通过双指针正确使用动态数组

void permute(int num_permute, int num_term, int** order) {
    int x, y;
    int term[5];

    /* debug only */
    for(y=num_term, x=0; y>0; y--, x++){
        term[x] = y;
    }
    fprintf(stderr, "\n");

    printf("order%12c", ' ');
    for (x=0; x<num_permute; ++x) {
        printf("  %-11d", x);
    }
    printf("\n");
    for(y=0; y<num_permute; y++){
        printf("%-5d%12p", y, (order+y));
        memcpy(&(order[y]), term, sizeof(term));

        for (x=0; x<num_term; x++)
            printf(" %12p", order+y+x);

        printf("\n");

    }
}

int main(){
    int y, z;
    int** x;

    x = (int*) malloc(5*5*sizeof(int*));

    permute(5, 5, x);
    printf("\n");

    printf("x   ");
    for(z=0; z<5; z++){
        printf(" %2d ", z);
    }
    printf("\n");
    for(y=0; y<5; y++){
        printf("%-4d", y);
        for(z=0; z<5; z++){
            printf(" %2d ", *(x+y+z));
        }
        printf("\n");
    }

    free(x);

    return 0;
}
void排列(int num\u排列,int num\u术语,int**order){
int x,y;
整数项[5];
/*仅调试*/
对于(y=num_项,x=0;y>0;y--,x++){
项[x]=y;
}
fprintf(标准格式,“\n”);
printf(“订单%12c”,”;

对于(x=0;x源代码:
代码将类似于:

#include <stdlib.h>

int **array;
array = malloc(nrows * sizeof(int *));
if(array == NULL)
{
     fprintf(stderr, "out of memory\n");
     /*exit or return*/
}
for(i = 0; i < nrows; i++)
{
    array[i] = malloc(ncolumns * sizeof(int));
    if(array[i] == NULL)
    {
          fprintf(stderr, "out of memory\n");
         /*exit or return*/
    }
}

以下代码段为给定的行和列创建二维矩阵。请将其用作调试程序的参考

#include <stdio.h>
#include <stdlib.h>

int main()
{
        int row, column;
        int **matrix;
        int i, j, val;

        printf("Enter rows: ");
        scanf("%d", &row);
        printf("Enter columns: ");
        scanf("%d", &column);

        matrix = (int **) malloc (sizeof(int *) * row);
        if (matrix == NULL) {
                printf("ERROR: unable to allocate memory \n");
                return -1;
        }  
        for (i=0 ; i<row ; i++) 
                matrix[i] = (int *) malloc (sizeof(int) * column);

        val=1;
        for (i=0 ; i<row ; i++) {
                for (j=0 ; j<column; j++) {
                        matrix[i][j] = val++;
                }
        }

        for (i=0 ; i<row ; i++) {
                for (j=0 ; j<column; j++) {
                        printf("%3d  ", matrix[i][j]);
                }
                printf("\n");
        }

        return 0;
}

/*
Allocation of 2d matrix with only one call to malloc and 
still get to access the matrix with a[i][j] format

the matrix is divided into headers and data.

headers = metadata to store the rows
data = actual data storage - buffer

allocate one contigious memory for header and data
and then make the elements in the header to point to the data are

        <- headers -----><----------- data -----------

        -----------------------------------------------------------------
        | | | | | |     ..      |
        | | | | | |     ..      |
        -----------------------------------------------------------------
         |                                 ^
         |                                 |
         |-----------------|
        header points to data area

*/

/*
Output:

$ gcc 2darray.c 
$ ./a.out 
Enter rows: 10
Enter columns: 20
  1    2    3    4    5    6    7    8    9   10   11   12   13   14   15   16   17   18   19   20  
 21   22   23   24   25   26   27   28   29   30   31   32   33   34   35   36   37   38   39   40  
 41   42   43   44   45   46   47   48   49   50   51   52   53   54   55   56   57   58   59   60  
 61   62   63   64   65   66   67   68   69   70   71   72   73   74   75   76   77   78   79   80  
 81   82   83   84   85   86   87   88   89   90   91   92   93   94   95   96   97   98   99  100  
101  102  103  104  105  106  107  108  109  110  111  112  113  114  115  116  117  118  119  120  
121  122  123  124  125  126  127  128  129  130  131  132  133  134  135  136  137  138  139  140  
141  142  143  144  145  146  147  148  149  150  151  152  153  154  155  156  157  158  159  160  
161  162  163  164  165  166  167  168  169  170  171  172  173  174  175  176  177  178  179  180  
181  182  183  184  185  186  187  188  189  190  191  192  193  194  195  196  197  198  199  200  
$ 

*/
#包括
#包括
int main()
{
int行,列;
int**矩阵;
int i,j,val;
printf(“输入行:”);
scanf(“%d”行和第行);
printf(“输入列:”);
scanf(“%d”列和列);
矩阵=(int**)malloc(sizeof(int*)*行);
if(矩阵==NULL){
printf(“错误:无法分配内存\n”);
返回-1;
}  

对于(i=0;i,代码示例仅模拟多维数组,但操作不正确。若要查看出现了什么问题,请从声明多维数组时发生的情况开始:

int foo[3][5];
这将分配大小为3*5*sizeof(int)的连续内存区域。在诸如
foo[i]
之类的表达式中,
foo
被转换为
int[5]
指针,然后应用索引运算符。换句话说,
foo[i]
相当于
*((int(*)[5])foo)+i)
。每个
foo[i]
将被视为大小为5*sizeof(int)

x、 y:0,0,10,20,30,41,0 foo-->1 | 2 | 3 | 4 | 5 | 1 |。。。 在示例代码中创建
x
时,您正在复制这种类型的多维数组。因此,您使用的索引表达式(
*(order+y+x)
)是错误的,因为它不能正确处理
order[y]的大小
order+1+0==order+0+1
,这就是您在示例输出中看到的问题

正确的表达式是:
(order+num\u term*y)
用于yth排列,而
*(order+num\u term*y+x)
用于元素
顺序[y][x]

这表明示例中存在另一类错误。对于这种模拟多维数组,数组类型实际上是指向一维数组的指针。
x
order
的声明类型应该是
int*
,而不是
int**
。这应该通过示例代码中的类型警告得到加强应产生:

  • x
    分配空间时,指针的类型(
    int*
    )与
    x
    的类型不匹配
  • 打印
    x
    的元素时,
    *(x+y+z)
    的类型与格式“%d”不匹配

但是,虽然模拟多维数组可以节省空间,但在使用时更容易出错(除非您编写一个函数来处理索引)。像Als这样的解决方案可能更安全,因为您可以使用标准的索引运算符。

如果您有C99(或C11),则使用指针数组模拟二维数组完全是一种过激行为。只需使用

void permute(size_t num_permute, size_t num_term, unsigned order[][num_term]);
作为函数签名,并在
main
中分配矩阵

unsigned (*order)[m] = malloc(sizeof(unsigned[n][m]));

此外,正如您在上面的示例中所看到的,我建议您使用语义正确的类型。大小总是与
size\u t
一起提供的,并且您的排列值在我看来似乎永远不会是负数。也许对于这些,您也应该从
0
开始计数,谢谢!!我忘记了这个概念!!我同意在这里使用真正的2D数组可能是最好的。只有对于OP,维度是动态的,在编译时不知道。使用C99可以直接在堆栈上执行VLA,但当维度未知时这有点危险。这就是为什么我在回答中使用
malloc
ed数组的原因。@JensGustedt:twfx不应该使用2D数组我只是用它来解释代码中发生了什么。注意:所以使用Q&a格式。问题不应该包含答案。 x,y: 0,0 0,1 0,2 0,3 0,4 1,0 foo --> | 1 | 2 | 3 | 4 | 5 | 1 |... <- 5 * sizeof(int) ->
void permute(size_t num_permute, size_t num_term, unsigned order[][num_term]);
unsigned (*order)[m] = malloc(sizeof(unsigned[n][m]));