网站建设高级教程,哪些网站做宾馆推广好,网页设计工资一般多少,公众号投票结构体指针 介绍定义结构体指针初始化结构体指针指向现有结构体变量动态分配内存 访问结构体成员使用结构体指针访问成员通过指针和解引用 结构体指针作为函数参数使用结构体指针构建链表 高级用法多级指针#xff08;指向指针的指针#xff09;动态二维数组结构体指针与链表… 结构体指针 介绍定义结构体指针初始化结构体指针指向现有结构体变量动态分配内存 访问结构体成员使用结构体指针访问成员通过指针和解引用 结构体指针作为函数参数使用结构体指针构建链表 高级用法多级指针指向指针的指针动态二维数组结构体指针与链表操作插入节点删除节点 高级链表操作链表反转链表合并 深拷贝结构体 介绍
在C语言中结构体指针是一种非常有用的工具它允许我们通过指针来操作结构体尤其是在处理动态内存分配或函数参数传递时。以下是关于C语言结构体指针的详细讲解。
定义结构体指针
首先我们需要定义一个结构体。例如定义一个表示学生信息的结构体
#include stdio.hstruct Student {char name[50];int age;float gpa;
};然后我们可以定义一个指向该结构体的指针
struct Student *studentPtr;初始化结构体指针
指向现有结构体变量
我们可以让结构体指针指向一个已有的结构体变量
struct Student student1 {Alice, 20, 3.5};
struct Student *studentPtr student1;动态分配内存
我们也可以使用动态内存分配来初始化结构体指针
struct Student *studentPtr (struct Student *)malloc(sizeof(struct Student));
if (studentPtr NULL) {printf(Memory allocation failed\n);return 1;
}访问结构体成员
使用结构体指针访问成员
当我们有一个结构体指针时可以使用箭头操作符 - 来访问结构体成员
studentPtr-age 21;
printf(Name: %s, Age: %d, GPA: %.2f\n, studentPtr-name, studentPtr-age, studentPtr-gpa);通过指针和解引用
我们也可以使用指针和解引用操作符 * 组合来访问结构体成员
(*studentPtr).age 22;
printf(Name: %s, Age: %d, GPA: %.2f\n, (*studentPtr).name, (*studentPtr).age, (*studentPtr).gpa);不过使用箭头操作符 - 更加简洁和常见。
结构体指针作为函数参数
将结构体指针作为函数参数可以高效地传递结构体数据避免大结构体的拷贝。以下是一个示例
void printStudent(struct Student *student) {printf(Name: %s, Age: %d, GPA: %.2f\n, student-name, student-age, student-gpa);
}int main() {struct Student student1 {Alice, 20, 3.5};printStudent(student1);struct Student *studentPtr (struct Student *)malloc(sizeof(struct Student));if (studentPtr NULL) {printf(Memory allocation failed\n);return 1;}strcpy(studentPtr-name, Bob);studentPtr-age 21;studentPtr-gpa 3.7;printStudent(studentPtr);free(studentPtr);return 0;
}使用结构体指针构建链表
结构体指针在构建复杂数据结构如链表时非常有用。以下是一个简单的单链表示例
#include stdio.h
#include stdlib.h// 定义链表节点
struct Node {int data;struct Node *next;
};// 创建新节点
struct Node* createNode(int data) {struct Node *newNode (struct Node *)malloc(sizeof(struct Node));if (newNode NULL) {printf(Memory allocation failed\n);exit(1);}newNode-data data;newNode-next NULL;return newNode;
}// 打印链表
void printList(struct Node *head) {struct Node *current head;while (current ! NULL) {printf(%d - , current-data);current current-next;}printf(NULL\n);
}int main() {struct Node *head createNode(1);head-next createNode(2);head-next-next createNode(3);printList(head);// 释放内存struct Node *current head;struct Node *next;while (current ! NULL) {next current-next;free(current);current next;}return 0;
}高级用法
当然这里有更多关于C语言结构体指针的高级用法和注意事项。
多级指针指向指针的指针
有时候我们可能需要使用指向指针的指针尤其是在处理动态二维数组或在函数中修改指针变量时。以下是一个简单的示例
#include stdio.h
#include stdlib.hstruct Student {char name[50];int age;float gpa;
};void allocateStudent(struct Student **studentPtr) {*studentPtr (struct Student *)malloc(sizeof(struct Student));if (*studentPtr NULL) {printf(Memory allocation failed\n);exit(1);}
}int main() {struct Student *studentPtr NULL;allocateStudent(studentPtr);strcpy(studentPtr-name, Alice);studentPtr-age 20;studentPtr-gpa 3.5;printf(Name: %s, Age: %d, GPA: %.2f\n, studentPtr-name, studentPtr-age, studentPtr-gpa);free(studentPtr);return 0;
}在这个例子中allocateStudent 函数使用了双重指针struct Student **来分配内存并修改指针变量。
动态二维数组
使用结构体指针可以创建动态二维数组。例如一个表示学生成绩的二维数组
#include stdio.h
#include stdlib.hstruct Grade {int studentId;float score;
};int main() {int rows 3;int cols 2;// 分配行指针数组struct Grade **grades (struct Grade **)malloc(rows * sizeof(struct Grade *));if (grades NULL) {printf(Memory allocation failed\n);return 1;}// 分配每行的列for (int i 0; i rows; i) {grades[i] (struct Grade *)malloc(cols * sizeof(struct Grade));if (grades[i] NULL) {printf(Memory allocation failed\n);return 1;}}// 初始化数据for (int i 0; i rows; i) {for (int j 0; j cols; j) {grades[i][j].studentId i * cols j;grades[i][j].score (i 1) * (j 1) * 10.0;}}// 输出数据for (int i 0; i rows; i) {for (int j 0; j cols; j) {printf(Student ID: %d, Score: %.2f\n, grades[i][j].studentId, grades[i][j].score);}}// 释放内存for (int i 0; i rows; i) {free(grades[i]);}free(grades);return 0;
}结构体指针与链表操作
链表是一种常见的数据结构使用结构体指针实现链表操作是一个非常好的练习。以下是一些基本的链表操作示例包括插入和删除节点
插入节点
void insertAtBeginning(struct Node **head, int data) {struct Node *newNode createNode(data);newNode-next *head;*head newNode;
}void insertAtEnd(struct Node **head, int data) {struct Node *newNode createNode(data);if (*head NULL) {*head newNode;return;}struct Node *current *head;while (current-next ! NULL) {current current-next;}current-next newNode;
}删除节点
void deleteNode(struct Node **head, int key) {struct Node *temp *head, *prev NULL;// 如果头节点持有要删除的值if (temp ! NULL temp-data key) {*head temp-next;free(temp);return;}// 搜索要删除的节点while (temp ! NULL temp-data ! key) {prev temp;temp temp-next;}// 如果没有找到该值if (temp NULL) return;// 解除链接并释放内存prev-next temp-next;free(temp);
}高级链表操作
链表反转
反转链表是一个常见的操作以下是反转单链表的代码示例
#include stdio.h
#include stdlib.hstruct Node {int data;struct Node *next;
};struct Node* createNode(int data) {struct Node *newNode (struct Node *)malloc(sizeof(struct Node));if (newNode NULL) {printf(Memory allocation failed\n);exit(1);}newNode-data data;newNode-next NULL;return newNode;
}void reverseList(struct Node **head) {struct Node *prev NULL;struct Node *current *head;struct Node *next NULL;while (current ! NULL) {next current-next;current-next prev;prev current;current next;}*head prev;
}void printList(struct Node *head) {struct Node *current head;while (current ! NULL) {printf(%d - , current-data);current current-next;}printf(NULL\n);
}int main() {struct Node *head createNode(1);head-next createNode(2);head-next-next createNode(3);printf(Original List:\n);printList(head);reverseList(head);printf(Reversed List:\n);printList(head);// 释放内存struct Node *current head;struct Node *next;while (current ! NULL) {next current-next;free(current);current next;}return 0;
}链表合并
合并两个有序链表是一个常见操作以下是合并两个有序链表的代码示例
struct Node* mergeLists(struct Node *l1, struct Node *l2) {if (l1 NULL) return l2;if (l2 NULL) return l1;struct Node *head NULL;if (l1-data l2-data) {head l1;l1 l1-next;} else {head l2;l2 l2-next;}struct Node *current head;while (l1 ! NULL l2 ! NULL) {if (l1-data l2-data) {current-next l1;l1 l1-next;} else {current-next l2;l2 l2-next;}current current-next;}if (l1 ! NULL) {current-next l1;} else {current-next l2;}return head;
}深拷贝结构体
有时候我们需要对结构体进行深拷贝即复制结构体及其所有嵌套的内容。以下是一个深拷贝简单结构体的示例
#include stdio.h
#include string.h
#include stdlib.hstruct Address {char street[100];char city[50];char state[50];int zip;
};struct Student {char name[50];int age;float gpa;struct Address *address;
};struct Student* deepCopyStudent(const struct Student *original) {struct Student *copy (struct Student *)malloc(sizeof(struct Student));if (copy NULL) {printf(Memory allocation failed\n);exit(1);}strcpy(copy-name, original-name);copy-age original-age;copy-gpa original-gpa;copy-address (struct Address *)malloc(sizeof(struct Address));if (copy-address NULL) {printf(Memory allocation failed\n);free(copy);exit(1);}memcpy(copy-address, original-address, sizeof(struct Address));return copy;
}int main() {struct Address address {123 Maple St, Springfield, IL, 62701};struct Student student1 {Alice, 20, 3.5, address};struct Student *studentCopy deepCopyStudent(student1);// 修改原始数据以验证深拷贝strcpy(student1.address-city, Changed City);printf(Original Student: %s, %s\n, student1