C语言快速入门教程
首页
入门指南
基础教程
进阶教程
实战案例
编程指南
首页
入门指南
基础教程
进阶教程
实战案例
编程指南
  • 进阶教程

    • 指针入门
    • 字符串处理
    • 结构体
    • 文件操作
    • 动态内存管理
    • 预处理器

指针入门

嗨,我是长安!

说实话,指针是我当年学C语言时最难啃的骨头。我光是理解指针就花了一个多月,做了无数练习题。但现在回过头来看,其实并没有那么难。今天我来用最简单的方式,把指针给你讲明白。

指针是C语言的核心概念,也是最难理解的部分。但别怕,跟着我的节奏来,一定能学会!

什么是指针?

指针就是存储地址的变量。

类比理解

我当年就是用这个例子理解的,分享给你:

想象你住在一个小区:

  • 房子 = 变量(存数据)
  • 门牌号 = 地址
  • 指针 = 记录门牌号的本子
graph LR
    A[变量 age=18] -->|地址: 0x1000| B[内存地址]
    C[指针 p] -->|存储| B

为什么需要指针?

工作这几年,我发现指针真的太重要了。它能让你:

  1. 直接操作内存 - 更高效
  2. 动态分配内存 - 灵活管理
  3. 函数修改参数 - 传递地址
  4. 数据结构 - 链表、树等

地址和取地址符 &

每个变量都有地址,使用 & 获取:

#include <stdio.h>

int main() {
    int age = 18;
    
    printf("age的值:%d\n", age);
    printf("age的地址:%p\n", &age);
    
    return 0;
}

输出:

age的值:18
age的地址:0x7ffeeb8a9a1c  (每次运行可能不同)

指针的声明和使用

语法

数据类型 *指针名;

示例

#include <stdio.h>

int main() {
    int age = 18;
    int *p;  // 声明指针
    
    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 - 取age的地址
  • *p - 通过指针访问值(解引用)

指针的三个重要操作

操作符号含义示例
声明*声明指针变量int *p;
取地址&获取变量地址p = &age;
解引用*访问指针指向的值*p = 20;
#include <stdio.h>

int main() {
    int num = 10;
    int *ptr = &num;  // ptr指向num
    
    printf("num = %d\n", num);      // 10
    printf("*ptr = %d\n", *ptr);    // 10(通过指针访问)
    
    *ptr = 20;  // 通过指针修改值
    
    printf("修改后 num = %d\n", num);  // 20
    
    return 0;
}

指针与函数

值传递 vs 指针传递

#include <stdio.h>

// 值传递(不能修改原变量)
void changeValue(int x) {
    x = 100;
}

// 指针传递(可以修改原变量)
void changeByPointer(int *p) {
    *p = 100;
}

int main() {
    int a = 10, b = 10;
    
    changeValue(a);
    printf("值传递后 a = %d\n", a);  // 10(没变)
    
    changeByPointer(&b);
    printf("指针传递后 b = %d\n", b);  // 100(改变了)
    
    return 0;
}

实例:交换两个数

#include <stdio.h>

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x = 10, y = 20;
    
    printf("交换前:x=%d, y=%d\n", x, y);
    swap(&x, &y);
    printf("交换后:x=%d, y=%d\n", x, y);
    
    return 0;
}

指针与数组

数组名就是指向第一个元素的指针!

#include <stdio.h>

int main() {
    int arr[] = {10, 20, 30, 40, 50};
    int *p = arr;  // 等价于 p = &arr[0]
    
    printf("arr[0] = %d\n", arr[0]);   // 10
    printf("*p = %d\n", *p);           // 10
    printf("*(p+1) = %d\n", *(p+1));   // 20
    printf("p[2] = %d\n", p[2]);       // 30
    
    // 遍历数组
    for (int i = 0; i < 5; i++) {
        printf("%d ", *(p + i));
    }
    printf("\n");
    
    return 0;
}

常见错误

错误1:未初始化指针

这个错误我当年犯过无数次:

int *p;
*p = 10;  // ❌ 危险!p指向未知地址

正确做法:

int num;
int *p = &num;
*p = 10;  // ✅ 安全

错误2:野指针

int *p = (int*)0x1234;  // ❌ 随意指向一个地址
*p = 10;  // 可能崩溃

错误3:悬空指针

int *p;
{
    int num = 10;
    p = &num;
}
// num已销毁,p变成悬空指针
*p = 20;  // ❌ 危险

NULL指针

#include <stdio.h>

int main() {
    int *p = NULL;  // 空指针
    
    if (p == NULL) {
        printf("指针为空\n");
    }
    
    // 使用前检查
    if (p != NULL) {
        *p = 10;
    }
    
    return 0;
}

实战案例

案例1:数组求和(指针版)

#include <stdio.h>

int sumArray(int *arr, int size) {
    int sum = 0;
    for (int i = 0; i < size; i++) {
        sum += *(arr + i);
    }
    return sum;
}

int main() {
    int nums[] = {10, 20, 30, 40, 50};
    int size = sizeof(nums) / sizeof(nums[0]);
    
    int total = sumArray(nums, size);
    printf("总和:%d\n", total);
    
    return 0;
}

案例2:字符串长度

#include <stdio.h>

int stringLength(char *str) {
    int len = 0;
    while (*str != '\0') {
        len++;
        str++;  // 指针移动
    }
    return len;
}

int main() {
    char name[] = "Hello";
    printf("长度:%d\n", stringLength(name));
    
    return 0;
}

练习题

练习1:通过指针输入

用指针实现输入两个数并交换。

练习2:数组最大值

用指针找出数组最大值。

练习3:字符串复制

用指针实现字符串复制功能。

答案参考

查看答案

练习1:

#include <stdio.h>

void input(int *a, int *b) {
    printf("输入两个数:");
    scanf("%d %d", a, b);
}

void swap(int *a, int *b) {
    int temp = *a;
    *a = *b;
    *b = temp;
}

int main() {
    int x, y;
    input(&x, &y);
    printf("原值:x=%d, y=%d\n", x, y);
    swap(&x, &y);
    printf("交换后:x=%d, y=%d\n", x, y);
    return 0;
}

知识点总结

  • ✅ 指针存储地址
  • ✅ & 取地址,* 解引用
  • ✅ 指针可以修改函数外的变量
  • ✅ 数组名是指针
  • ✅ 使用前初始化,用后检查NULL

下一步

👉 字符串详解

💡 学习建议

指针是难点,多写代码多实践!画图理解内存布局会很有帮助。

最近更新: 2025/12/26 14:29
Next
字符串处理