【问题标题】:C - dynamic arrays of structuresC - 结构的动态数组
【发布时间】:2017-03-13 00:30:18
【问题描述】:

我有一段相当大的代码有问题。了解我自己,这是一种愚蠢的错误,或者更有可能是缺乏对指针的理解。我真的需要一些帮助,所以如果有人可以看看它,我将非常感激!我现在就解释一下。

这是我的编程课上的一个程序。老师给了我们一个txt文件中的一个数字(N)和一个字母(X),要我们创建一个结构体,包含三个字段(int、char和float),然后是四个函数:

函数 #1 将数字 N 作为参数,并为指向 N 个结构的指针数组动态分配内存。然后它将值分配给结构中的字段 - int 和 char 设置为随机值,float 字段设置为结构的编号。该函数返回数组的地址。

函数 #2 将创建的数组的大小(其中的指针数量)和指向数组的指针作为参数并删除数组,释放内存。

函数 #3 将创建的数组的大小和指向数组的指针作为参数,然后使用冒泡排序根据 int 字段对结构进行排序

函数 #4 搜索结构并计算字母 (X) 在结构的字符字段中重复的次数。

这是带有 cmets 和错误的代码。请,有人可以解释我做错了什么吗?老实说,我几乎没时间了,但我愿意熬夜来了解和解决这个问题。

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

 struct Foo {
 int fieldint;
 char fieldchar;
 float fieldfloat;
 };

 Foo *initialize(int N);
 int sort(int N, Foo *tablica);
 int count(int N, Foo *tablica, char*X);
 int deleting(int N, Foo **tablica);

 int main () {

      //this reads the number N and the letter to find from the .txt file:
      FILE *file = fopen("inlab01.txt", "r");
      int number;
      char letter[1];
      if (file == NULL) {
           printf("Error opening file");
           exit(-1);
      } 
      while (fscanf(file, "%d%s", &number, letter) != EOF);
      fclose(file);

      //creating the array
      //again, it's supposed to be an array of pointers to N structures:
      Foo *arr[number]; 
      *arr = initialize(number);

      //sorting:
      sort(number, *arr); //the program crashes at this function

      //counting how many times the given letter appears:
      //count(number, *arr, letter);

      //we're supposed to print the first 20 of the structures
      //this loop prints one structure and then the program crashes
      for(int i=0;i<20;i++) {
          printf("Structure %d:\nfield int:%d\nfield char:%c\nfield float:\f\n\n", i+1, arr[i]->fieldint, arr[i]->fieldchar, arr[i]->fieldfloat);
      }

      //deleting:
      deleting(number, arr);

      getch();
      return 0;
}

Foo *initialize(int N) { 
     Foo **array;
     array = (Foo **)malloc(sizeof(Foo) * N);
     srand( time( NULL ) );    

     for(int i=0; i<N; i++) {
          array[i] = (Foo*)malloc(sizeof(Foo));           
          array[i] -> fieldint = rand();  //random number
          array[i] -> fieldchar = ( char )( rand() % 24 ) + 65; //random letter
          array[i] -> fieldfloat=i;     
     }

     return *array; 
}

 int sort(int N, Foo *array) {  
     int temp;
     for (int i=0;i<N;i++){
         for (int j=N-1;j>=j;j--) {
             if(array[j].fieldint < array[j-1].fieldint) {
                 temp = array[j-1].fieldint;
                 array[j-1].fieldint = array[j].fieldint;
                 array[j].fieldint = temp;
             }
         }
     }
     return 0;
 }

 int count(int N, Foo *array, char*X){ 
     int counter = 0;
     for(int i=0;i<N;i++) {
         if (array[i].fieldchar == 'X') {
             counter = counter+1;
         }
     }
     return counter;
 }

 int deleting(int N, Foo **array) {
     for (int i=0;i<N;i++) {
         free(array[i]);
     }  
     free(array);
     return 0;
 }

整个事情都编译好了,但是程序崩溃了,而不是做任何事情,真的。

请帮忙。

【问题讨论】:

  • 请发布一个最小、完整和可验证的示例,以展示您面临的错误。您现在的问题是 TL;DR 材料,大多数人不会打扰。
  • 你的代码没有编译,比如*arr = initialize是错误的,arr[i]-&gt;fieldint是错误的,你应该修复这些。
  • 顺便说一句,您似乎正在用 C++ 编译 C 代码,可能您正在使用 *.cpp 扩展名。
  • @BarmakShemirani 为什么会出错?我尝试做 *arr = initialize 以便能够在其他函数中使用创建的数组。我应该怎么做呢?非常感谢您的回答,尽管代码非常长!谢谢!
  • 我更改为 .c 扩展名,现在我正在使用“struct Foo”。如果我更改为 arr=initialize,我会收到一条错误消息,提示“将 'Foo' 分配给 'Foo [number]' 的类型不兼容”。如果我将 -> 更改为点,我会得到“在 '(array + ((sizetype)(((long long unsigned int)i) * 8ull)))'中对成员 'fieldint' 的请求,即指针类型 'Foo' (也许你打算使用 '->' ?)”。我正在使用 DevC++ ......是的,我知道。我只是没有时间开始适应其他事情。

标签: c arrays pointers dynamic structure


【解决方案1】:
struct Foo 
{
    int fieldint;
    char fieldchar;
    float fieldfloat;
};

Foo **array;
array = (Foo **)malloc(sizeof(Foo) * N);

您正在用 C++ 编译此代码。你想用一个C编译器,你得把代码改成下面这样:

struct Foo **array;

你会在任何地方使用struct Foo,你不需要那个演员表。或者用typedef声明结构

其次,Foo **array 用于分配二维数组。您分配二维数组的方式是错误的。另外,你只需要一个一维数组Foo arr[number]

for (int j=N-1;j>=j;j--)

请注意,您的排序函数中有错误(j &gt;= j) 始终为真。修复排序功能,避免分配二维数组就完成了。

int sort(int N, struct Foo *array)
{
    int temp, i, j;
    for (i = 0; i< N; i++) {
        for (j = i + 1; j < N; j++) {
            if (array[i].fieldint > array[j].fieldint) {
                temp = array[i].fieldint;
                array[i].fieldint = array[j].fieldint;
                array[j].fieldint = temp;
            }
        }
    }
    return 0;
}

int main()
{
    srand((unsigned)time(NULL));
    int number = 3;
    struct Foo arr[number];
    int i;
    for (i = 0; i < number; i++) {
        arr[i].fieldint = rand(); //random number
        arr[i].fieldchar = 'A' + (char)(rand() % 26); //random letter
        arr[i].fieldfloat = (float)i;
    }

    sort(number, arr);
    for (i = 0; i < number; i++)
        printf("Structure %d:\nfield int:%d\nfield char:%c\nfield float:%f\n\n",
            i + 1, arr[i].fieldint, arr[i].fieldchar, arr[i].fieldfloat);
    getch();
    return 0;
}

请注意,您的排序函数交换了fieldintFoo 有其他成员,如果您的目标是交换对象,您可能希望交换所有成员。

【讨论】:

  • 哦,我才注意到这一点!我现在会经历这一切,非常感谢你,你是一个祝福!
猜你喜欢
  • 1970-01-01
  • 2020-04-14
  • 2012-10-11
  • 2013-11-08
  • 1970-01-01
  • 1970-01-01
  • 2015-06-09
  • 2017-09-20
  • 1970-01-01
相关资源
最近更新 更多