C 语言指针详解:从入门到精通的完整指南

释放双眼,带上耳机,听听看~!
指针是 C 语言的灵魂,也是很多初学者最头疼的概念。本文通过大量实例,带你彻底理解 C 语言指针的核心用法,包括指针基础、数组与指针、函数指针、动态内存分配等。

指针是 C 语言的灵魂,也是很多初学者最头疼的概念。本文将通过大量实例,带你彻底理解 C 语言指针的核心用法。

什么是指针?

简单来说,指针就是一个变量,它存储的是另一个变量的内存地址。想象一下,你家的地址就是一个”指针”,通过这个地址可以找到你家。

#include <stdio.h>

int main() {
    int age = 25;        // 定义一个整型变量
    int *p = &age;       // p 是指针,存储 age 的地址
    
    printf("age 的值:%d\n", age);
    printf("age 的地址:%p\n", &age);
    printf("指针 p 的值:%p\n", p);
    printf("指针 p 指向的值:%d\n", *p);
    
    return 0;
}

输出结果:

age 的值:25
age 的地址:0x7fff5fbff6ac
指针 p 的值:0x7fff5fbff6ac
指针 p 指向的值:25

指针的核心运算符

1. 取地址运算符 &

int a = 10;
int *ptr = &a;  // &a 获取变量 a 的地址

2. 解引用运算符 *

int a = 10;
int *ptr = &a;
printf("%d", *ptr);  // *ptr 获取 ptr 指向的值,输出 10

指针与数组

指针和数组有着密切的关系,数组名本质上就是一个常量指针。

#include <stdio.h>

int main() {
    int arr[5] = {1, 2, 3, 4, 5};
    int *ptr = arr;  // ptr 指向数组第一个元素
    
    // 两种访问方式等价
    printf("arr[0] = %d\n", arr[0]);
    printf("*ptr = %d\n", *ptr);
    
    // 指针算术运算
    for(int i = 0; i < 5; i++) {
        printf("arr[%d] = %d\n", i, *(ptr + i));
    }
    
    return 0;
}

指针与函数

1. 指针作为函数参数

通过指针可以实现”传地址调用”,在函数内部修改外部变量的值。

#include <stdio.h>

// 交换两个数的值
void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 10, y = 20;
    swap(&x, &y);
    printf("x = %d, y = %d\n", x, y);  // 输出:x = 20, y = 10
    return 0;
}

2. 返回指针的函数

// 返回数组中最大值的指针
int* findMax(int arr[], int size) {
    int *maxPtr = &arr[0];
    for(int i = 1; i  *maxPtr) {
            maxPtr = &arr[i];
        }
    }
    return maxPtr;
}

二级指针

指针本身也是变量,也有地址,指向指针的指针就是二级指针。

#include <stdio.h>

int main() {
    int a = 100;
    int *p1 = &a;      // 一级指针
    int **p2 = &p1;    // 二级指针
    
    printf("a = %d\n", a);
    printf("*p1 = %d\n", *p1);
    printf("**p2 = %d\n", **p2);
    
    return 0;
}

动态内存分配

指针最重要的应用之一就是动态内存管理。

#include <stdio.h>
#include <stdlib.h>

int main() {
    // 动态分配数组
    int n = 5;
    int *arr = (int*)malloc(n * sizeof(int));
    
    // 使用动态数组
    for(int i = 0; i < n; i++) {
        arr[i] = (i + 1) * 10;
    }
    
    // 打印结果
    for(int i = 0; i < n; i++) {
        printf("arr[%d] = %d\n", i, arr[i]);
    }
    
    // 释放内存
    free(arr);
    arr = NULL;  // 避免野指针
    
    return 0;
}

常见指针错误

1. 野指针

// 错误示例
int *ptr;  // 未初始化的指针
*ptr = 10; // 危险!ptr 指向未知地址

// 正确做法
int *ptr = NULL;  // 初始化为 NULL
int a = 10;
ptr = &a;         // 再赋值有效地址

2. 内存泄漏

// 错误示例
int *ptr = (int*)malloc(sizeof(int));
*ptr = 10;
// 忘记 free(ptr),导致内存泄漏

// 正确做法
int *ptr = (int*)malloc(sizeof(int));
*ptr = 10;
// 使用完毕后
free(ptr);
ptr = NULL;

3. 悬空指针

// 错误示例
int *getPointer() {
    int local = 100;
    return &local;  // 错误!返回局部变量地址
}

// 正确做法
int *getPointer() {
    int *ptr = (int*)malloc(sizeof(int));
    *ptr = 100;
    return ptr;  // 返回动态分配的内存
}

实战练习

题目 1:字符串反转

#include <stdio.h>
#include <string.h>

void reverseString(char *str) {
    char *start = str;
    char *end = str + strlen(str) - 1;
    char temp;
    
    while(start < end) {
        temp = *start;
        *start = *end;
        *end = temp;
        start++;
        end--;
    }
}

int main() {
    char str[] = "Hello, World!";
    printf("原字符串:%s\n", str);
    reverseString(str);
    printf("反转后:%s\n", str);
    return 0;
}

题目 2:冒泡排序(指针实现)

#include <stdio.h>

void bubbleSort(int *arr, int n) {
    for(int i = 0; i < n - 1; i++) {
        for(int j = 0; j  *(arr + j + 1)) {
                int temp = *(arr + j);
                *(arr + j) = *(arr + j + 1);
                *(arr + j + 1) = temp;
            }
        }
    }
}

int main() {
    int arr[] = {64, 34, 25, 12, 22, 11, 90};
    int n = sizeof(arr) / sizeof(arr[0]);
    
    bubbleSort(arr, n);
    
    printf("排序后:");
    for(int i = 0; i < n; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    return 0;
}

总结

指针是 C 语言的核心,掌握指针需要大量实践。以下是学习建议:

  1. 理解概念:指针就是地址,*和&是核心运算符
  2. 多画图:画出内存图帮助理解指针指向
  3. 多练习:通过实际编程加深理解
  4. 注意内存管理:malloc 和 free 配对使用
  5. 避免常见错误:野指针、内存泄漏、悬空指针

指针虽然难,但一旦掌握,你的 C 语言水平会有质的飞跃。加油!💪


下节预告:《数据结构基础:链表与指针的完美结合》

如果你觉得本文有帮助,欢迎收藏、转发,让更多人看到!

声明:本站所有文章,如无特殊说明或标注,均来自于互联网,下载的软件和资源请在24小时之内删除,本站提供的资源只可作为下载、学习交流使用,其版权归原作者所有,其产生的任何后果均自己承担,本站不作任何责任承担,具体可查看本站免责声明。如已声明或标注原创,任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理,客服链接:点此前往,投诉邮箱:nc08wlkj@163.com

给TA赞赏
共{{data.count}}人
人已赞赏
技术教程

Linux系统运维必备:20个最实用的命令行技巧

2026-2-15 14:39:39

技术教程

Java 基础语法入门:零基础也能看懂的详细教程

2026-3-27 0:37:35

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索