1. 指针和函数
1.1 函数参数传递
- 值传递:
- 将实参的值复制一份传递给形参。
- 形参的修改不会影响实参。
- 指针传递:
- 将实参的地址传递给形参。
- 形参的修改会影响到实参。
1.1.1 值传递
- 示例:c
#include <stdio.h> void increment(int x) { x++; printf("Inside function: x = %d\n", x); } int main() { int a = 5; printf("Before function call: a = %d\n", a); increment(a); printf("After function call: a = %d\n", a); return 0; }- 输出:
Before function call: a = 5 Inside function: x = 6 After function call: a = 5
- 输出:
1.1.2 指针传递
- 示例:c
#include <stdio.h> void increment(int *x) { (*x)++; printf("Inside function: *x = %d\n", *x); } int main() { int a = 5; printf("Before function call: a = %d\n", a); increment(&a); printf("After function call: a = %d\n", a); return 0; }- 输出:
Before function call: a = 5 Inside function: *x = 6 After function call: a = 6
- 输出:
1.2 返回指针的函数
- 返回指针:
- 函数可以返回指向某个数据类型的指针。
- 示例:c
#include <stdio.h> #include <stdlib.h> int* createArray(int size) { int *arr = (int*)malloc(size * sizeof(int)); if (arr == NULL) { printf("Memory allocation failed\n"); exit(1); } for (int i = 0; i < size; i++) { arr[i] = i + 1; } return arr; } int main() { int *myArray = createArray(5); for (int i = 0; i < 5; i++) { printf("%d ", myArray[i]); } free(myArray); // 释放内存 return 0; }- 输出:
1 2 3 4 5
- 输出:
2. 动态内存分配
2.1 malloc 函数
- 功能:
- 分配指定字节数的内存块,并返回指向该内存块的指针。
- 语法:c
void* malloc(size_t size); - 参数:
size:需要分配的字节数。
- 返回值:
- 成功时返回指向分配内存的指针,失败时返回
NULL。
- 成功时返回指向分配内存的指针,失败时返回
- 示例:c
#include <stdio.h> #include <stdlib.h> int main() { int *arr = (int*)malloc(5 * sizeof(int)); if (arr == NULL) { printf("Memory allocation failed\n"); return 1; } for (int i = 0; i < 5; i++) { arr[i] = i + 1; } for (int i = 0; i < 5; i++) { printf("%d ", arr[i]); } free(arr); // 释放内存 return 0; }- 输出:
1 2 3 4 5
- 输出:
2.2 calloc 函数
- 功能:
- 分配指定数量和大小的内存块,并将其初始化为零。
- 语法:c
void* calloc(size_t num, size_t size); - 参数:
num:元素的数量。size:每个元素的大小(字节数)。
- 返回值:
- 成功时返回指向分配内存的指针,失败时返回
NULL。
- 成功时返回指向分配内存的指针,失败时返回
- 示例:c
#include <stdio.h> #include <stdlib.h> int main() { int *arr = (int*)calloc(5, sizeof(int)); if (arr == NULL) { printf("Memory allocation failed\n"); return 1; } for (int i = 0; i < 5; i++) { printf("%d ", arr[i]); // 输出 0 0 0 0 0 } free(arr); // 释放内存 return 0; }- 输出:
0 0 0 0 0
- 输出:
2.3 realloc 函数
- 功能:
- 改变已分配内存块的大小。
- 语法:c
void* realloc(void* ptr, size_t newSize); - 参数:
ptr:指向已分配内存的指针。newSize:新的内存大小(字节数)。
- 返回值:
- 成功时返回指向重新分配内存的指针,失败时返回
NULL。
- 成功时返回指向重新分配内存的指针,失败时返回
- 示例:c
#include <stdio.h> #include <stdlib.h> int main() { int *arr = (int*)malloc(5 * sizeof(int)); if (arr == NULL) { printf("Memory allocation failed\n"); return 1; } for (int i = 0; i < 5; i++) { arr[i] = i + 1; } arr = (int*)realloc(arr, 10 * sizeof(int)); if (arr == NULL) { printf("Memory reallocation failed\n"); return 1; } for (int i = 5; i < 10; i++) { arr[i] = i + 1; } for (int i = 0; i < 10; i++) { printf("%d ", arr[i]); } free(arr); // 释放内存 return 0; }- 输出:
1 2 3 4 5 6 7 8 9 10
- 输出:
2.4 free 函数
- 功能:
- 释放之前用
malloc,calloc或realloc分配的内存。
- 释放之前用
- 语法:c
void free(void* ptr); - 参数:
ptr:指向要释放内存的指针。
- 示例:c
#include <stdio.h> #include <stdlib.h> int main() { int *arr = (int*)malloc(5 * sizeof(int)); if (arr == NULL) { printf("Memory allocation failed\n"); return 1; } for (int i = 0; i < 5; i++) { arr[i] = i + 1; } for (int i = 0; i < 5; i++) { printf("%d ", arr[i]); } free(arr); // 释放内存 return 0; }- 输出:
1 2 3 4 5
- 输出:
3. 结构体和动态内存分配
3.1 结构体定义
- 定义:
- 结构体是一种用户自定义的数据类型,可以包含多个不同类型的数据成员。
- 示例:c
#include <stdio.h> #include <stdlib.h> struct Student { char name[50]; int age; float gpa; }; int main() { struct Student *student = (struct Student*)malloc(sizeof(struct Student)); if (student == NULL) { printf("Memory allocation failed\n"); return 1; } strcpy(student->name, "John Doe"); student->age = 20; student->gpa = 3.5; printf("Name: %s\n", student->name); printf("Age: %d\n", student->age); printf("GPA: %.2f\n", student->gpa); free(student); // 释放内存 return 0; }- 输出:
Name: John Doe Age: 20 GPA: 3.50
- 输出:
3.2 动态分配数组中的结构体
- 示例:c
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Student { char name[50]; int age; float gpa; }; int main() { int n; printf("Enter the number of students: "); scanf("%d", &n); struct Student *students = (struct Student*)malloc(n * sizeof(struct Student)); if (students == NULL) { printf("Memory allocation failed\n"); return 1; } for (int i = 0; i < n; i++) { printf("Enter details for student %d:\n", i + 1); printf("Name: "); scanf("%s", students[i].name); printf("Age: "); scanf("%d", &students[i].age); printf("GPA: "); scanf("%f", &students[i].gpa); } for (int i = 0; i < n; i++) { printf("Student %d:\n", i + 1); printf("Name: %s\n", students[i].name); printf("Age: %d\n", students[i].age); printf("GPA: %.2f\n", students[i].gpa); } free(students); // 释放内存 return 0; }
总结
- 指针和函数:
- 值传递:将实参的值复制一份传递给形参。
- 指针传递:将实参的地址传递给形参。
- 返回指针的函数:函数可以返回指向某个数据类型的指针。
- 动态内存分配:
malloc:分配指定字节数的内存块。calloc:分配指定数量和大小的内存块,并初始化为零。realloc:改变已分配内存块的大小。free:释放之前分配的内存。
- 结构体和动态内存分配:
- 结构体定义:用户自定义的数据类型,可以包含多个不同类型的数据成员。
- 动态分配数组中的结构体:使用
malloc分配多个结构体的内存。
