释放双眼,带上耳机,听听看~!
欢迎来到今天的 C 语言教程!结构体和指针是 C 语言的核心,掌握它们对理解内存管理至关重要。
一、结构体基础
1.1 结构体定义
结构体允许我们将不同类型的数据组合在一起:
#include <stdio.h>
#include <string.... 
欢迎来到今天的 C 语言教程!结构体和指针是 C 语言的核心,掌握它们对理解内存管理至关重要。
一、结构体基础
1.1 结构体定义
结构体允许我们将不同类型的数据组合在一起:
#include <stdio.h>
#include <string.h>
// 定义学生结构体
struct Student {
char name[50];
int age;
float score;
};
int main() {
// 创建结构体变量
struct Student stu1;
strcpy(stu1.name, "张三");
stu1.age = 20;
stu1.score = 95.5;
printf("姓名:%s, 年龄:%d, 成绩:%.1f\n",
stu1.name, stu1.age, stu1.score);
return 0;
}
1.2 结构体数组
struct Student class[3] = {
{"张三", 20, 95.5},
{"李四", 21, 88.0},
{"王五", 19, 92.5}
};
// 遍历结构体数组
for (int i = 0; i < 3; i++) {
printf("%s: %.1f 分\n", class[i].name, class[i].score);
}
二、指针基础
2.1 指针定义
指针存储变量的内存地址:
int num = 42;
int *ptr = # // ptr 指向 num 的地址
printf("num 的值:%d\n", num);
printf("num 的地址:%p\n", (void*)&num);
printf("ptr 的值:%p\n", (void*)ptr);
printf("ptr 指向的值:%d\n", *ptr); // 解引用
2.2 指针运算
int arr[] = {10, 20, 30, 40, 50};
int *p = arr; // p 指向数组首元素
printf("%d\n", *p); // 10
printf("%d\n", *(p+1)); // 20
printf("%d\n", *(p+2)); // 30
// 指针遍历数组
for (int i = 0; i < 5; i++) {
printf("%d ", *(p+i));
}
三、结构体指针
3.1 指向结构体的指针
struct Student stu = {"张三", 20, 95.5};
struct Student *ptr = &stu;
// 访问结构体成员(两种方式)
printf("%s\n", ptr->name); // 推荐:使用箭头运算符
printf("%d\n", (*ptr).age); // 等价。但不常用
3.2 结构体指针数组
struct Student s1 = {"张三", 20, 95.5};
struct Student s2 = {"李四", 21, 88.0};
struct Student s3 = {"王五", 19, 92.5};
// 指针数组(存储地址。节省内存)
struct Student *students[] = {&s1, &s2, &s3};
for (int i = 0; i < 3; i++) {
printf("%s: %d 岁\n", students[i]->name, students[i]->age);
}
四、动态内存分配
4.1 malloc 和 free
#include <stdlib.h>
// 动态分配结构体内存
struct Student *createStudent(char *name, int age, float score) {
struct Student *stu = (struct Student*)malloc(sizeof(struct Student));
strcpy(stu->name, name);
stu->age = age;
stu->score = score;
return stu;
}
int main() {
struct Student *stu = createStudent("赵六", 22, 90.0);
printf("%s: %.1f 分\n", stu->name, stu->score);
// 释放内存(重要!)
free(stu);
return 0;
}
4.2 动态结构体数组
int n = 5;
struct Student *class = (struct Student*)malloc(n * sizeof(struct Student));
// 使用
for (int i = 0; i < n; i++) {
sprintf(class[i].name, "学生%d", i+1);
class[i].age = 20 + i;
}
// 释放
free(class);
五、链表实现
5.1 链表节点定义
struct Node {
int data;
struct Node *next;
};
// 创建新节点
struct Node* createNode(int data) {
struct Node *newNode = (struct Node*)malloc(sizeof(struct Node));
newNode->data = data;
newNode->next = NULL;
return newNode;
}
5.2 插入节点
void insertAtHead(struct Node **head, int data) {
struct Node *newNode = createNode(data);
newNode->next = *head;
*head = newNode;
}
// 使用
struct Node *head = NULL;
insertAtHead(&head, 30);
insertAtHead(&head, 20);
insertAtHead(&head, 10);
// 链表:10 -> 20 -> 30
5.3 遍历链表
void printList(struct Node *head) {
struct Node *current = head;
while (current != NULL) {
printf("%d -> ", current->data);
current = current->next;
}
printf("NULL\n");
}
六、常见错误
6.1 野指针
// 错误:未初始化的指针
int *ptr;
*ptr = 42; // 崩溃!
// 正确:初始化或分配内存
int num = 42;
int *ptr = #
*ptr = 42; // OK
6.2 内存泄漏
// 错误:分配后未释放
struct Student *stu = malloc(sizeof(struct Student));
// ... 使用
// 忘记 free(stu) - 内存泄漏!
// 正确:成对使用 malloc/free
struct Student *stu = malloc(sizeof(struct Student));
// ... 使用
free(stu); // 释放内存
七、总结
结构体和指针是 C 语言的精髓:
- 结构体用于组织相关数据
- 指针用于直接操作内存
- 结构体指针结合两者优势
- 动态内存分配需要手动管理
- 链表是指针的经典应用
关注我们获取更多 C 语言教程!
声明:本站所有文章,如无特殊说明或标注,均来自于互联网,下载的软件和资源请在24小时之内删除,本站提供的资源只可作为下载、学习交流使用,其版权归原作者所有,其产生的任何后果均自己承担,本站不作任何责任承担,具体可查看本站免责声明。如已声明或标注原创,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理,客服链接:点此前往,投诉邮箱:nc08wlkj@163.com。
