C编程中的数组

Arrays in C programming

我正在编写以下二维数组程序来输出如图所示的结果:

我似乎无法获取结果的最小值并以数组形式显示它。 代码如下:

#include<stdio.h>
#define NUMROWS 2
#define NUMCOLS 3

//accessing elements of 2D array using pointers
int main(void){

    const int table[NUMROWS][NUMCOLS]={{1,2,3},{5,6,7}};
    int minvals[NUMROWS];
    int i, j;
    int *ptr = &table;

    //accessing the elements of 2D array using ptr
    printf("table values:  min value\n");

    for(int i=0;i<NUMROWS;i++){
        for(int j=0;j<NUMCOLS;j++)
            printf("%d ",*((ptr+i*NUMCOLS)+j)); 
        printf("\n");
    }
    
    for(int i=0;i<NUMROWS;i++){
        for(int j=0;j<NUMCOLS;j++)
            printf("%d ",*((ptr+i*NUMCOLS)+j)<minvals[i]); 
    }
    return 0;
}

int *ptr = &table;

是错误的,因为 &tableint (*)[2][3] 类型(即指向整个 table 的指针),而 ptr 是指向单个元素的指针。此外,您的指针是非 const,因此不能指向 const 数组。

如果您希望 ptr 指向单个 int 值,则应按以下方式声明它:

const int *ptr = &table[0][0];

此外,您正在读取数组 minvals 的内容,尽管该数组包含未初始化的数据。这没有意义并会导致未定义的行为。

而不是用表达式

做复杂的指针运算

*((ptr+i*NUMCOLS)+j))

你可以简单地写下:

table[i][j]

这样,您就不需要指针 ptr 并且您的代码更简单。

minvals的存在意味着你需要计算table之前的每个'row'的最小值然后移动开始印刷。就目前而言,如果您的程序正确计算了每个数组的最小值,您的打印就会出现问题。

无需进行任何棘手的手动指针操作。简单的数组订阅就清晰多了。

让我们从简单的 return 基础开始,看看我们在一维数组中找到最小值的方法,因为它是这个问题的核心。

要找到数组中的最小值,我们需要做一些事情:

  • 数组
  • 数组的长度
  • 要比较的初始值

数组本身显然是table的每个子数组,本例中的长度已知为NUMCOLS。我们的初始值应该是 INT_MAX(或找到的另一个适合类型的最大常量 <limits.h>),这样数组中的每个元素都等于或小于我们的初始值,或者数组中的一个值本身。

我们经常在这里选择第二个选项,选择数组中的第一个元素作为我们的初始值,并将它与第二个和后续元素进行比较。

因此,在单个 'row' 中找到最小值看起来像这样

const int row[NUMCOLS] = { 9, 2, 5 };
int min = row[0];

for (int i = 1; i < NUMCOLS; i++)
    if (row[i] < min)
        min = row[i];

但由于我们要查找并记录table中每个'row'的最小值,我们将使用嵌套循环。我们将每个值存储在 minvals 数组的关联索引中,而不是之前的 min 变量。

for (i = 0; i < NUMROWS; i++) {
    minvals[i] = table[i][0];

    for (j = 1; j < NUMCOLS; j++)
        if (table[i][j] < minvals[i])
            minvals[i] = table[i][j];
}

当需要打印时,我们将重复我们的嵌套循环。我们的内循环打印 table 的每个 'row' 的每个元素,我们通过打印在 minvals 中找到的值与我们的 'row' 相同的索引来结束外循环的每次迭代].

for (i = 0; i < NUMROWS; i++) {
    for (j = 0; j < NUMCOLS; j++)
        printf("%6d", table[i][j]);

    printf(":%6d\n", minvals[i]);
}

这是一个工作示例。

#include <stdio.h>
#define NUMROWS 2
#define NUMCOLS 3

int main(void) {
    const int table[NUMROWS][NUMCOLS] = {
        { 9, 2, 5 },
        { 3, -4, -12 }
    };
    int minvals[NUMROWS];
    int i, j;

    for (i = 0; i < NUMROWS; i++) {
        minvals[i] = table[i][0];

        for (j = 1; j < NUMCOLS; j++)
            if (table[i][j] < minvals[i])
                minvals[i] = table[i][j];
    }

    puts("Table value: minimum values");

    for (i = 0; i < NUMROWS; i++) {
        for (j = 0; j < NUMCOLS; j++)
            printf("%6d", table[i][j]);

        printf(":%6d\n", minvals[i]);
    }
}

对您来说,一个很好的进一步练习是将用于查找最小值的内循环逻辑组合到一个更通用的函数中。它的函数签名看起来像

int min(int *array, size_t length);

允许它在不同大小的数组上工作。那么我们的外层循环就可以这么简单:

for (i = 0; i < NUMROWS; i++)
    minvals[i] = min(table[i], NUMCOLS);