C程序使用结构发生了什么?/无法正常工作

时间:2021-05-03 03:41:30

I'm currently working on fixing a piece of code I've been working on for the past few weeks. Pretty much what this is supposed to do is generate a linked list of structs. Currently it generating nothing but I'm still working on the code. I could use any advice on how to implement the insert_ordered correctly. Thanks!

我正在努力修复过去几周我一直在研究的一段代码。这应该做的几乎是生成结构的链接列表。目前它没有产生任何东西,但我仍在研究代码。我可以使用任何关于如何正确实现insert_ordered的建议。谢谢!

#include <stdlib.h> //for malloc and rand
#include <stdio.h>

struct PCB
{
    struct PCB *Next_PCB ;
    int PID ;
} ;

struct PCB *ptr, *tmp ;
void insert_ordered (struct PCB *Head, struct PCB *Add) ;
void print_list(struct PCB *Head) ;

int main()
{
    int num_structs, i;

    ptr = (struct PCB *) malloc (sizeof (struct PCB)) ;
    ptr->Next_PCB = NULL;
    ptr->PID = rand()%20;

    num_structs = 10 + (rand() % 10) ;
    for ( i = 0 ; i < num_structs ; i++)
    {tmp = (struct PCB *) malloc (sizeof(struct PCB)) ;
        tmp->PID = rand() % 20 ;
        tmp->Next_PCB = NULL ;

    insert_ordered(ptr, tmp);
    }
    print_list(ptr) ;
    return EXIT_SUCCESS;
    }



void insert_ordered (struct PCB *Head, struct PCB *Add)
{
    struct PCB* first;
    if ((Head == NULL) || ((Head)->PID >= Add->PID)){
            Add->Next_PCB= Head;
            Head = Add;
        }
    else{
            first = Head;
    }
    while ((first->Next_PCB != NULL) && (first->Next_PCB->PID < Add->PID))
    {
        first = first->Next_PCB;
    }
    Add->Next_PCB = first->Next_PCB;
    first->Next_PCB = Add;
}


void print_list(struct PCB *Head)
{
    tmp=(struct PCB *) malloc(sizeof(struct PCB));
    tmp=Head;

    while (tmp != NULL) 
    {

        printf("%d\n", tmp->PID);
        tmp=tmp->Next_PCB;

    }
    exit(EXIT_SUCCESS);
}

This code will now compile but I'm currently getting no output from the file.

此代码现在将编译,但我目前没有从该文件输出。

2 个解决方案

#1


in short, a struct is (in very brief layman's terms): a collection of data under the same name. More info. Basically, you can store the values for all of your test scores (for example) under

简而言之,结构是(在非常简短的外行人的术语中):同名的数据集合。更多信息。基本上,您可以存储所有测试分数(例如)下的值

struct test_scores {
    int test1;
    int test2;
    int test3;
    ...
}

Where you can set their values under main with

你可以在main下设置它们的值

main() 
{
    struct test_scores Math;
    Math.test1 = 90;
    Math.test2 = 85;
    Math.test3 = 100;
}

(of course, with more code around them!) The * in the line struct PCB *ptr, *tmp, *tcn; indicates a pointer (and yes, I do quite like cprogramming.com! It's where I learned c++)

(当然,周围有更多的代码!)行中的* * PCB * ptr,* tmp,* tcn;指示一个指针(是的,我非常喜欢cprogramming.com!这是我学习c ++的地方)

You do seem to have a handle on that stuff (was reading the comments showing up as I type this). What I think is confusing you, as it confused me for a long time (and admittedly, still does) is this line:

你似乎对这些东西有了处理(正在阅读我输入的评论时出现的评论)。我认为让你困惑的是,因为它困扰了我很长一段时间(而且不可否认,现在仍然如此)是这一行:

struct PCB *Next_PCB;

What this is, is a linked list. A linked list is a setup you can use in c++ that lets you create several structs under a linked list (similar to how you can set several variables in a struct, just one level higher). The *Next_PCB is a pointer that would point to the next struct in the linked list. So, keeping with the test analogy, you could put all of your courses in one linked list. Instead of creating an individual struct for each course, i.e. struct Math { int test1; }; struct Physics { int test1; }; you can simply create one struct struct Courses { int test1; struct Courses *next; }, and then, in the main() function, create the Math struct, and then create the Physics struct to make a linked list. (N.B. Check the source for a good example).

这是一个链表。链接列表是一个可以在c ++中使用的设置,它允许您在链接列表下创建多个结构(类似于如何在结构中设置多个变量,只有一个级别更高)。 * Next_PCB是一个指向链表中下一个结构的指针。因此,按照测试类比,您可以将所有课程放在一个链表中。而不是为每个课程创建单独的结构,即struct Math {int test1; }; struct Physics {int test1; };你可以简单地创建一个struct struct Courses {int test1; struct Courses * next;然后,在main()函数中,创建Math结构,然后创建Physics结构以创建链接列表。 (N.B.检查来源以获得一个好的例子)。


You seem to understand what you're doing, or simply getting lucky with your edits! To all the 'actual' c programmers, I know that I simplified things quite a bit! Am willing to step through more thoroughly than explaining how the structs and linked lists work if you still are having difficulties.

你似乎明白你正在做什么,或者只是对你的编辑感到幸运!对于所有“实际”的c程序员,我知道我简化了一些事情!如果您仍有困难,我愿意更详尽地解释结构和链表如何工作。

Edit: You commented saying it wouldn't compile after/just before I posted this, going to look through the code, try to help. Edit 2.0: And someone beat me to that. Oh well

编辑:您评论说它不会在我发布之后/之前编译,要查看代码,尝试提供帮助。编辑2.0:有人打败了我。那好吧

#2


I went ahead and commented the above code and called out a few deficiencies and a ton of memory leaks.

我继续并评论了上面的代码,并提出了一些缺陷和大量的内存泄漏。

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

struct PCB 
{
  struct PCB *Next_PCB;
  int PID;
};

struct PCB *ptr, *tmp, *tcn;

void insert_ordered(struct PCB *Head, struct PCB *Add);
void print_list(struct PCB *);

int main() 
{
  int num_structs, i;

  // Allocate memory for the PCB structure and setup it's pointers and data
  ptr=(struct PCB *) malloc(sizeof (struct PCB));
  ptr->Next_PCB=NULL;
  ptr->PID=rand() % 20;

  // Let's create between 10 and 19 structures
  num_structs=10 + (rand() % 10);
  for (i=0; i<num_structs; i++)
  {
    tmp = (struct PCB *) malloc(sizeof(struct PCB));
    tmp->PID=rand() % 20;
    tmp->Next_PCB = NULL;

    // Add these structures in order of their PID
    insert_ordered(ptr, tmp); 
  }

  // Print the result to screen
  print_list(ptr);

  return EXIT_SUCCESS;
}

void insert_ordered(struct PCB *Head, struct PCB *Add)
{
  // Create a new structure, even though Add and Head already exist?

  tcn = (struct PCB*) malloc(sizeof(struct PCB));

  // If there is no Head, or if Head's PID is smaller than head's
  // value, make Add the new head.
  if (Head == NULL || Head->PID >= Add->PID)
  {
    Add->Next_PCB=Head;
    Head=Add;
  }
  else 
  {
    // Otherwise leak memory.
    tcn=Head;

    // Step through our list until we hit the end (Next_PCB == NULL)
    // Or the value we're adding is bigger than what is in the list.
    // Confusing as hell to swap from < and >= above on the Head check.
    while (tcn->Next_PCB != NULL && tcn->Next_PCB->PID < Add->PID)
    {
      tcn=tcn->Next_PCB;
    }

    // Point Add's next pointer to our current next pointer 
    // (Hope it isn't NULL because boom...)
    // And point the current list's Next to Add to complete list insertion.
    Add->Next_PCB=tcn->Next_PCB;
    tcn->Next_PCB=Add;
  }
}

void print_list(struct PCB *Head)
{
  // Malloc some memory and leak it just for the hell of it.
  tmp=(struct PCB *) malloc(sizeof(struct PCB));
  tmp=Head;

  // Step through the list and print IDs.
  while (tmp != NULL) 
  {
    printf("%d\n", tmp->PID);
    tmp=tmp->Next_PCB;
  }

  EXIT_SUCCESS;
}

#1


in short, a struct is (in very brief layman's terms): a collection of data under the same name. More info. Basically, you can store the values for all of your test scores (for example) under

简而言之,结构是(在非常简短的外行人的术语中):同名的数据集合。更多信息。基本上,您可以存储所有测试分数(例如)下的值

struct test_scores {
    int test1;
    int test2;
    int test3;
    ...
}

Where you can set their values under main with

你可以在main下设置它们的值

main() 
{
    struct test_scores Math;
    Math.test1 = 90;
    Math.test2 = 85;
    Math.test3 = 100;
}

(of course, with more code around them!) The * in the line struct PCB *ptr, *tmp, *tcn; indicates a pointer (and yes, I do quite like cprogramming.com! It's where I learned c++)

(当然,周围有更多的代码!)行中的* * PCB * ptr,* tmp,* tcn;指示一个指针(是的,我非常喜欢cprogramming.com!这是我学习c ++的地方)

You do seem to have a handle on that stuff (was reading the comments showing up as I type this). What I think is confusing you, as it confused me for a long time (and admittedly, still does) is this line:

你似乎对这些东西有了处理(正在阅读我输入的评论时出现的评论)。我认为让你困惑的是,因为它困扰了我很长一段时间(而且不可否认,现在仍然如此)是这一行:

struct PCB *Next_PCB;

What this is, is a linked list. A linked list is a setup you can use in c++ that lets you create several structs under a linked list (similar to how you can set several variables in a struct, just one level higher). The *Next_PCB is a pointer that would point to the next struct in the linked list. So, keeping with the test analogy, you could put all of your courses in one linked list. Instead of creating an individual struct for each course, i.e. struct Math { int test1; }; struct Physics { int test1; }; you can simply create one struct struct Courses { int test1; struct Courses *next; }, and then, in the main() function, create the Math struct, and then create the Physics struct to make a linked list. (N.B. Check the source for a good example).

这是一个链表。链接列表是一个可以在c ++中使用的设置,它允许您在链接列表下创建多个结构(类似于如何在结构中设置多个变量,只有一个级别更高)。 * Next_PCB是一个指向链表中下一个结构的指针。因此,按照测试类比,您可以将所有课程放在一个链表中。而不是为每个课程创建单独的结构,即struct Math {int test1; }; struct Physics {int test1; };你可以简单地创建一个struct struct Courses {int test1; struct Courses * next;然后,在main()函数中,创建Math结构,然后创建Physics结构以创建链接列表。 (N.B.检查来源以获得一个好的例子)。


You seem to understand what you're doing, or simply getting lucky with your edits! To all the 'actual' c programmers, I know that I simplified things quite a bit! Am willing to step through more thoroughly than explaining how the structs and linked lists work if you still are having difficulties.

你似乎明白你正在做什么,或者只是对你的编辑感到幸运!对于所有“实际”的c程序员,我知道我简化了一些事情!如果您仍有困难,我愿意更详尽地解释结构和链表如何工作。

Edit: You commented saying it wouldn't compile after/just before I posted this, going to look through the code, try to help. Edit 2.0: And someone beat me to that. Oh well

编辑:您评论说它不会在我发布之后/之前编译,要查看代码,尝试提供帮助。编辑2.0:有人打败了我。那好吧

#2


I went ahead and commented the above code and called out a few deficiencies and a ton of memory leaks.

我继续并评论了上面的代码,并提出了一些缺陷和大量的内存泄漏。

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

struct PCB 
{
  struct PCB *Next_PCB;
  int PID;
};

struct PCB *ptr, *tmp, *tcn;

void insert_ordered(struct PCB *Head, struct PCB *Add);
void print_list(struct PCB *);

int main() 
{
  int num_structs, i;

  // Allocate memory for the PCB structure and setup it's pointers and data
  ptr=(struct PCB *) malloc(sizeof (struct PCB));
  ptr->Next_PCB=NULL;
  ptr->PID=rand() % 20;

  // Let's create between 10 and 19 structures
  num_structs=10 + (rand() % 10);
  for (i=0; i<num_structs; i++)
  {
    tmp = (struct PCB *) malloc(sizeof(struct PCB));
    tmp->PID=rand() % 20;
    tmp->Next_PCB = NULL;

    // Add these structures in order of their PID
    insert_ordered(ptr, tmp); 
  }

  // Print the result to screen
  print_list(ptr);

  return EXIT_SUCCESS;
}

void insert_ordered(struct PCB *Head, struct PCB *Add)
{
  // Create a new structure, even though Add and Head already exist?

  tcn = (struct PCB*) malloc(sizeof(struct PCB));

  // If there is no Head, or if Head's PID is smaller than head's
  // value, make Add the new head.
  if (Head == NULL || Head->PID >= Add->PID)
  {
    Add->Next_PCB=Head;
    Head=Add;
  }
  else 
  {
    // Otherwise leak memory.
    tcn=Head;

    // Step through our list until we hit the end (Next_PCB == NULL)
    // Or the value we're adding is bigger than what is in the list.
    // Confusing as hell to swap from < and >= above on the Head check.
    while (tcn->Next_PCB != NULL && tcn->Next_PCB->PID < Add->PID)
    {
      tcn=tcn->Next_PCB;
    }

    // Point Add's next pointer to our current next pointer 
    // (Hope it isn't NULL because boom...)
    // And point the current list's Next to Add to complete list insertion.
    Add->Next_PCB=tcn->Next_PCB;
    tcn->Next_PCB=Add;
  }
}

void print_list(struct PCB *Head)
{
  // Malloc some memory and leak it just for the hell of it.
  tmp=(struct PCB *) malloc(sizeof(struct PCB));
  tmp=Head;

  // Step through the list and print IDs.
  while (tmp != NULL) 
  {
    printf("%d\n", tmp->PID);
    tmp=tmp->Next_PCB;
  }

  EXIT_SUCCESS;
}