c语言中链表如何外部声明
时间: 2024-08-16 12:05:46 浏览: 55
在C语言中,如果你想要在函数或文件之间声明一个链表,你可以使用结构体声明并加上 extern 关键字。这样做的目的是让其他函数能够引用这个链表,而不需要直接定义它。以下是基本的步骤:
1. **头文件声明**:
在包含链表相关的数据结构的头文件 (`.h` 文件) 中,声明链表节点的结构体,并使用 extern 关键字:
```c
// 链表.h
typedef struct Node {
int data;
struct Node* next;
} ListNode;
extern ListNode* head; // 外部声明链表头部指针
```
这里的 `ListNode` 是链表节点的结构体,`head` 是指向链表头部的指针。
2. **单个源文件定义**:
在某个源文件 (.c 文件) 中,初始化链表变量或者提供其实际定义:
```c
// 链表.c
#include "链表.h" // 包含头文件
ListNode* head = NULL; // 初始化为NULL 或者创建一个初始节点
```
3. **使用链表**:
其他需要使用链表的文件可以在包含头文件后直接使用 `head` 指针,无需再次声明。
注意,这种方式适用于全局变量或静态局部变量的共享。如果链表是动态分配的,通常在链接阶段完成初始化。
相关问题
用C语言写一个有头单向链表存放员工(name age gender),可以实现外部增删查改。
以下是使用C语言实现有头单向链表存放员工信息的代码:
```c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 定义员工结构体
typedef struct Employee {
char name[20];
int age;
char gender[10];
struct Employee *next;
} Employee;
// 全局变量,指向头结点
Employee *head = NULL;
// 函数声明
void addEmployee();
void deleteEmployee();
void modifyEmployee();
void searchEmployee();
void printAllEmployees();
int main() {
int choice;
do {
printf("\n1. Add employee\n");
printf("2. Delete employee\n");
printf("3. Modify employee\n");
printf("4. Search employee\n");
printf("5. Print all employees\n");
printf("6. Exit\n");
printf("Enter your choice: ");
scanf("%d", &choice);
switch (choice) {
case 1:
addEmployee();
break;
case 2:
deleteEmployee();
break;
case 3:
modifyEmployee();
break;
case 4:
searchEmployee();
break;
case 5:
printAllEmployees();
break;
case 6:
printf("Exiting program...\n");
break;
default:
printf("Invalid choice. Try again.\n");
}
} while (choice != 6);
return 0;
}
void addEmployee() {
Employee *newEmployee = (Employee *) malloc(sizeof(Employee));
printf("Enter employee name: ");
scanf("%s", newEmployee->name);
printf("Enter employee age: ");
scanf("%d", &newEmployee->age);
printf("Enter employee gender: ");
scanf("%s", newEmployee->gender);
newEmployee->next = NULL;
if (head == NULL) { // 链表为空,新节点为第一个节点
head = newEmployee;
} else { // 链表不为空,将新节点插入到链表头部
newEmployee->next = head;
head = newEmployee;
}
printf("Employee added successfully.\n");
}
void deleteEmployee() {
if (head == NULL) { // 链表为空
printf("No employees to delete.\n");
return;
}
char name[20];
printf("Enter the name of the employee to delete: ");
scanf("%s", name);
Employee *currentEmployee = head;
Employee *previousEmployee = NULL;
int found = 0;
while (currentEmployee != NULL) {
if (strcmp(currentEmployee->name, name) == 0) { // 找到要删除的节点
found = 1;
break;
}
previousEmployee = currentEmployee;
currentEmployee = currentEmployee->next;
}
if (!found) { // 没有找到要删除的节点
printf("Employee not found.\n");
} else {
if (previousEmployee != NULL) { // 要删除的节点不是头结点
previousEmployee->next = currentEmployee->next;
} else { // 要删除的节点是头结点
head = currentEmployee->next;
}
free(currentEmployee);
printf("Employee deleted successfully.\n");
}
}
void modifyEmployee() {
if (head == NULL) { // 链表为空
printf("No employees to modify.\n");
return;
}
char name[20];
printf("Enter the name of the employee to modify: ");
scanf("%s", name);
Employee *currentEmployee = head;
int found = 0;
while (currentEmployee != NULL) {
if (strcmp(currentEmployee->name, name) == 0) { // 找到要修改的节点
found = 1;
break;
}
currentEmployee = currentEmployee->next;
}
if (!found) { // 没有找到要修改的节点
printf("Employee not found.\n");
} else {
printf("Enter new age: ");
scanf("%d", ¤tEmployee->age);
printf("Enter new gender: ");
scanf("%s", currentEmployee->gender);
printf("Employee modified successfully.\n");
}
}
void searchEmployee() {
if (head == NULL) { // 链表为空
printf("No employees to search.\n");
return;
}
char name[20];
printf("Enter the name of the employee to search: ");
scanf("%s", name);
Employee *currentEmployee = head;
int found = 0;
while (currentEmployee != NULL) {
if (strcmp(currentEmployee->name, name) == 0) { // 找到要查找的节点
found = 1;
break;
}
currentEmployee = currentEmployee->next;
}
if (!found) { // 没有找到要查找的节点
printf("Employee not found.\n");
} else {
printf("Name: %s\n", currentEmployee->name);
printf("Age: %d\n", currentEmployee->age);
printf("Gender: %s\n", currentEmployee->gender);
}
}
void printAllEmployees() {
if (head == NULL) { // 链表为空
printf("No employees to print.\n");
return;
}
Employee *currentEmployee = head;
while (currentEmployee != NULL) {
printf("Name: %s\n", currentEmployee->name);
printf("Age: %d\n", currentEmployee->age);
printf("Gender: %s\n", currentEmployee->gender);
printf("\n");
currentEmployee = currentEmployee->next;
}
}
```
在该程序中,我们定义了一个员工结构体,包含员工的姓名、年龄和性别,并且还有一个指向下一个节点的指针。我们使用全局变量 `head` 来指向链表的头结点。
程序提供了以下操作:
- 添加员工信息
- 删除员工信息
- 修改员工信息
- 查找员工信息
- 打印所有员工信息
在添加员工信息时,我们先创建一个新的节点,然后从用户获取员工信息,并将新节点插入到链表头部。在删除员工信息时,我们先从用户获取要删除的员工姓名,然后遍历链表,找到对应的节点并删除。在修改员工信息时,我们要先从用户获取要修改的员工姓名,然后遍历链表,找到对应的节点并修改。在查找员工信息时,我们要先从用户获取要查找的员工姓名,然后遍历链表,找到对应的节点并输出。最后,在打印所有员工信息时,我们只需遍历链表并输出每个节点的信息即可。
我们可以根据需要对该程序进行修改,例如增加员工编号等信息。
C语言:基本数据结构(堆栈、队列)的数组、链表实现; 一、 实验目的: 1. 学习基本数据结构(堆栈、队列的实现) 2. 要求:分别通过数组、链表的形式对上述两个数据结构进行实现; 3. 注意: • 学习如何实现多文件C程序的编译和运行; • 学习使用头文件实现函数信息(接口)的声明; • 学习掌握全局变量、外部变量的声明和使用; • 学习使用make命令对多文件的工程进行管理(编译,链接),配合Makefile文件; 二、 实验提示: a) 可以对堆栈(队列)存储数组(队列)定义为全局变量; b) 实现堆栈LIFO操作方法,push(),pop() c) 实现队列的FIFO操作方法,put(),get() d) 将上述函数保存在不同的文件中; e) 主函数中可以添加相应的测试代码;
以下是一份示例代码,包含了堆栈和队列的数组、链表实现。代码分为头文件和源文件,使用 make 命令进行编译和链接。
stack.h:
```
#ifndef STACK_H
#define STACK_H
#define MAX_STACK_SIZE 100
void stack_array_push(int element);
int stack_array_pop();
void stack_list_push(int element);
int stack_list_pop();
#endif
```
stack_array.c:
```
#include "stack.h"
int stack_array[MAX_STACK_SIZE];
int top = 0;
void stack_array_push(int element) {
if (top == MAX_STACK_SIZE) {
printf("Stack overflow!\n");
return;
}
stack_array[top++] = element;
}
int stack_array_pop() {
if (top == 0) {
printf("Stack underflow!\n");
return -1;
}
return stack_array[--top];
}
```
stack_list.c:
```
#include "stack.h"
#include <stdlib.h>
typedef struct stack_node {
int element;
struct stack_node* next;
} StackNode;
StackNode* top = NULL;
void stack_list_push(int element) {
StackNode* new_node = (StackNode*)malloc(sizeof(StackNode));
new_node->element = element;
new_node->next = top;
top = new_node;
}
int stack_list_pop() {
if (top == NULL) {
printf("Stack underflow!\n");
return -1;
}
int element = top->element;
StackNode* old_top = top;
top = top->next;
free(old_top);
return element;
}
```
queue.h:
```
#ifndef QUEUE_H
#define QUEUE_H
#define MAX_QUEUE_SIZE 100
void queue_array_put(int element);
int queue_array_get();
void queue_list_put(int element);
int queue_list_get();
#endif
```
queue_array.c:
```
#include "queue.h"
int queue_array[MAX_QUEUE_SIZE];
int front = 0;
int rear = 0;
void queue_array_put(int element) {
if (rear == MAX_QUEUE_SIZE) {
printf("Queue overflow!\n");
return;
}
queue_array[rear++] = element;
}
int queue_array_get() {
if (front == rear) {
printf("Queue underflow!\n");
return -1;
}
return queue_array[front++];
}
```
queue_list.c:
```
#include "queue.h"
#include <stdlib.h>
typedef struct queue_node {
int element;
struct queue_node* next;
} QueueNode;
QueueNode* front = NULL;
QueueNode* rear = NULL;
void queue_list_put(int element) {
QueueNode* new_node = (QueueNode*)malloc(sizeof(QueueNode));
new_node->element = element;
new_node->next = NULL;
if (rear == NULL) {
front = rear = new_node;
} else {
rear->next = new_node;
rear = new_node;
}
}
int queue_list_get() {
if (front == NULL) {
printf("Queue underflow!\n");
return -1;
}
int element = front->element;
QueueNode* old_front = front;
front = front->next;
if (front == NULL) {
rear = NULL;
}
free(old_front);
return element;
}
```
main.c:
```
#include <stdio.h>
#include "stack.h"
#include "queue.h"
int main() {
// Stack array implementation
printf("Stack array implementation:\n");
stack_array_push(1);
stack_array_push(2);
stack_array_push(3);
printf("%d\n", stack_array_pop());
printf("%d\n", stack_array_pop());
printf("%d\n", stack_array_pop());
printf("%d\n", stack_array_pop()); // should print "Stack underflow!"
// Stack list implementation
printf("Stack list implementation:\n");
stack_list_push(1);
stack_list_push(2);
stack_list_push(3);
printf("%d\n", stack_list_pop());
printf("%d\n", stack_list_pop());
printf("%d\n", stack_list_pop());
printf("%d\n", stack_list_pop()); // should print "Stack underflow!"
// Queue array implementation
printf("Queue array implementation:\n");
queue_array_put(1);
queue_array_put(2);
queue_array_put(3);
printf("%d\n", queue_array_get());
printf("%d\n", queue_array_get());
printf("%d\n", queue_array_get());
printf("%d\n", queue_array_get()); // should print "Queue underflow!"
// Queue list implementation
printf("Queue list implementation:\n");
queue_list_put(1);
queue_list_put(2);
queue_list_put(3);
printf("%d\n", queue_list_get());
printf("%d\n", queue_list_get());
printf("%d\n", queue_list_get());
printf("%d\n", queue_list_get()); // should print "Queue underflow!"
return 0;
}
```
Makefile:
```
CC = gcc
CFLAGS = -Wall -Wextra -Wpedantic -std=c99
all: main
main: main.o stack_array.o stack_list.o queue_array.o queue_list.o
$(CC) $(CFLAGS) -o $@ $^
main.o: main.c stack.h queue.h
$(CC) $(CFLAGS) -c $<
stack_array.o: stack_array.c stack.h
$(CC) $(CFLAGS) -c $<
stack_list.o: stack_list.c stack.h
$(CC) $(CFLAGS) -c $<
queue_array.o: queue_array.c queue.h
$(CC) $(CFLAGS) -c $<
queue_list.o: queue_list.c queue.h
$(CC) $(CFLAGS) -c $<
clean:
rm -f main *.o
```
阅读全文