简体   繁体   English

使用函数减少重复

[英]Using functions to lesser repetitiveness

I have been working on this problem for a while now: basically I need to put the for loop in a function so I can call for it, but I don't how to to make a function return a 2D array, I want to solve this by creating a 1D array, but the problem is that my task is to compute the sum of numbers under the diagonal of a matrix, so I need it to be 2D first, then it can only become 1D.我已经研究这个问题一段时间了:基本上我需要将for循环放在 function 中,这样我就可以调用它,但是我不知道如何让 function 返回一个二维数组,我想解决这是通过创建一个一维数组,但问题是我的任务是计算矩阵对角线下的数字总和,所以我需要它首先是二维的,然后它只能变成一维的。 Does anyone have a solution?有没有人有办法解决吗?

Maybe my thought process is just wrong and somebody could just recommend how to put the for loops in functions?也许我的思考过程是错误的,有人可以建议如何将for循环放入函数中? If it was without the if clause inside then I might have an idea, but now I really don't.如果里面没有if子句,那么我可能会有想法,但现在我真的没有了。

#include <math.h>
#include <stdio.h>
#include <stdlib.h> // libraries added from example
#include <time.h>

//(*) For a square matrix calculate the sum of elements under the main diagonal excluding it.
#define A -10
#define B 10

int main() {
    void enter(int *x, int *y);
    int get_random(int lbound, int ubound); // telling the programs that functions are declared
    int r;
    int c;
    int row, col, sum = 0;
    enter(&r, &c); // calling the function
    srand48(time(NULL)); //Call srand48 with current time reported by `time` casted to a long integer.
    // srand48 is used to reinitialize the most recent 48-bit value in this storage
    int array[r][c]; // we decided its gonna be r rows and c columns
    int line[r * c]; // turning 2d into 1d array
    for (row = 0; row < r; ++row) // we cycle numeration of rows of matrix
    {
        for (col = 0; col < c; col++) // we cycle numeration of columns of matrix
        {
            array[row][col] = get_random(B, A);// filling array with random numbers, taken from example
            printf("%d ", array[row][col]);
            if (row > col) { //since we want the sum numbers below the diagonal row>col must be true
                sum = sum + array[row][col];// if row>col then we add the number to our sum;
            };
        }
        printf("\n"); // this is to break line after row 1,2 col 3, so it looks nicer
    }
    for (row = 0; row < r; ++row) // we cycle numeration of rows of matrix
    {
        for (col = 0; col < c; col++) // we cycle numeration of columns of matrix
        {
            line[row * r + col] = array[row][col];
        }
    }
    printf("the array in 1D: ");
    for (row = 0; row < r * c; row++) {
        printf("%d ", line[row]);
    }
    printf("\n");
    printf("sum of array below the diagonal: %d\n", sum);

    return 0;
}

void enter(int *x, int *y) { // we have to use pointers if we want more then one return from a function

    printf("How man rows in array?  "); // just like the last lab we decide how big the matrix will be
    scanf("%d", x); // we use x instead of &x because we need the address of the number not the value
    printf("How man columns in array? ");
    scanf("%d", y); // we use y instead of &y because we need the address of the number not the value
}

int get_random(int lbound, int ubound) {
    return mrand48() % (ubound - lbound + 1) + lbound; // function for generating random numbers
}

Conditions have to be met:必须满足以下条件:

  1. the user decides size of square matrix用户决定方阵的大小

  2. the matrix has to be filled with random numbers矩阵必须用随机数填充

  3. the array is called by the function has to be 1D using i*N+j , 2D array can't be passed function 调用的数组必须是 1D 使用i*N+j ,不能传递 2D 数组

Let's consider your assignment让我们考虑一下你的任务

Conditions have to be met:必须满足以下条件:

  1. the user decides size of square matrix用户决定方阵的大小

  2. the matrix has to be filled with random numbers矩阵必须用随机数填充

  3. the array is called by the function has to be 1D using i*N+j, 2D array can't be passed function 调用的数组必须是 1D 使用 i*N+j,不能传递 2D 数组

Firstly the matrix must be square.首先矩阵必须是正方形的。

So this your function所以这是你的 function

void enter(int *x, int *y) { // we have to use pointers if we want more then one return from a function

    printf("How man rows in array?  "); // just like the last lab we decide how big the matrix will be
    scanf("%d", x); // we use x instead of &x because we need the address of the number not the value
    printf("How man columns in array? ");
    scanf("%d", y); // we use y instead of &y because we need the address of the number not the value
}

does not make sense.没有意义。 The user can enter different values for the numbers of rows and columns of the matrix.用户可以为矩阵的行数和列数输入不同的值。 You need to enter only one positive value.您只需输入一个正值。

Secondly as we are speaking about a matrix then it means that you have to define a two-dimensional array.其次,当我们谈论矩阵时,这意味着您必须定义一个二维数组。

Also you need to write a function that will calculate the sum of elements under the main diagonal of a matrix.您还需要编写一个 function 来计算矩阵主对角线下元素的总和。 The function is declared such a way that it can accept only a one-dimensional array. function 的声明方式使其只能接受一维数组。 This means that you need to pass your matrix to the function casting it to a pointer of the type int * .这意味着您需要将矩阵传递给 function 并将其转换为int *类型的指针。 There is no need to create an auxiliary one-dimensional array,无需创建辅助一维数组,

Here is a demonstration program that shows how the function can be declared and defined and how the matrix can be passed to the function.下面是一个演示程序,展示了如何声明和定义 function 以及如何将矩阵传递给 function。

#include <stdio.h>

long long int sum_under_dioganal( const int a[], size_t n )
{
    long long int sum = 0;

    for (size_t i = 1; i < n; i++)
    {
        for (size_t j = 0; j < i; j++)
        {
            sum += a[i * n + j];
        }
    }

    return sum;
}

int main( void )
{
    enum { N = 5 };
    int a[N][N] =
    {
        {  0,  0,  0,  0,  0 },
        {  1,  0,  0,  0,  0 },
        {  2,  3,  0,  0,  0 },
        {  4,  5,  6,  0,  0 },
        {  7,  8,  9, 10,  0 }
    };

    printf( "sum of elements under the main diagonal = %lld\n",
        sum_under_dioganal( ( int * )a, N ) );
}

The program output is程序 output 是

sum of elements under the main diagonal = 55

Another approach to define the function and call it is the following另一种定义 function 并调用它的方法如下

#include <stdio.h>

long long int sum_under_dioganal( const int a[], size_t n )
{
    long long int sum = 0;

    size_t m = 0;

    while (m * m < n) ++m;

    if (m * m == n)
    {
        for (size_t i = 1; i < m; i++)
        {
            for (size_t j = 0; j < i; j++)
            {
                sum += a[i * m + j];
            }
        }
    }

    return sum;
}

int main( void )
{
    enum { N = 5 };
    int a[N][N] =
    {
        {  0,  0,  0,  0,  0 },
        {  1,  0,  0,  0,  0 },
        {  2,  3,  0,  0,  0 },
        {  4,  5,  6,  0,  0 },
        {  7,  8,  9, 10,  0 }
    };

    printf( "sum of elements under the main diagonal = %lld\n",
        sum_under_dioganal( ( int * )a, N * N ) );
}

The program output is the same as shown above.程序output与上图相同。

sum of elements under the main diagonal = 55

2d arrays don't really exist. 2d arrays 并不真正存在。 The compiler just allows you to write a[i][j] so that you can believe in them.编译器只是让你写a[i][j]这样你就可以相信它们了。 Here's some simple code to demonstrate a few methods:下面是一些简单的代码来演示一些方法:

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

void *
make_array(size_t size)
{
        int *a = malloc(sizeof *a * size * size);
        int *t = a;
        if( a == NULL ){
                perror("malloc");
                exit(1);
        }
        for( int row = 0; row < size; row += 1 ){
                for( int col = 0; col < size; col += 1 ){
                        *t++ = rand() % 32 - 16;
                }
        }
        return a;
}

int
trace(void *v, size_t s)
{
        int *a = v;
        int sum = 0;
        for( size_t i = 0; i < s; i += 1 ){
                sum += *a;
                a += s + 1;
        }
        return sum;
}


int
main(int argc, char **argv)
{
        srand(time(NULL));
        size_t s = argc > 1 ? strtol(argv[1], NULL, 0) : 5;
        void *v = make_array(s);

        /* a, b, c, and d will demonstrate different access techniques */
        int *a = v;       /* a is the conventional "1-d array" (1)*/
        int (*b)[s] = v;  /* b is a "two-d" array */
        int *c = v;       /* c iterates through each element */
        int *d = v;       /* d treats each row as a 1-d array */

        for( int i = 0; i < s; i += 1 ){
                for( int j = 0; j < s; j += 1 ){
                        printf("%3d  ", b[i][j]);
                        assert( a[i * s + j] == b[i][j] );
                        assert(     *c       == b[i][j] );
                        assert(    d[j]      == b[i][j] );
                        c += 1;
                }
                d += s;
                putchar('\n');


         }
         printf("trace: %d\n", trace(v, s));
    }

   
/* (1) These comments are not strictly accurate.  `a` is *not* an
 * array, and `b` is *not* a 2-d array.  `a` is a pointer, and `b` is
 * an array of pointers.  Arrays are not pointers, and pointers are
 * not arrays.
 */

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM