如何在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.
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 pricedefines a basic structure to store currency values (dollars and cents).- The
typedefgives this structure a shorthand alias:Price. Instead of writingstruct price my_price;, you can now writePrice 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
Pricetype), and inventory count. - Again,
typedeflets us useStockinstead ofstruct stockwhen declaring variables or pointers (likeStock *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
Stockitem (data) and a pointer to the next node in the list (next). - Notice we use
struct node *nexthere instead ofNode *next—that's because thetypedefaliasNodeisn't fully defined yet when we're writing thestruct nodeitself. Once thetypedefis done, we can useNodefor 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.
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

