C语言 如何将双指针设置回第一个数组元素?

35g0bw71  于 2023-03-11  发布在  其他
关注(0)|答案(3)|浏览(142)

编辑以添加整个作业和预期输出。
您受雇协助消防员在一个较大的地理区域内定位野火。该区域被划分为较小的区域。每个区域都通过卫星扫描其平均温度。如果某个区域的平均温度严格高于1000°F,则我们认为该区域发生了火灾。如果温度在100度(包括在内)和1000度(包括在内),我们要进一步调查,所以它成为一个“值得关注的区域”
您正在观察的大地理区域是一个具有特定长度和宽度的矩形,每个矩形都以区域的形式给出。例如,如果要扫描的区域的长度为6,宽度为9,则它将被划分为6*9个区域:
由于程序将用于各种地理区域(每个区域都有自己的长度和宽度),因此程序需要根据要处理的区域数量动态分配内存(垂直和水平)。
为此,必须使用以下两个函数,而不更改其中的代码:

int ** allocateIntStarArray(int num){
int ** ptr = (int **) malloc(num * sizeof(int *));
return ptr;

}

int * allocateIntArray(int num){
int * ptr = (int *) malloc(num * sizeof(int));
return ptr;

}

The function `allocateIntArray()` will be used to allocate the space required to store the average temperatures in one row of zones, that is, an array of integers. The function therefore returns a pointer to such an array of integers.

The function `allocateIntStarArray()` will be used to allocate an array of pointers, each of which will store a pointer to a row of integers (temperatures of zones). That is, the function returns a pointer to an array of pointers. Each cell of this array will point to an array of integers containing the temperature values for the zones.

The inputs of the program are first the length, then the width of an area, then the average temperatures of all zones, row by row.

Please remember to free the memory you have allocated.

The output should pinpoint the possible zones with fires with [X] and the watch zone with a [*], the other zone are displayed with [ ].

    Input:

6
9
70   71   70   72   70   69
71   73   68   71   73   72
70   71   70   76   1900 78
69   71   100  800  75   71
70   70   71   79   70   69
70   71   112  1005 75   72
70   71   70   900  70   70
72   70   70   72   70   69
73   74   73   72   70   70

    Output:

[ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][X][ ]
[ ][ ][*][*][ ][ ]
[ ][ ][ ][ ][ ][ ]
[ ][ ][*][X][ ][ ]
[ ][ ][ ][*][ ][ ]
[ ][ ][ ][ ][ ][ ]
[ ][ ][ ][ ][ ][ ]
----

The code I'm working on is to create a matrix based off user input. I'm having an issue getting my variable **mat back to the first array element so that it will print the rectangle correctly. Could someone enlighten me on how to do this? What I have so far:

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

int **allocateIntStarArray(int);
int *allocateIntArray(int);
int **allocateMatrix(int, int);

void readValues(int **, int, int);
void print(int **, int, int);

int main(void) {
    int rows, cols;

scanf("%d %d", &rows, &cols);
    int **mat = allocateMatrix(rows, cols);

    readValues(mat, cols, rows);
    print(mat, cols, rows);

    /* free your memory */
    for (int r = 0; r < rows; r++){
        free(mat[r]);
    }
    free(mat);
    return 0;
}

void readValues(int **mat, int ncols, int nrows) {
    for (int r = 0; r < nrows; r++) {
        for (int c = 0; c < ncols; c++) {
            scanf("%d", &mat[r][c]);

            
        }
    }
}

void print(int **mat, int ncols, int nrows) {
    for (int r = 0; r < nrows; r++) {
        for (int c = 0; c < ncols; c++) {
            int value = mat[r][c];

            if (value > 1000){
                printf("[X]");
            }
            else if (value >= 100){
                printf("[*]");
            }
            else{
                printf("[ ]");
            }
        
        }
        printf("\n");
    }
}

int **allocateMatrix(int nrows, int ncols) {
    
    int **mat = allocateIntStarArray(nrows);

    for (int row = 0; row <= nrows; ++row) {
        mat[row] = allocateIntArray(ncols);
    }

    return mat;
}

/* Provided functions, do not edit */
int **allocateIntStarArray(int num) {
    int **ptr = (int **) malloc(num * sizeof(int *));
    return ptr;
}

int *allocateIntArray(int num) {
    int *ptr = (int *) malloc(num * sizeof(int));
    return ptr;
}
gcmastyq

gcmastyq1#

我不会用双指针代替二维数组。

void *allocateMatrix(size_t nrows, size_t ncols, int (**array)[ncols]) 
{
    int (*arrptr)[ncols]  = malloc(nrows * sizeof(*arrptr));
    if(array) *array = arrptr;
    return arrptr;
}

int main(void)
{
    size_t cols = 30, rows = 40;
    int (*matrix)[cols] = allocateMatrix(rows, cols, NULL);

    if(matrix)
    {
        matrix[5][4] = 97;
        matrix[4][2] = matrix[5][4] * 4;
        printf("%d %d\n", matrix[5][4], matrix[4][2]);
    }
    free(matrix);
}

更简单,只有一次分配/释放,用法与数组相同,并且由于删除了一个间接级别而更加高效。
还应使用正确的大小和索引类型:size_t

k5ifujac

k5ifujac2#

scanf("%d", &**mat);中,第一个*将被它的对应物&平衡,因为这两个操作符具有相反的效果。
结果为*mat,即int *类型的值。虽然is是%d说明符的正确类型,但*mat是矩阵中第一个子数组的地址。重复读取此地址的值将继续覆盖第一个子数组(mat[0][0])的第一个值。
由于您从不移动任何指针,矩阵的其余部分将保持未初始化状态。
也就是说,不需要手动管理指针,因为你已经在计算索引了,只需要在索引中使用数组下标符号,并获取每个值的位置地址。

scanf("%d", &mat[rows][cols]);

在print函数中,mat - num将解析为您不应该尝试访问的某个地址,因为它超出了mat对象的范围,这是Undefined Behavior的一个经典示例。
然后尝试将m设置为通过此地址定位的某个值,但仅一次。
同样,您已经在计算索引,因此要充分利用它们。将 inner 循环中的m设置为mat[rows][cols]中的值,以便在每次迭代时更新其值。
这是一个函数式程序,其中有一个释放所分配内存的例子。

  • (注意:如前所述,size_t是用于内存大小和索引的正确类型。这里我坚持使用int,以匹配教师的flawed实现。)*
#include <stdio.h>
#include <stdlib.h>

int **allocateIntStarArray(int);
int *allocateIntArray(int);
int **allocateMatrix(int, int);

void readValues(int **, int, int);
void print(int **, int, int);

int main(void) {
    int rows, cols;

    if (2 != scanf("%d %d", &cols, &rows)) {
        fprintf(stderr, "Could not read matrix size information.\n");
        return EXIT_FAILURE;
    }

    int **mat = allocateMatrix(rows, cols);

    readValues(mat, cols, rows);
    print(mat, cols, rows);

    /* free your memory */
    for (int i = 0; i < rows; i++)
        free(mat[i]);
    free(mat);
}

void readValues(int **mat, int ncols, int nrows) {
    for (int i = 0; i < nrows; i++) {
        for (int j = 0; j < ncols; j++) {
            if (1 != scanf("%d", &mat[i][j])) {
                fprintf(stderr, "Invalid value read.\n");
                exit(EXIT_FAILURE);
            }
        }
    }
}

void print(int **mat, int ncols, int nrows) {
    for (int i = 0; i < nrows; i++) {
        for (int j = 0; j < ncols; j++) {
            int value = mat[i][j];

            if (value > 1000)
                printf("[X]");
            else if (value >= 100)
                printf("[*]");
            else
                printf("[ ]");
        }

        /* print a newline after every row */
        putchar('\n');
    }
}

int **allocateMatrix(int nrows, int ncols) {
    int **mat = allocateIntStarArray(nrows);

    for (int row = 0; row < nrows; ++row) {
        mat[row] = allocateIntArray(ncols);
    }

    return mat;
}

/* Provided functions, do not edit */
int **allocateIntStarArray(int num) {
    int **ptr = (int **) malloc(num * sizeof(int *));
    return ptr;
}

int *allocateIntArray(int num) {
    int *ptr = (int *) malloc(num * sizeof(int));
    return ptr;
}

下面是我用来快速生成测试数据的程序:

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

int main(void) {
    srand((unsigned) time(NULL));

    int rows = (rand() % 20) + 1;
    int cols = (rand() % 20) + 1;

    printf("%d %d\n", rows, cols);

    for (int i = 0, n = rows * cols; i < n; i++)
        printf("%d ", rand() % 2000);
}

更新:
正如我所怀疑的,您将行和列的索引弄混了。
根据矩阵的构建方式,第一个下标值(matrix[r])对应于 row,第二个下标值(matrix[r][c])对应于该行中的 column
单位:read_values

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

以及在print

for(i=0;i<ncols;i++){
    for(j=0;j<nrows;j++){
        int value = mat[i][j];
        /* ... */

您已经将它们翻转过来,访问mat[COLUMN as i][ROW as j]
i >= nrowsj >= ncols时,您将访问超出界限的内存。
翻转嵌套循环也可能是一个好主意,这样它们就读作 “for each row,for each column”,这更好地匹配了下标语法:

for (int r = 0; r < nrows; r++)    
    for (int c = 0; c < ncols; c++)       
        scanf("%d", &mat[r][c]);

此外,在main中,只有在释放了所有子数组之后才必须使用free(mat);first

for(int i=0;i<rows;i++){ 
    free(mat[i]);
}   

free(mat); /* move this outside, after the loop */

否则,mat在第二次迭代上将是dangling pointer,并且mat[i]将调用Undefined Behavior
最后要注意的是,为了满足任务要求,您的中间温度范围应该是value >= 100,因为该范围包括([100, 1000])。

yftpprvb

yftpprvb3#

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

int * allocateIntArray(int num);
int ** allocateIntStarArray(int num);

int main(void)
{
    int rown, coln,i,j;
    scanf("%d %d",&coln,&rown);
    int ** matrix = allocateIntStarArray(rown);
    for(i = 0; i < rown; i++){
        matrix[i] = allocateIntArray(coln);
    }

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

    for(i = 0; i < rown; i++){
        for(j = 0; j < coln; j++){
            if(matrix[i][j]>1000){
                printf("[X]");
            }
            else{
                if(matrix[i][j]>=100){
                    printf("[*]");
                }
                else{
                    printf("[ ]");
                }
            }
        }
        printf("\n");
    }
    return 0;
}

int ** allocateIntStarArray(int num){
    int ** ptr = (int **) malloc(num * sizeof(int *));
    return ptr;
}

int * allocateIntArray(int num){
    int * ptr = (int *) malloc(num * sizeof(int));
    return ptr;
}

相关问题