链表输出

Linked List output

我正在做一项学校作业,几个月前我才开始学习 C 编程。在这个作业中,我要输出 space 被 'file'.

占用

初始输出是正确的,但是,当我尝试打印出 table 时,输出变得不正确。

代码:

#define TOTAL_DISK_BLOCKS 32
#define TOTAL_DISK_INODES 8
int blockStatus[TOTAL_DISK_BLOCKS];                   // free = 0
int blockList[TOTAL_DISK_BLOCKS - TOTAL_DISK_INODES]; // list of blocks of a file
struct file_table
{
    char fileName[20];
    int fileSize;
    struct block *sb; // start block
};
struct file_table fileTable[TOTAL_DISK_BLOCKS - TOTAL_DISK_INODES];

struct block
{
    int blockNumber;
    struct block *next;
} * head;
int AllocateBlocks(int Size)
{
    int i = 0, count = 0, inList = 0, nextBlock = 0, j = 0, dcount = 0, fails = 0;
    int allocStartBlock = TOTAL_DISK_INODES;
    int allocEndBlock = TOTAL_DISK_BLOCKS - 1;
    // check whether sufficient free blocks are available
    // some codes here     
    {

        for (j = 0; j < Size; j++)
        {
            nextBlock = (rand() % (allocEndBlock - allocStartBlock + 1)) + allocStartBlock;

            if (blockStatus[nextBlock] == 0)
            {
                // printf("\ncount:%d\n", count);
                blockList[j] = nextBlock;
                count += 1;
            }
            else
            {
                count = 0;
                fails += 1;
                // printf("\nfails:%d, block %d taken\n", fails, nextBlock);
                break;
            }
        }
    }
    // remaining blocks left
    dcount = 0;
    for (i = 0; i < (TOTAL_DISK_BLOCKS - TOTAL_DISK_INODES); i++)
        if (blockStatus[i] == 0)
            dcount++;
    printf("Remaining blocks: %d\n", dcount);
    if (count == Size)
    {
        for (j = 0; j < Size; j++)
        {
            blockStatus[blockList[j]] = 1;
        }
        return 0; // success
    }

    else
        return 1; // not successful
}

void printBlockNumbers(struct block *temp)
{

    // Return if list is empty
    if (head == NULL)
    {
        printf("List is empty.");
        return;
    }

    temp = head;
    while (temp != NULL)
    {
        printf("-%d", temp->blockNumber); // Print data of current node
        temp = temp->next;                // Move to next node
    }
}

void main()
{
    int i = 0, j = 0, numFiles = 0, nextBlock = 0, ret = 1;
    char s[20];
    struct block *temp, *newBlock;

    //some print codes here...

    scanf("%d", &numFiles);

    for (i = 0; i < numFiles; i++)
    {
        printf("\nEnter the name of file #%d: ", i + 1);
        scanf("%s", fileTable[i].fileName);
        printf("Enter the size (kB) of file #%d: ", i + 1);
        scanf("%d", &fileTable[i].fileSize);
        ret = AllocateBlocks(fileTable[i].fileSize);
        if (ret == 0)
        {
            head = (struct block *)malloc(sizeof(struct block));
            head->blockNumber = blockList[0];
            head->next = NULL;
            temp = head;

            for (j = 1; j < fileTable[i].fileSize; j++)
            {
                newBlock = (struct block *)malloc(sizeof(struct block));

                newBlock->blockNumber = blockList[j]; // Link data field of newNode
                newBlock->next = NULL;                // Make sure new node points to NULL

                temp->next = newBlock; // Link previous node with newNode
                temp = temp->next;     // Make current node as previous node
            }
            printf("Blocks occupied");
            printBlockNumbers(fileTable[i].sb);
            printf("\nFile allocation success\n");
        }
        else
        {
            printf("\nFile allocation failed\n");
        }
    }
    // Seed the pseudo-random number generator used by rand() with the value seed

    srand(1234);
    printf("\nFile Allocation Table\n");
    printf("%s%20s%40s\n", "FILE_NAME", "FILE_SIZE", "BLOCKS_OCCUPIED");

    for (i = 0; i < numFiles; i++)
    {

        printf("%s%20d", fileTable[i].fileName, fileTable[i].fileSize);
        printf("\t\t\t\t");
        printBlockNumbers(fileTable[i].sb);

        printf("\n");
    }

    printf("File allocation completed. Exiting.\n");
}

下面是第一个输出。

Blocks occupied-15-30-17

Blocks occupied-21-10-27-10

Blocks occupied-20-26-12-24-19

这是 table 输出。

File Allocation Table
FILE_NAME           FILE_SIZE                         BLOCKS_OCCUPIED
3                   3                           -20-26-12-24-19
4                   4                           -20-26-12-24-19
5                   5                           -20-26-12-24-19
File allocation completed. Exiting.

在第一个循环中,您每次都打印新分配的列表,但在第二个循环中,您打印最后分配的列表,因为您从列表中打印尾部是全局变量head

在这里:

void printBlockNumbers(struct block *temp)
{

    // Return if list is empty
    if (head == NULL)
    {
        printf("List is empty.");
        return;
    }

    temp = head;

temp 的初始值无关紧要。

此处:

head = (struct block *)malloc(sizeof(struct block));
head->blockNumber = blockList[0];
head->next = NULL;
temp = head;

您正在分配 temphead,因此 temp->smth 指向与 head->smth 相同的地址,因此当您使用 printBlockNumbers 打印时head 它将打印出在此循环中分配给它的内容。

您应该将 printBlockNumbers 更改为:

void printBlockNumbers(struct block *temp)
{
   // Return if list is empty
   if(!temp) {
      return;
   }
   
   while (temp != NULL)
   {
       printf("-%d", temp->blockNumber); // Print data of current node
       temp = temp->next;                // Move to next node
   }

并在每个循环中分配 fileTable[i].sbhead,然后在最后释放这些列表。

仅供参考: 如果你想传递一些东西作为“引用”(即指针)来改变这个函数中的原始值,你可以这样做:

void changeIntToFive(int* a) {
   *a = 5;
}

int main(){
   int var = 1;
   changeIntToFive(&var);
   printf("%d\n", var);    // prints 5
}

如果你想对指针做同样的事情:

int glob = 5;

void makePtrPointToGlob(int** a) {
   *a = &glob;
}

int main(){
   int *ptr;
   makePtrPointToGlob(&ptr);
   printf("%d\n", *ptr);    // prints 5
}