【问题标题】:How to do an operation in two arrays and stock it in one?如何在两个数组中进行操作并将其存储在一个数组中?
【发布时间】:2019-12-14 05:28:08
【问题描述】:

我是 C 的新程序员,最近我渴望学习机器学习。我编写了一个程序只是为了了解内核是如何工作的,但结果证明它给了我一个未定义的行为错误。问题很可能出在计算 O 数组中,或者可能出在打印中。

int S[M][N];
srand(time(NULL));

for(i = 0; i < M; i++) {
    for(j = 0; j < N; j++) {
        S[M][N] =rand() % ARRAY_RANGE;
        printf("%d\t", S[M][N]);
    }
    printf("\n\n");
}


//S[M][N] initialized and printed here. No problem.

int K[3][3];

printf("Enter the kernel: \n");

for( i = 0 ; i<3; i++ ){
    for(j = 0; j<3; j++){
        scanf("%d", &K[i][j]);
    }
}

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

 unsigned long long int O[M][N] = {{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0},{0,0,0,0,0}};
   long int sum,m,n;

for(i = 0; i < M-2 ; i++){
     for(j = 0; j < N-2; j++){
        for(k = 0; k < 3; k++){
         for(l = 0; l < 3; l++){
             O[i+1][j+1] += (S[i+l][j+k])*(K[k][l]);           

               }        
          } 
     } 
 }


       for (i=0; i<M; i++){
          for(j=0; j<N; j++){
             printf("%d", O[i][j]);
             }
              printf("\n");
         }
    return 0;
}

应该是这样的:

0        0         0          0         0
0   *calculated 3 integers of O array*  0
0   *calculated 3 integers of O array*  0 
0   *calculated 3 integers of O array*  0
0       0          0          0         0

但它会给出随机的非常大或非常小的数字,例如“3241242”或“-2431452”,我在其中写了计算出 O 数组的 3 个整数

-编辑了我如何初始化 S 数组。我也包含了 stdio.h、stdlib.h、time.h。

【问题讨论】:

  • 请解释它应该做什么,它做了什么,确切的错误是什么,它是编译时错误还是运行时错误等。我们需要细节来帮助你
  • 对不起,我是 Stack Overflow 的新手,无法立即回复:它应该像一个 5x5 矩阵,顶部有 5 个零,底部有 5 个零,中间有 5 个零,如下所示:0 计算O数组的三个整数 0
  • 然后它做了什么?
  • @whysoserious 没问题,欢迎来到 SO!我建议editing your post 提供输入/输出作为具体示例,并附上解释。在某些数据中硬编码比依赖scanf 更好,这可能是任何东西。谢谢。
  • 我不知道错误的类型,但它看起来像整数溢出。在我写 计算 O 数组的三个整数的地方,有随机的非常大的数字或非常小的负数,例如:19725214 或 -24246214

标签: c arrays multidimensional-array


【解决方案1】:

你有一些小问题(一些错字,一些不是)。首先,与拼写错误相关的错误是:

    S[M][N] =rand() % ARRAY_RANGE;
    printf("%d\t", S[M][N]);

这显然应该是:

    S[i][j] = rand() % ARRAY_RANGE;
    printf("%d\t", S[i][j]);

您有一个转换说明符不匹配,当您尝试将O(类型unsigned long long int)打印为"%d"(签名int)时调用未定义行为 )。 long long unsigned 的正确转换说明符是 "%llu"

O 中的每个元素都不需要指定为零,只需初始化第一个元素,然后默认将所有其他元素设置为零,例如

    unsigned long long int O[M][N] = {{0}};

C11 Standard - § 6.7.9 Initialization (p21)

把它放在一起并添加标题和定义,你可以做类似的事情:

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

#define M 5
#define N M
#define ARRAY_RANGE 1000

int main (void) {

    int S[M][N];

    srand(time(NULL));

    for(int i = 0; i < M; i++) {
        for(int j = 0; j < N; j++) {
            S[i][j] = rand() % ARRAY_RANGE;
            printf("%d\t", S[i][j]);
        }
        printf("\n\n");
    }

    int K[3][3];

    printf("Enter the kernel: \n");

    for (int i = 0 ; i<3; i++ ) {
        for (int j = 0; j<3; j++) {
            scanf("%d", &K[i][j]);
        }
    }

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

    unsigned long long int O[M][N] = {{0}};

    for (int i = 0; i < M-2 ; i++) {
        for (int j = 0; j < N-2; j++) {
            for (int k = 0; k < 3; k++) {
                for (int l = 0; l < 3; l++){
                    O[i+1][j+1] += (S[i+l][j+k])*(K[k][l]);           
                }        
            } 
        } 
    }


    for (int i = 0; i < M; i++) {
        for (int j = 0; j < N; j++) {
            printf (" %5llu", O[i][j]);
        }
        putchar ('\n');
    }
    return 0;
}

注意:未使用的变量long int sum,m,n;被省略)

输入 3x3 示例

$ cat dat/3x3.txt
1 2 3
4 5 6
7 8 9

使用/输出示例

$ ./bin/three2d <dat/3x3.txt
445     971     809     962     208

648     547     459     981     634

656     529     534     710     10

796     548     696     998     647

215     857     384     698     54

Enter the kernel:
   1   2   3


   4   5   6


   7   8   9


     0     0     0     0     0
     0 27643 33359 22960     0
     0 26218 33460 27418     0
     0 25653 31352 20828     0
     0     0     0     0     0

查看一下,如果您还有其他问题,请告诉我。

【讨论】:

  • 非常感谢先生。还有一件事:如何以 3x3 格式获得带有 scanf 的内核?当我想得到它时,它总是 9x1 格式,因为当我用 scanf 阅读内容时我必须按 Enter。
  • scanf("%d", &amp;K[i][j]); 将读取任何格式的 9 个数字。 "%d" 格式说明符会忽略所有空格,因此我可以在第一行使用 9 个值并且它会正常读取。另请注意,我将stdin 上的文件重定向 到调用该程序为./bin/three2d &lt;dat/3x3.txt 的程序。我不是在“输入”单个值并在两者之间按[Enter]
猜你喜欢
  • 1970-01-01
  • 2021-07-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-06-14
  • 2021-12-19
  • 1970-01-01
相关资源
最近更新 更多