1.malloc函数
malloc
函数用于在堆上动态分配内存空间,其原型如下:
#include <stdlib.h>
void *malloc(size_t size);
参数size
指定要分配的字节数。
成功时返回指向分配内存的指针,
失败时返回NULL
。申请的空间未初始化,内容不确定。
示例:
int *p = (int *)malloc(10 * sizeof(int));
if (p == NULL) {
// 处理内存分配失败
}
2.free函数
free
函数用于释放之前动态分配的内存:
void free(void *ptr);
参数ptr
必须是指向由malloc
、calloc
或realloc
分配的内存块的指针。
释放后应将指针设为NULL
,避免成为野指针。
示例:
free(p);
p = NULL;
3.realloc函数
realloc
函数用于调整已分配内存块的大小:
void *realloc(void *ptr, size_t size);
ptr
是之前分配的内存指针。
size
是新的大小(字节数)。
可能返回新的指针位置,原内容会被复制到新空间。
原空间会被自动释放。
示例:
int *new_p = (int *)realloc(p, 20 * sizeof(int));
if (new_p != NULL)
{
p = new_p;
}
4.calloc函数
calloc
函数分配并清零内存:
void *calloc(size_t nmemb, size_t size);
分配nmemb
个大小为size
的连续空间。
内存会被初始化为0。
示例:
int *p = (int *)calloc(10, sizeof(int)); // 分配10个int并清零
5.reallocarray函数
reallocarray
是realloc
的安全版本:
void *reallocarray(void *ptr, size_t nmemb, size_t size);
防止nmemb * size
计算溢出。
其他特性与realloc
相同。
6.函数指针
函数指针是指向函数的指针变量,存储函数的入口地址。
基本用法:
// 函数声明
int max(int a, int b);
// 定义函数指针
int (*pfunc)(int, int);
// 赋值
pfunc = max; // 或 pfunc = &max;
// 通过指针调用函数
int result = pfunc(3, 5);
6.回调函数
回调函数是通过函数指针调用的函数,常用于库函数中让用户自定义行为。
示例:
// 回调函数示例
int div1(int a, int b)
{
return a / b;
}
// 使用回调的函数
void calculate(int (*callback)(int, int), int x, int y)
{
int result = callback(x, y);
printf("Result: %d\n", result);
}
// 调用
calculate(div1, 10, 2);
7.qsort函数应用
qsort
是标准库中的快速排序函数,使用回调函数进行比较:
void qsort(void *base, size_t nmemb, size_t size, int (*compar)(const void *, const void *));
示例:对double
数组排序
int doublecmp(const void *a, const void *b)
{
double da = *(const double *)a;
double db = *(const double *)b;
return (da > db) - (da < db);
}
double arr[] = {3.2, 1.5, 4.7, 2.1};
qsort(arr, 4, sizeof(double), doublecmp);
8.指针的高级应用
1.字符指针数组
字符指针数组常用于存储多个字符串:
char *names[] = {"Alice", "Bob", "Charlie"};
for (int i = 0; i < 3; i++)
{
printf("%s\n", names[i]);
}
2.指针函数
指针函数是返回指针类型的函数:
// 返回字符串的函数
const char *get_greeting()
{
return "Hello, World!";
}
3.多级指针
多级指针用于处理复杂的数据结构:
int a = 10;
int *p = &a;
int **pp = &p;
printf("%d\n", **pp); // 输出10
4.二维数组作为函数参数
void print_matrix(int (*mat)[3], int rows)
{
for (int i = 0; i < rows; i++)
{
for (int j = 0; j < 3; j++)
{
printf("%d ", mat[i][j]);
}
printf("\n");
}
}
int main()
{
int matrix[2][3] = {{1,2,3}, {4,5,6}};
print_matrix(matrix, 2);
return 0;
}
5.指针数组作为函数参数
void print_strings(char **strings, int count)
{
for (int i = 0; i < count; i++)
{
printf("%s\n", strings[i]);
}
}
int main()
{
char *strs[] = {"One", "Two", "Three"};
print_strings(strs, 3);
return 0;
}