You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在C语言中从含自定义类型的节点链表读写数据?

Hey there! Let's tackle your questions step by step—first clearing up that typedef confusion, then walking through how to perform read/write operations on this linked list structure.

Understanding the typedef Statements

Let's break down each typedef one by one to demystify what they do:

1. Price Type

typedef struct price { unsigned dollars; unsigned cents; } Price;
  • struct price defines a basic structure to store currency values (dollars and cents).
  • The typedef gives this structure a shorthand alias: Price. Instead of writing struct price my_price;, you can now write Price my_price; to create a variable of this type.

2. Stock Type

typedef struct stock { 
    char id[ID_LEN + NULL_SPACE]; 
    char name[NAME_LEN + NULL_SPACE]; 
    char desc[DESC_LEN + NULL_SPACE]; 
    Price price; 
    unsigned onHand; 
} Stock;
  • This defines a structure for a full stock item: it includes an ID, name, description, price (using our Price type), and inventory count.
  • Again, typedef lets us use Stock instead of struct stock when declaring variables or pointers (like Stock *item_data;).

3. Node Type

typedef struct node { 
    Stock *data; 
    struct node *next; 
} Node;
  • This is the linked list node structure. It holds a pointer to a Stock item (data) and a pointer to the next node in the list (next).
  • Notice we use struct node *next here instead of Node *next—that's because the typedef alias Node isn't fully defined yet when we're writing the struct node itself. Once the typedef is done, we can use Node for future declarations.

4. List Type

typedef struct list { 
    Node *head; 
    unsigned size; 
} List;
  • This is the "wrapper" for our linked list. It stores a pointer to the first node (head) and the total number of nodes in the list (size). This makes it easier to manage the entire list without having to track the head and size separately.
Linked List Read/Write Operations

Now let's cover core operations to interact with this list—creating it, adding items, reading data, modifying entries, and cleaning up.

1. Initialize an Empty List

First, create an empty list structure to work with:

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

// Assume these constants are defined somewhere:
#define ID_LEN 10
#define NAME_LEN 20
#define DESC_LEN 50
#define NULL_SPACE 1

List* create_list() {
    List *new_list = malloc(sizeof(List));
    if (new_list == NULL) {
        perror("Failed to allocate memory for list");
        return NULL;
    }
    new_list->head = NULL;
    new_list->size = 0;
    return new_list;
}

2. Create a New Stock Node (Write Data)

This function creates a new node with your stock item data:

Node* create_stock_node(const char *id, const char *name, const char *desc, 
                       unsigned dollars, unsigned cents, unsigned onHand) {
    // Allocate memory for the node
    Node *new_node = malloc(sizeof(Node));
    if (new_node == NULL) {
        perror("Failed to allocate node");
        return NULL;
    }
    // Allocate memory for the Stock data
    new_node->data = malloc(sizeof(Stock));
    if (new_node->data == NULL) {
        free(new_node); // Clean up if allocation fails
        perror("Failed to allocate Stock data");
        return NULL;
    }
    // Copy string data safely (avoid buffer overflow)
    strncpy(new_node->data->id, id, ID_LEN);
    new_node->data->id[ID_LEN] = '\0'; // Ensure null termination
    strncpy(new_node->data->name, name, NAME_LEN);
    new_node->data->name[NAME_LEN] = '\0';
    strncpy(new_node->data->desc, desc, DESC_LEN);
    new_node->data->desc[DESC_LEN] = '\0';
    // Set price and inventory
    new_node->data->price.dollars = dollars;
    new_node->data->price.cents = cents;
    new_node->data->onHand = onHand;
    // Next pointer starts as NULL (end of list)
    new_node->next = NULL;
    return new_node;
}

3. Add Node to the List (Write to List)

Add the new node to the end of the list:

int add_node_to_list(List *list, Node *new_node) {
    if (list == NULL || new_node == NULL) {
        fprintf(stderr, "Error: Invalid list or node\n");
        return -1;
    }
    if (list->head == NULL) {
        // List is empty: new node becomes the head
        list->head = new_node;
    } else {
        // Traverse to the last node
        Node *current = list->head;
        while (current->next != NULL) {
            current = current->next;
        }
        current->next = new_node;
    }
    list->size++;
    return 0; // Success
}

4. Read/Traverse the List

Print all items in the list to read their data:

void print_list(const List *list) {
    if (list == NULL || list->head == NULL) {
        printf("List is empty\n");
        return;
    }
    Node *current = list->head;
    unsigned item_num = 1;
    while (current != NULL) {
        printf("=== Item #%u ===\n", item_num);
        printf("ID: %s\n", current->data->id);
        printf("Name: %s\n", current->data->name);
        printf("Description: %s\n", current->data->desc);
        printf("Price: $%u.%02u\n", current->data->price.dollars, current->data->price.cents);
        printf("Stock on hand: %u\n\n", current->data->onHand);
        current = current->next;
        item_num++;
    }
}

5. Modify Existing Node Data (Update Write)

Find a node by ID and update its data:

int modify_stock_by_id(List *list, const char *target_id, 
                       const char *new_name, unsigned new_onHand) {
    if (list == NULL || target_id == NULL) {
        return -1;
    }
    Node *current = list->head;
    while (current != NULL) {
        if (strcmp(current->data->id, target_id) == 0) {
            // Update name safely
            strncpy(current->data->name, new_name, NAME_LEN);
            current->data->name[NAME_LEN] = '\0';
            // Update inventory count
            current->data->onHand = new_onHand;
            return 0; // Success: item found and updated
        }
        current = current->next;
    }
    fprintf(stderr, "Error: Item with ID '%s' not found\n", target_id);
    return -1; // Item not found
}

6. Clean Up Memory (Avoid Leaks)

Always free allocated memory when you're done with the list:

void free_list(List *list) {
    if (list == NULL) return;
    Node *current = list->head;
    while (current != NULL) {
        Node *next_node = current->next;
        // Free the Stock data first
        free(current->data);
        // Free the node itself
        free(current);
        current = next_node;
    }
    // Free the list wrapper
    free(list);
}

Quick Usage Example

Here's how you'd put it all together:

int main() {
    List *inventory = create_list();
    if (inventory == NULL) return 1;
    // Create a new stock item
    Node *apple = create_stock_node("APL001", "Apple", "Fresh red apple", 1, 99, 50);
    if (apple != NULL) {
        add_node_to_list(inventory, apple);
    }
    // Read the list
    print_list(inventory);
    // Modify the item
    modify_stock_by_id(inventory, "APL001", "Organic Apple", 75);
    print_list(inventory);
    // Clean up
    free_list(inventory);
    return 0;
}

内容的提问来源于stack exchange,提问作者Rajesh Kummar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:53:19