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

问题描述 投票:0回答:3

编辑以添加整个作业和预期输出。

您受雇协助消防员在广阔的地理区域定位野火。该区域被划分为更小的区域。通过卫星扫描每个区域的平均温度。如果一个区域的平均温度严格高于 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;
}
c pointers debugging matrix
3个回答
0
投票

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

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


0
投票

scanf("%d", &**mat);
中,第一个
*
将被它的
&
对应物平衡,因为两个运算符具有相反的效果。

结果将是

*mat
,一个
int *
类型的值。虽然 is 是
%d
格式说明符的正确类型,但
*mat
是矩阵中第一个子数组的地址。重复读取该地址的值将继续覆盖第一个子数组的第一个值(
mat[0][0]
)。

因为你永远不会移动任何指针,矩阵的其余部分将保持未初始化状态。

也就是说,不需要手动管理你的指针,因为你已经在计算索引了。只需在索引中使用 array subscript notation,并获取每个值位置的地址。

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

(参见会员访问运营商

在 print 函数中,

mat - num
将解析为一些您不应尝试访问的地址,因为它在
mat
对象的范围之外。这是未定义行为的经典例子。

然后您尝试将

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 >= nrows
,或者
j >= ncols
.

翻转嵌套循环也可能是个好主意,这样它们就读作 “对于每一行,对于每一列”,这更符合下标语法:

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

此外,在

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

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

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

否则

mat
将在第二次迭代中成为 悬空指针,并且
mat[i]
将调用 Undefined Behavior.

最后注意,为了符合作业要求,您的中间温度范围应该是

value >= 100
,因为该范围包括(
[100, 1000]
)。


0
投票
#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;
}
© www.soinside.com 2019 - 2024. All rights reserved.