【问题标题】:Error: subscripted value is not an array, pointer, or vector and idk what the issue is? [closed]错误:下标值不是数组、指针或向量,idk 是什么问题? [关闭]
【发布时间】:2017-09-05 17:39:29
【问题描述】:

本练习的目的是使用动态内存分配的双下标方法。 这个程序的输入是一个二维浮点数据数组,位于一个名为 测试数据2。输入数组将包含 3 行数据,每行包含 5 列数据。

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

int main()
{
    FILE *fp;
    int temp;
    int number;
    int r = 3;
    int c = 5;

    fp = fopen("testdata2.txt", "r");

    number = (int)malloc(r * c * sizeof(int));

    while (fscanf(fp, "%d", &temp) != EOF){
        for(int i = 0; i < 3;i++){
            for(int j = 0; j < 5; j++){
                temp = number[i][j];
            }
        }   
    }   

    return(0);
}

【问题讨论】:

  • 错误消息所指的“下标值”是numbernumber 的类型为 int,您不能将其作为数组进行测试(在 temp = number[i][j]; 中)。
  • number = (int)malloc(r * c * sizeof(int)); 如果有更具体的例子,用演员表错误地掩盖警告,我们很难找到它。
  • 对于浮点数据,也可以使用floatdouble

标签: c arrays pointers vector


【解决方案1】:
number = (int)malloc(r * c * sizeof(int));

在 C 中,永远不要强制转换 malloc 的结果。如果您省略了对 int 的强制转换,您将在此处得到一个诊断信息,告诉您该数字不是指针类型。

你可以这样做:

int* number = malloc(r * c * sizeof(int));

但这会给你一个大的一维数组。您需要像这样取消引用它:

temp = number[i * c + j];

如果你想要二维索引,就好像你已经这样声明了:

int number[r][c];

你需要分两个阶段进行分配:

int** number = malloc(r * sizeof(int*));
number[0] = malloc(r * c * sizeof(int));
for (int i = 1 ; i < r ; i++)
{
    number[i] = &number[0][i * c];
}

这为每一行设置了一个大整数数组和一个指向整数的中间指针数组。现在你可以做

temp = number[i][j];

编辑

或者你可以按照 Dmitri 所说的去做:

int (*number)[c] = malloc(r * c * sizeof(number[0][0]));

这一次有效地分配了一个由 r 个 c int 块组成的数组。

【讨论】:

  • int number[r][c]; 等效的动态分配不是您所显示的...尝试int (*number)[c] = malloc(r * c * sizeof(number[0][0]));,它将其分配为包含二维数组的单个块,具有与非数组相同的布局-动态版本,不依赖于行指针数组。
  • @Dmitri 非常感谢。
【解决方案2】:

在您的代码中有很多不正确的地方(其中任何一个都可能导致未定义的行为):

  1. 核心数据类型错误。该问题专门要求浮点值,但您使用的是整数类型。
  2. C 中任何内存分配的接收者都应该是一个指针;您使用的是简单的int
  3. 您通过硬转换隐藏了收到的任何警告/错误。 Casting malloc in C isn't necessary, nor advised
  4. 即使其他所有内容都已修复,temp = ... 的赋值语句向后。您希望将刚刚读取的值保存到矩阵中,而不是将其丢弃并用您刚刚分配的内存中的任何未定义值覆盖它。

所有这一切,知道你的数组数组的宽度是五,问题就减少了。注意temp 根本不需要

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

int main()
{
    static const size_t r = 3;
    static const size_t c = 5;

    FILE *fp = NULL;
    double (*number)[c] = NULL; // pointer to array of dimension c.

    fp = fopen("testdata2.txt", "r");
    if (fp == NULL)
    {
        perror("Failed to open file: ");
        return EXIT_FAILURE;
    }

    number = malloc(r * sizeof *number); // allocate r-rows of dimension c
    if (number == NULL)
    {
        perror("Failed to allocate array of arrays: ");
        return EXIT_FAILURE;
    }

    for (size_t i=0; i<r; ++i)
    {
        for (size_t j=0; j<c; ++j)
        {
            if (fscanf(fp, "%lf", number[i]+j) != 1)
            {
                fprintf(stderr, "Failed to parse int at %zu,%zu", i, j);
                return EXIT_FAILURE;
            }
        }
    }

    for (size_t i=0; i<r; ++i)
    {
        for (size_t j=0; j<c; ++j)
            printf("%lf ", number[i][j]);
        fputc('\n', stdout);
    }

    free(number);

    return(0);
}

【讨论】:

    【解决方案3】:

    不是

    (int)malloc(rcsizeof(int))

    是的

    (int*) malloc(rcsizeof(int))

    另一个错误是你不能访问元素

    温度=数字[i][j];

    替换为

    温度=数字[i*r+j]

    希望对你有帮助

    【讨论】:

    • 永远不要在 C 中转换 malloc 的结果。
    • 这是此问题中发布的代码的冰山一角。 number 是错误的类型,temp = ... 分配显然是向后
    【解决方案4】:

    你声明一个整数:

    int number;
    

    并且您正在使用 malloc 分配内存,假设它是一个多维数组,然后尝试以相同的方式访问其元素。 将声明更改为:

    int **number;
    

    【讨论】:

    • 这还不够。你还是不能用number[i][j]
    • 这还不够……他试图将其索引为二维数组或指针数组。 int **number; 将作为指针数组工作,但他必须分配 r 指针数组,然后分配 r 数组 c ints 分配给每个指针。他还可以使用int (*number)[c] = malloc(r * c * sizeof(int));(一旦知道cr)并分配一个真正的二维数组。
    • 然后他要加上: number= (int **)malloc(r * sizeof(int *)); for (i=0; i
    • 或者甚至对所有行使用一个malloc number = (int **)malloc(sizeof(int *) * r);然后对于每个元素 number[0] = (int *)malloc(sizeof(int) * c * r);
    猜你喜欢
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多