【问题标题】:Subscripted value not array nor pointer下标值不是数组也不是指针
【发布时间】:2014-11-29 03:50:09
【问题描述】:

我有一个程序可以从文件中读取二维数组,并使其成为锯齿状数组(其中每一行的大小都非常适合所有非零元素)。然后将数组打印出来。

但我有几个问题我想不通。

具体

26: 我收到一个警告(赋值使指针变成整数而没有强制转换

44: 错误:下标值既不是数组也不是指针

我能做些什么来解决它?

int main() {

FILE *inputFile1 = fopen("denseMatrix1.txt", "r");

char inputBuffer[SIZE];
int dim1, dim2, input, i, j;
int *mtrx1;

fgets(inputBuffer, SIZE, inputFile1);
sscanf(inputBuffer, "%d%d", &dim1, &dim2);

mtrx1 = malloc(sizeof(int *) * dim1);

for (i=0; i<dim1; i++) {
    int cols=0;
    int *row = malloc(sizeof(int) * cols);
    fgets(inputBuffer, SIZE, inputFile1);
    for (j=0; j<dim2; j++) {
        sscanf(inputBuffer, "%d", input);
        printf("i=%d   j=%d    input=%d\n", i, j, input); // ADDED LINE (NOT PRINTING)
        if (input) {
            cols++;
            row = realloc(row, sizeof(int) * cols);
            row[cols-1] = input;
        }
    }
    mtrx1[i] = row;
    cols=0;
}

int mtrx3[DIM1][DIM2] = {0};

// Prints first 2 matrices
printf("First matrix: \n");
printMatrix(mtrx1, dim1);/*

return 0;


// Prints a 2d array matrix
void printMatrix(int *mtrx, int dim1) {
int i, j;
for (i=0; i<dim1; i++) {
    for (j=0; j<(sizeof(mtrx[i]) / sizeof(int)); j++) {
        printf("%d ", mtrx[i][j]);
    }
    printf("\n");
}
printf("\n\n");

denseMatrix1.txt 文件内容:

7 8
0 0 0 5 1 0 0 5
0 0 0 0 0 0 0 0
0 0 0 0 1 2 0 0
1 0 0 0 0 0 0 0
3 0 0 5 0 0 3 0
1 0 0 0 0 3 0 0
0 0 0 0 0 0 0 1

【问题讨论】:

  • 此代码无法编译,并且语法中有几个错误,例如此行末尾的 '*': printMatrix(mtrx1, dim1);/* 并且即使该错误不存在,缺少 main() 函数末尾的关闭“}”,printMatrix() 函数的其余部分也是如此
  • 需要检查来自 I/O 输入函数(scanf、fgets)的返回值,以确保实际发生所需的操作。由于空格仍在输入中(例如换行符),scanf() 的格式字符串将失败。要解决这个问题,格式字符串中需要有一个前导“”
  • 如果调用 realloc() 失败,那么下一行代码将导致 seg 错误事件。 IE。使用前测试返回值
  • 变量“输入”未定义。你有没有尝试编译这段代码?

标签: c arrays malloc realloc


【解决方案1】:

代替

int *mtrx1;

使用

int **mtrx1;

使用前一个声明,mtrx[i] 的计算结果为 int。您需要将其评估为 int* 才能使用:

mtrx1[i] = row;

更新

您使用fgets 获取一行文本并将该行与sscanf 一起使用的策略在for 循环中不起作用。

我们取矩阵的第一行:

0 0 0 5 1 0 0 5

还有for 循环:

for (j=0; j<dim2; j++) {
    sscanf(inputBuffer, "%d", input);
    printf("i=%d   j=%d    input=%d\n", i, j, input); // ADDED LINE (NOT PRINTING)
    if (input) {
        cols++;
        row = realloc(row, sizeof(int) * cols);
        row[cols-1] = input;
    }
}

for 循环中,每次第一行都会将0 分配给inputsscanf 不会存储您第一次阅读的内容并从剩下的内容继续。

您需要想出不同的策略。例如:

for (i=0; i<dim1; i++) {
   int cols=0;
   int *row = malloc(sizeof(int) * cols);
   fgets(inputBuffer, SIZE, inputFile1);
   char* token = strtok(inputBuffer, " \n");
   for (j=0; j<dim2; j++) {
      input = atoi(token);
      printf("i=%d   j=%d    input=%d\n", i, j, input);
      if (input) {
         cols++;
         row = realloc(row, sizeof(int) * cols);
         row[cols-1] = input;
      }
      token = strtok(NULL, " \n");
   }
   mtrx1[i] = row;
   cols=0;
}

【讨论】:

  • 新策略是有道理的,但我收到关于在没有演员表的情况下进行作业的警告。而且它仍然不会打印出 printf。真的不知道还能做什么,但我需要使用 sscanf。
【解决方案2】:

第 26 行警告

这是有问题的行:

mtrx1[i] = row;

以下是这些变量的声明:

int *mtrx1;
int ..., i, ...;
int *row = ...;

正如您的警告消息所说,您正在尝试获取一个指针值row,并将其分配给ints 的数组。假设你想要 mtrx1 成为一个单独的 row 子数组的数组,你应该相应地改变它的类型——从 int *,它是一个 ints 的数组,到 int **,它将是ints 的 arrays 数组。

第 44 行错误

相关代码:

void printMatrix(int *mtrx, int dim1) {
    int i, j;
    ...
    printf("%d ", mtrx[i][j]); // line 44
    ...
}

这一行的错误是由与上面类似的问题导致的——mtrx 被声明为int 的一维数组,但在第 44 行你有两个下标,就好像它是一个二-维数组。这也可以通过将mtrx 的类型更改为int ** 来解决。

For 循环

for 循环无法遍历所有值,因为您的 sscanf 行不明确 - 您的 %d 值之间没有空格,因此 sscanf 无法判断哪个数字应该是哪个,并且它将它们作为一个值读取。这意味着dim2 永远不会正确设置。

对于这种错误,使用断点通常是了解程序中发生了什么的最简单方法,尤其是对于循环。如果您还没有研究过它们,那么您应该这样做。

附加信息

第 26 行给你一个警告,而第 44 行给你一个错误,因为在 C 中定义指针的方式与 int 相关。C 允许“指针算术”,这意味着除了指针之外,指针还可以被视为纯数字引用对象或数组。

当您在 C 中为数组下标时,表达式的类型实际上只是删除了 *;例如,下标int * 数组的类型为int。因此,当您尝试将指针分配给int *mtrx1 时,它会将其视为尝试将指针分配给int 变量,因此指针将转换为其原始数值。这是完全合法的 C,但被大多数程序员认为是相当糟糕的做法(出于各种原因),因此编译器会为此发出警告。

第 44 行的情况正好相反——你的 mtrx[i][j] 表达式等同于 (mtrx[i])[j]。由于mtrx 仅定义为int *,这意味着您实际上最终会尝试为int 下标,这在C 中完全是非法的。没有警告,只是一个错误。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-07-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多