【问题标题】:Why doesn't my function really initialize the array?为什么我的函数没有真正初始化数组?
【发布时间】:2017-12-24 13:33:04
【问题描述】:

我正在尝试编写一个将数组初始化为零的函数:

void InitializingToZero(int numOfrows, int numOfcols, int array[][20]) {
    for (int i = 0; i < numOfrows; i++) {
        for (int j = 0; j < numOfcols; j++) {
            array[i][j] = 0;
        }
    }
}

int main() {
    int num_of_rows = 3;    
    int num_of_cols = 3;

    int array[num_of_rows][num_of_cols];

    InitializingToZero(num_of_rows, num_of_cols, array);

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

我得到这个输出:

0 0 0
0 0 0
268501009 0 4200656

【问题讨论】:

    标签: c arrays function multidimensional-array


    【解决方案1】:

    错误是

    int num_of_rows = 3;    
    int num_of_cols = 3;
    

    然后你传递带有列字段20 的数组。由于这个原因,数组没有正确初始化。这就是问题所在。

    你应该这样做

    void InitializingToZero(int numOfrows, int numOfcols, int array[][numOfcols]) {
    

    如果只知道数组的最大大小可以是 20x20,并且 numOfrows、numOfcols 是用户的输入,我该怎么做?

    然后你这样做

    #define MAXSIZE 20
    
    int array[MAXSIZE ][MAXSIZE];
    
    ..
    
    
    InitializingToZero(num_of_rows, num_of_cols, array);
    

    功能是

    void InitializingToZero(int numOfrows, int numOfcols, int array[][MAXSIZE]) {
    

    【讨论】:

    • 如果只知道数组的最大大小可以是 20x20,并且 numOfrows、numOfcols 是用户的输入,我该怎么做?
    • @MasterQuestion.: 好问题..我已经编辑了答案
    • @MasterQuestion.: 肯定会的。
    【解决方案2】:

    我知道 Quentin 的回答是正确的,但为什么将内存区域设置为 0 如此复杂?

    int main( void ) {
        const int COLS_AMOUNT = 3;
        static const int ROWS_AMOUNT = 3;
    
        int num_of_rows = ROWS_AMOUNT;
        int num_of_cols = ROWS_AMOUNT;
        int array[ROWS_AMOUNT][COLS_AMOUNT];
    
        /* Set to 0 */
        (void)memset( (void*)array, (int)0, sizeof( array ) );
    
        /* Then check previous set in decreasing order... */
        while( num_of_rows-- ) {
            while( num_of_cols-- ) {
                printf( "array[%d][%d]:%d ",
                        num_of_rows,
                        num_of_cols,
                        array[num_of_rows][num_of_cols] );
            }
            printf("\n");
        }
    }
    

    【讨论】:

    • 声明COLS_AMOUNTROWS_AMOUNT 而不是像在OP 的代码中那样仅使用num_of_rowsnum_of_cols 到底有什么意义?它有什么区别?为什么ROWS_AMOUNT 被声明为staticCOLS_AMOUNT 不是?
    • 至于“将内存区域设置为 0 的复杂性”......问题的价值不仅仅是将 int 数组归零。下一次它可能是其他东西的数组。一般情况下,memset 方法对于整数类型是可以的,但对于浮点类型或使用 memset 的指针,形式上不能保证有效。
    【解决方案3】:

    通过将数组声明为

    int num_of_rows = 3;    
    int num_of_cols = 3;
    
    int array[num_of_rows][num_of_cols];
    

    您正在创建大小为 [3][3] 的可变长度数组 (VLA)。但是函数参数被声明为数组[][20]

    对于正确的数组参数,传递第一个大小无关紧要(因此为空的[]),但第二个(以及进一步,如果有的话)大小必须完全匹配。通过在[3][20] 之间创建这种不匹配,您实际上是在欺骗您的功能。行为未定义。在 VLA 的情况下,编译器无法检测和报告此类不匹配,因为它们的实际大小通常在编译时是未知的。

    代码中的问题很容易解决:只需将函数参数声明为适当大小的 VLA

    void InitializingToZero(int numOfrows, int numOfcols, 
                            int array[numOfrows][numOfcols])
    

    并保持其他一切不变。 (第一个尺寸[numOfrows] 可以留“空”为[],但为了更清楚,我决定把它拼出来。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-07-02
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多