C语言 使用函数减少重复性

pftdvrlh  于 2023-02-03  发布在  其他
关注(0)|答案(2)|浏览(137)

我研究这个问题已经有一段时间了:基本上我需要把for循环放到一个函数中,这样我就可以调用它,但是我不知道如何让函数返回一个2D数组,我想通过创建一个1D数组来解决这个问题,但是问题是我的任务是计算一个矩阵对角线下的数字之和,所以我需要它首先是2D的,然后它就只能变成1D的了,有人有解决办法吗?
也许我的思维过程是错误的,有人可以建议如何把for循环放在函数中?如果没有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
}

必须满足的条件:
1.用户决定方阵的大小
1.必须用随机数填充矩阵
1.函数调用的数组必须是使用i*N+j的1D数组,无法传递2D数组

kmpatx3s

kmpatx3s1#

让我们考虑一下你的任务
必须满足的条件:
1.用户决定方阵的大小
1.必须用随机数填充矩阵
1.函数调用的数组必须是使用i * N + j的1D数组,不能传递2D数组
首先,矩阵必须是正方形。
这就是你的功能

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 *类型的指针。没有必要创建一个辅助的一维数组。
下面是一个演示程序,它展示了如何声明和定义函数,以及如何将矩阵传递给函数。

#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 ) );
}

程序输出为

sum of elements under the main diagonal = 55

定义函数并调用它的另一种方法如下

#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 ) );
}

程序输出与上图相同。

sum of elements under the main diagonal = 55
sauutmhj

sauutmhj2#

2d数组并不存在,编译器只允许你写a[i][j],这样你就可以相信它们了,下面是一些简单的代码来演示一些方法:

#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.
 */

相关问题