指针运算

指针的算术操作

指针运算是指针的重要特性之一,它允许我们对指针进行算术操作。东巴文(db-w.cn) 将带你深入学习指针运算,掌握指针的高级应用。

💡 东巴文观点:指针运算不是简单的整数运算,而是基于指针类型的地址运算,运算步长由指针类型决定。

指针运算概述

指针运算的类型

东巴文说明:指针支持以下运算:

指针运算类型
├── 算术运算
│   ├── 指针 + 整数
│   ├── 指针 - 整数
│   ├── 指针++ / 指针--
│   └── 指针 - 指针
├── 关系运算
│   ├── 指针 == 指针
│   ├── 指针 != 指针
│   ├── 指针 < 指针
│   ├── 指针 > 指针
│   ├── 指针 <= 指针
│   └── 指针 >= 指针
└── 赋值运算
    ├── 指针 = 地址
    ├── 指针 += 整数
    └── 指针 -= 整数

指针的算术运算

指针加减整数

#include <stdio.h>

int main() {
    printf("=== 东巴文指针加减整数 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr = arr;
    
    printf("初始指针:\n");
    printf("ptr = %p, *ptr = %d\n", ptr, *ptr);
    
    printf("\n指针 + 1:\n");
    printf("ptr + 1 = %p, *(ptr + 1) = %d\n", ptr + 1, *(ptr + 1));
    
    printf("\n指针 + 2:\n");
    printf("ptr + 2 = %p, *(ptr + 2) = %d\n", ptr + 2, *(ptr + 2));
    
    printf("\n指针 - 1:\n");
    printf("ptr + 4 - 1 = %p, *(ptr + 4 - 1) = %d\n", ptr + 4 - 1, *(ptr + 4 - 1));
    
    return 0;
}

东巴文说明

  • ptr + n 向后移动n个元素
  • ptr - n 向前移动n个元素
  • 移动的字节数 = n * sizeof(指针类型)

指针的自增自减

#include <stdio.h>

int main() {
    printf("=== 东巴文指针自增自减 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr = arr;
    
    printf("初始:*ptr = %d\n", *ptr);
    
    ptr++;  // 向后移动一个元素
    printf("ptr++后:*ptr = %d\n", *ptr);
    
    ptr++;  // 再向后移动一个元素
    printf("ptr++后:*ptr = %d\n", *ptr);
    
    ptr--;  // 向前移动一个元素
    printf("ptr--后:*ptr = %d\n", *ptr);
    
    return 0;
}

东巴文说明

  • ptr++ 等价于 ptr = ptr + 1
  • ptr-- 等价于 ptr = ptr - 1
  • ++ptr--ptr 也可以使用

指针减指针

#include <stdio.h>

int main() {
    printf("=== 东巴文指针减指针 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr1 = arr;
    int *ptr2 = arr + 4;
    
    printf("ptr1 = %p, *ptr1 = %d\n", ptr1, *ptr1);
    printf("ptr2 = %p, *ptr2 = %d\n", ptr2, *ptr2);
    
    // 指针相减得到元素个数
    int diff = ptr2 - ptr1;
    printf("\nptr2 - ptr1 = %d 个元素\n", diff);
    
    return 0;
}

东巴文说明

  • 两个指针相减得到元素个数
  • 两个指针必须指向同一数组
  • 结果类型为 ptrdiff_t

指针的关系运算

指针比较

#include <stdio.h>

int main() {
    printf("=== 东巴文指针比较 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr1 = arr;
    int *ptr2 = arr + 2;
    int *ptr3 = arr + 2;
    
    printf("ptr1 = %p\n", ptr1);
    printf("ptr2 = %p\n", ptr2);
    printf("ptr3 = %p\n", ptr3);
    
    printf("\n比较结果:\n");
    printf("ptr1 < ptr2: %s\n", (ptr1 < ptr2) ? "true" : "false");
    printf("ptr2 == ptr3: %s\n", (ptr2 == ptr3) ? "true" : "false");
    printf("ptr1 != ptr2: %s\n", (ptr1 != ptr2) ? "true" : "false");
    printf("ptr2 > ptr1: %s\n", (ptr2 > ptr1) ? "true" : "false");
    
    return 0;
}

东巴文说明

  • 可以比较两个指针的大小
  • 比较的是地址值
  • 通常用于判断指针在数组中的位置

指针与NULL比较

#include <stdio.h>

int main() {
    printf("=== 东巴文指针与NULL比较 ===\n\n");
    
    int num = 10;
    int *ptr1 = &num;
    int *ptr2 = NULL;
    
    printf("ptr1 = %p\n", ptr1);
    printf("ptr2 = %p\n", ptr2);
    
    printf("\n比较结果:\n");
    printf("ptr1 != NULL: %s\n", (ptr1 != NULL) ? "true" : "false");
    printf("ptr2 == NULL: %s\n", (ptr2 == NULL) ? "true" : "false");
    
    return 0;
}

指针运算的步长

不同类型的指针步长

#include <stdio.h>

int main() {
    printf("=== 东巴文指针步长 ===\n\n");
    
    // int指针步长
    int intArr[] = {10, 20, 30};
    int *intPtr = intArr;
    
    printf("int指针步长:\n");
    printf("intPtr = %p\n", intPtr);
    printf("intPtr + 1 = %p (差值:%td字节)\n", intPtr + 1, (char *)(intPtr + 1) - (char *)intPtr);
    
    // double指针步长
    double dblArr[] = {1.1, 2.2, 3.3};
    double *dblPtr = dblArr;
    
    printf("\ndouble指针步长:\n");
    printf("dblPtr = %p\n", dblPtr);
    printf("dblPtr + 1 = %p (差值:%td字节)\n", dblPtr + 1, (char *)(dblPtr + 1) - (char *)dblPtr);
    
    // char指针步长
    char charArr[] = "ABC";
    char *charPtr = charArr;
    
    printf("\nchar指针步长:\n");
    printf("charPtr = %p\n", charPtr);
    printf("charPtr + 1 = %p (差值:%td字节)\n", charPtr + 1, (char *)(charPtr + 1) - (char *)charPtr);
    
    return 0;
}

东巴文说明

  • 指针步长 = sizeof(指针指向的类型)
  • int指针步长为4字节(32位系统)
  • double指针步长为8字节
  • char指针步长为1字节

指针运算的应用

数组遍历

#include <stdio.h>

int main() {
    printf("=== 东巴文指针遍历数组 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr = arr;
    int size = sizeof(arr) / sizeof(arr[0]);
    
    printf("使用指针遍历数组:\n");
    for (int i = 0; i < size; i++) {
        printf("*(ptr + %d) = %d\n", i, *(ptr + i));
    }
    
    printf("\n使用指针自增遍历数组:\n");
    ptr = arr;  // 重置指针
    for (int i = 0; i < size; i++) {
        printf("*ptr = %d\n", *ptr);
        ptr++;
    }
    
    return 0;
}

字符串处理

#include <stdio.h>

int main() {
    printf("=== 东巴文指针处理字符串 ===\n\n");
    
    char str[] = "Hello, 东巴文";
    char *ptr = str;
    
    printf("原字符串:%s\n", str);
    
    // 使用指针遍历字符串
    printf("\n逐字符输出:\n");
    while (*ptr != '\0') {
        printf("%c", *ptr);
        ptr++;
    }
    printf("\n");
    
    // 计算字符串长度
    ptr = str;
    int len = 0;
    while (*ptr != '\0') {
        len++;
        ptr++;
    }
    printf("\n字符串长度:%d\n", len);
    
    return 0;
}

查找元素

#include <stdio.h>

int *findElement(int *arr, int size, int target) {
    for (int i = 0; i < size; i++) {
        if (*arr == target) {
            return arr;
        }
        arr++;
    }
    return NULL;
}

int main() {
    printf("=== 东巴文指针查找元素 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int size = sizeof(arr) / sizeof(arr[0]);
    int target = 30;
    
    int *result = findElement(arr, size, target);
    
    if (result != NULL) {
        printf("找到元素:%d,地址:%p\n", *result, result);
        printf("位置:%ld\n", result - arr);
    } else {
        printf("未找到元素:%d\n", target);
    }
    
    return 0;
}

数组逆序

#include <stdio.h>

void reverseArray(int *start, int *end) {
    while (start < end) {
        int temp = *start;
        *start = *end;
        *end = temp;
        
        start++;
        end--;
    }
}

int main() {
    printf("=== 东巴文指针实现数组逆序 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    printf("原数组:\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    reverseArray(arr, arr + size - 1);
    
    printf("逆序后:\n");
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    return 0;
}

指针运算的注意事项

不要越界访问

#include <stdio.h>

int main() {
    printf("=== 东巴文避免指针越界 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int *ptr = arr;
    int size = sizeof(arr) / sizeof(arr[0]);
    
    // ✅ 正确:在数组范围内访问
    for (int i = 0; i < size; i++) {
        printf("*(ptr + %d) = %d\n", i, *(ptr + i));
    }
    
    // ❌ 错误:越界访问
    // printf("%d\n", *(ptr + 5));  // 越界
    
    return 0;
}

指向同一数组

#include <stdio.h>

int main() {
    printf("=== 东巴文指针运算指向同一数组 ===\n\n");
    
    int arr1[] = {10, 20, 30};
    int arr2[] = {40, 50, 60};
    
    int *ptr1 = arr1;
    int *ptr2 = arr2;
    
    // ✅ 正确:同一数组内的指针运算
    printf("arr1内:arr1[2] - arr1[0] = %ld 个元素\n", (arr1 + 2) - arr1);
    
    // ❌ 错误:不同数组间的指针运算(未定义行为)
    // printf("%ld\n", ptr2 - ptr1);  // 未定义行为
    
    return 0;
}

注意指针类型

#include <stdio.h>

int main() {
    printf("=== 东巴文注意指针类型 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    
    // int指针
    int *intPtr = arr;
    printf("int指针:*(intPtr + 1) = %d\n", *(intPtr + 1));
    
    // char指针(不推荐)
    char *charPtr = (char *)arr;
    printf("char指针:*(charPtr + 1) = %d\n", *(charPtr + 1));
    
    // 注意:不同类型的指针步长不同
    printf("\n指针步长:\n");
    printf("intPtr + 1 = %p\n", intPtr + 1);
    printf("charPtr + 4 = %p (相当于intPtr + 1)\n", charPtr + 4);
    
    return 0;
}

东巴文最佳实践

1. 使用指针遍历数组

#include <stdio.h>

int main() {
    printf("=== 东巴文使用指针遍历数组 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    // ✅ 推荐:使用指针遍历
    int *ptr = arr;
    for (int i = 0; i < size; i++) {
        printf("%d ", *ptr);
        ptr++;
    }
    printf("\n");
    
    return 0;
}

2. 检查指针范围

#include <stdio.h>

int main() {
    printf("=== 东巴文检查指针范围 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int *start = arr;
    int *end = arr + 5;
    int *ptr = arr;
    
    // ✅ 正确:检查指针范围
    while (ptr < end) {
        printf("%d ", *ptr);
        ptr++;
    }
    printf("\n");
    
    return 0;
}

3. 使用const保护数据

#include <stdio.h>

void printArray(const int *arr, int size) {
    // ✅ 正确:使用const保护数据
    for (int i = 0; i < size; i++) {
        printf("%d ", arr[i]);
    }
    printf("\n");
    
    // ❌ 错误:不能修改const指针指向的值
    // arr[0] = 100;
}

int main() {
    printf("=== 东巴文使用const保护数据 ===\n\n");
    
    int arr[] = {10, 20, 30, 40, 50};
    int size = sizeof(arr) / sizeof(arr[0]);
    
    printArray(arr, size);
    
    return 0;
}

东巴文验证清单

完成本章学习后,请确认:

  • 理解指针运算的类型
  • 掌握指针的算术运算
  • 掌握指针的关系运算
  • 理解指针运算的步长
  • 掌握指针运算的应用
  • 理解指针运算的注意事项
  • 掌握最佳实践

下一步学习

掌握指针运算后,你可以继续学习:

如果遇到问题,欢迎访问 东巴文(db-w.cn) 获取帮助!


东巴文(db-w.cn) - 让编程学习更简单

🎯 东巴文指针运算提示:指针运算不是简单的整数运算,而是基于指针类型的地址运算。在 db-w.cn,我们会通过大量实例帮你掌握指针运算!