1. 函数指针
函数指针是指向函数的指针,它允许将函数作为参数传递给其他函数,或者从函数返回函
数。这种技术在实现回调函数和策略模式时非常有用。
void hello() { printf("Hello, World!\n"); } void greet(void (*func)()) { func(); // 调用传入的函数 } int main() { void (*funcPtr)() = hello; // 声明并初始化函数指针 greet(funcPtr); // 将函数指针作为参数传递 return 0; }
2. 指针算术运算
指针算术运算允许你在指针上进行加减操作,从而在数组或内存块中移动。这种技术在处理数组和动态内存分配时非常有用。
int arr[] = {10, 20, 30, 40, 50}; int *ptr = arr; ptr += 2; // 移动指针到数组的第三个元素 printf("%d\n", *ptr); // 输出30
3. 指针与数组
指针和数组紧密相关,指针可以像数组一样被索引,数组名可以作为指向数组首元素的指针。
int arr[] = {1, 2, 3, 4, 5}; int *p = arr; for (int i = 0; i < 5; i++) { printf("%d ", *(p + i)); // 使用指针访问数组元素 }
4. void指针
void指针是一种特殊的指针类型,可以指向任何数据类型的内存地址。它通常用于泛型数据处理和内存操作函数,如memcpy和malloc。
int a = 10; void *p = &a; printf("%d\n", *(int *)p); // 将void指针转换为int指针再解引用
5. 指针数组与数组指针
指针数组是包含指针的数组,而数组指针是指向数组的指针。有点绕哈🥲,这两者在语法上相似,但含义完全不同。
int *ptrArray[5]; // 指针数组,包含5个int类型的指针 int (*arrayPtr)[5]; // 数组指针,指向一个含有5个int的数组
6. 多级指针
多级指针,即指向指针的指针,可以用来动态管理多维数组或传递指针的地址。
int var = 23; int *ptr = &var; int **pptr = &ptr; printf("Value of var = %d\n", **pptr); // 输出23
7. 指针与结构体
指针可以指向结构体,这在动态内存分配和数据结构(如链表和树)的操作中非常有用。
typedef struct { int x; int y; } Point; Point p = {10, 20}; Point *ptr = &p; printf("Point: (%d, %d)\n", ptr->x, ptr->y); // 使用箭头操作符访问结构体成员
8. 指针类型转换
指针类型转换允许你在不同类型的指针之间进行转换,这在底层数据处理和优化时非常有用。
char *cptr; int *iptr; cptr = (char *)malloc(10 * sizeof(char)); iptr = (int *)cptr; // 将char指针转换为int指针
9. 指针与动态内存分配
指针与动态内存分配结合使用,可以创建灵活的数据结构,并管理程序运行时的内存需求。
int *ptr = (int *)malloc(5 * sizeof(int)); // 动态分配内存 if (ptr != NULL) { for (int i = 0; i < 5; i++) { ptr[i] = i * 10; // 初始化内存 } } free(ptr); // 释放内存
10. 指针与位操作
结合指针和位操作,可以用于硬件编程和优化内存访问。
unsigned int a = 0x12345678; unsigned char *p = (unsigned char *)&a; *p &= 0xF0; // 只修改最低字节的低四位
【注】
指针的高级应用能够极大地提升程序的灵活性和效率,使用指针时需要谨慎操作,避免出现内存泄漏、野指针等问题。
掌握好C语言指针的使用技巧,将使你在编程道路上更加得心应手。