在C中传递数组数组

时间:2009-12-09 15:21:47

标签: c pointers

我需要一个带有2D数组并生成随机位的函数,因此结果是一个随机二进制字符串数组。

我有以下代码,

#define pop_size 50
#define chrom_length 50
main() {
    int population[pop_size][chrom_length];
    init_pop(&population);
}
int init_pop(int *population[][]) {
    for(i = 0; i < pop_size; i++) {
        for(j = 0; j < chrom_length; j++) {
            *population[i][j] = rand() % 2;
        }
    }
    return 0;
}

在编译时,我收到以下错误消息:

  

数组类型具有不完整的元素类型

有什么建议吗?

4 个答案:

答案 0 :(得分:7)

通常情况下的时间......

当数组表达式出现在大多数上下文中时,其类型将从“N元素数组T”隐式转换为“指向T”,其值设置为指向数组的第一个元素。此规则的例外情况是,数组表达式是sizeof或一元&运算符的操作数,或者它是在声明中用作初始值设定项的字符串文字。

在代码的上下文中,这意味着什么?

表达式population的类型是“pop_size - chrome_length的元素数组 - int”的元素数组。按照上面的规则,在大多数情况下,表达式population将隐式转换为类型“指向chrome_length的指针 - int”的元素数组,或int (*)[chrome_length]

表达式&population的类型是“指向pop_size的指针 - chrome_length的元素数组 - int”或int (*)[pop_length][chrome_size]的元素数组,因为{ {1}}是一元population运算符的操作数。

请注意,这两个表达式具有相同的(数组的第一个元素的地址),但是不同的类型。

根据您编写的代码,将函数称为

&

相应的函数定义应为

init_pop(&population);

您将以

的形式访问每个元素
int init_pop(int (*population)[pop_size][chrome_length]) // note that both dimensions
                                                         // must be specified

请注意,这意味着(*population)[i][j] = initial_value; 只能 处理init_pop x pop_size数组;你不能在不同大小的数组上使用它。

如果您将此功能称为

chrome_length

然后相应的函数定义必须是

init_pop(population); // note no & operator

您将以

的形式访问每个元素
int init_pop(int (*population)[chrome_length]) // or population[][chrome_length],
                                               // which is equivalent

请注意,在这种情况下,您不必明确取消引用 population[i][j] = initial_value; 。现在你可以处理具有不同种群大小的数组,但是你仍然坚持使用固定的染色体长度。

第三种方法是将指向数组第一个元素的指针显式传递为int的简单指针,并​​将其视为一维数组,根据数组维度手动计算偏移量(作为单独的参数传递): / p>

population

现在init_pop(&population[0][0], pop_size, chrome_length); ... int init_pop(int *population, size_t pop_size, size_t chrome_length) { size_t i, j; ... population[i*chrome_length+j] = initial_value; ... } 可用于不同大小的int二维数组:

init_pop

编辑:请注意,上述技巧仅适用于连续分配的 2D数组;它不适用于动态分配的数组,其中主要维度和次要维度是分开分配的。

这是一个方便的表格,假定int pop1[10][10]; int pop2[15][20]; int pop3[100][10]; ... init_pop(&pop1[0][0], 10, 10); init_pop(&pop2[0][0], 15, 20); init_pop(&pop3[0][0], 100, 10); ... 的定义:

Expression     Type           Implicitly converted to
----------     ----           -----------------------
a              int [N][M]     int (*)[M]
a[i]           int [M]        int *
a[i][j]        int            
&a             int (*)[N][M]   

答案 1 :(得分:5)

当将数组作为参数传递时,您需要告诉编译器除第一个之外的所有维:

int init_pop(int population[][pop_size])
{ 
 ...
}

是的,这意味着很难让它变得完全动态,并且介绍一个你必须重复自己的地方。

更新:我很困惑,并且要求倒置了。现在修好了。

答案 2 :(得分:0)

这是问题所在:

int *population[][]

多维数组只是一个连续内存块,当你说foo[3][2]时,编译器会找到3*last_dimension_size + 2的正确索引,这意味着它到知道除了最后一个尺寸之外的所有尺寸。

因此声明是错误的。


BTW--在SO上已经有几个非常完整的讨论与c中的多维数组有关的问题。尝试在[c][c++]

下搜索

答案 3 :(得分:0)

对于C / C ++中的多维数组,您必须指定除第一个之外的所有维度。我正在修改您的程序以使其正常工作:

#include <stdio.h>
#include <stdlib.h>
#define pop_size 3
#define chrom_length 3

void init_pop(int population[][chrom_length]) {
 int i,j;
 for(i = 0; i < pop_size; i++) {
      for(j = 0; j < chrom_length; j++) {
            population[i][j] = rand() % 2;
      }
 }
}

/* For Checking */
void display (int population[][chrom_length]){
  int i,j;
 for(i = 0; i < pop_size; i++) {
      for(j = 0; j < chrom_length; j++) {
          printf("%d ",population[i][j]);
      }
      printf("\n");
    }
}


int main(void) {
 int population[pop_size][chrom_length];
 init_pop(population);
 display(population); /* For Checking */

 return 0;
}

如果你不打算使用全局常量here是正确的方法。