c语言的指针的用处是什么?它的表现形式是什么?

lin, kelriclink 发布于 2025-10-29 181 次阅读


此文用来记录

好的,我们来仔细讲 C语言指针,它是C语言最核心也最“魔法”的概念之一。为了理解,我会从用处表现形式两方面解释,并配上例子。


一、指针的用处(为什么需要指针)

  1. 直接操作内存
    • 指针就是一个变量,但它存储的不是数据本身,而是数据在内存中的地址。
    • 通过指针可以直接访问和修改内存中的数据。
    • 用途:提高效率、操作数组或大型数据结构而不必复制数据。
    int a = 10; int *p = &a; // p保存了a的地址 *p = 20; // 通过指针修改a printf("%d\n", a); // 输出20
  2. 函数间共享数据 / 传递引用
    • 在C中,函数参数默认是“值传递”,函数内修改不会影响原变量。
    • 如果想让函数修改外部变量,就需要传入指针(地址)。
    void addOne(int *x) { (*x)++; } int main() { int n = 5; addOne(&n); printf("%d\n", n); // 输出6 }
  3. 动态内存管理
    • 指针可以和mallocfree一起使用,动态申请和释放内存。
    • 用途:创建数组、链表、树等灵活数据结构。
    int *arr = (int*)malloc(5 * sizeof(int)); for(int i=0;i<5;i++) arr[i] = i; free(arr); // 使用完记得释放
  4. 构建复杂数据结构
    • 链表、树、图等数据结构都依赖指针来连接节点。
    • 例如链表节点:
    typedef struct Node { int data; struct Node *next; } Node;
  5. 函数指针和回调
    • 可以保存函数地址,实现回调和策略模式。
    void sayHello() { printf("Hello\n"); } void (*funcPtr)() = sayHello; funcPtr(); // 调用函数

二、指针的表现形式(指针长什么样)

  1. 声明指针 int *p; // p是指向int类型的指针 char *c; // c是指向char类型的指针 double *d; // d是指向double类型的指针
  2. 获取地址
    • 使用 & 运算符获取变量地址。
    int a = 10; int *p = &a; // p存的是a的地址
  3. 访问指针指向的数据
    • 使用 * 解引用(dereference)操作符。
    printf("%d\n", *p); // 输出10 *p = 20; // 修改a
  4. 指针运算
    • 指针可以加减整数(按类型大小移动内存地址)。
    int arr[3] = {1,2,3}; int *p = arr; // 指向arr[0] printf("%d\n", *(p+2)); // 输出3
  5. NULL指针
    • 指针未指向有效地址时可以设为NULL,防止野指针。
    int *p = NULL; if(p != NULL) *p = 10; // 避免访问非法内存

总结

方面内容
用处操作内存、共享数据、动态内存、数据结构、函数回调
表现形式指针变量(int *p)、获取地址(&a)、解引用(*p)、指针运算、NULL指针

💡 小提示
指针的核心就是“变量的地址”,一旦理解了“地址”和“解引用”,你就能理解大部分C语言高级技巧。


如果你愿意,我可以画一张 指针的图解,让你直观理解“变量、地址、指针、解引用”之间的关系,看一眼就明白。

void sayHello() { printf("Hello\n"); }
void (*funcPtr)() = sayHello;
funcPtr(); // 调用函数 ,,这是什么意思?平常起的作用是什么?

好的,我们来详细拆解你写的这段 函数指针代码,弄清楚它是什么意思、平常有什么用。


代码回顾

void sayHello() { 
    printf("Hello\n"); 
}

void (*funcPtr)() = sayHello;

funcPtr();  // 调用函数

一、逐行解析

  1. 定义一个普通函数
void sayHello() { 
    printf("Hello\n"); 
}
  • sayHello 是一个函数,功能是打印 "Hello\n"
  • 返回类型是 void,没有参数。

  1. 定义函数指针并赋值
void (*funcPtr)() = sayHello;
  • 这里出现了 函数指针
  • void (*funcPtr)() 的意思:
    • funcPtr 是一个指针变量;
    • 它指向的函数 返回类型是 void参数为空
  • = sayHello 是把 sayHello 函数的地址赋给指针。
  • 这样 funcPtr 就“指向”了 sayHello 函数。

⚠️ 注意:函数名 sayHello 本身就是函数的地址,不需要加 &,C语言里函数名会自动转换成地址。


  1. 通过指针调用函数
funcPtr();  
  • funcPtr 指向 sayHello,加上 () 就相当于调用 sayHello()
  • 输出结果是:
Hello

二、函数指针的作用

  1. 动态选择函数
    • 你可以在运行时决定调用哪个函数,而不是写死。
    void add() { printf("Add\n"); } void sub() { printf("Sub\n"); } void (*op)(); if(userChoice == 1) op = add; else op = sub; op(); // 动态调用
  2. 回调函数
    • 常用于库函数或API中,让调用者提供自己要执行的函数。
    void timer(void (*callback)()) { // 一秒后调用callback callback(); }
  3. 函数数组 / 表驱动
    • 用函数指针数组快速选择处理逻辑,避免大量if/else
    void func1() { printf("1\n"); } void func2() { printf("2\n"); } void (*funcs[2])() = {func1, func2}; funcs[1](); // 调用 func2
  4. 实现多态 / 策略模式(在C语言里)
    • 不同的行为可以通过指针动态绑定,不用改调用代码。

总结

  • funcPtr 就像是函数的“遥控器”,可以随时指向某个函数,然后通过它去调用函数。
  • 平常用途:
    1. 动态选择函数
    2. 回调机制
    3. 表驱动 / 策略模式

如果你想,我可以画一张 函数指针图解,直观展示“函数、地址、指针、调用”的关系,比文字容易理解