C语言指针

一、指针基础概念
  1. 指针与内存的关系

  • 本质:指针是存储内存地址的变量,用于直接操作内存。
  • 变量内存分配

    int a = 10;    // 在栈区申请4字节(假设int为4字节)存储10
    int* p = &a;   // p存储a的地址,通过*p可访问a的值

  • 内存单元编号:每个字节有一个唯一地址(如0x7ffd42a1),指针通过地址访问数据。

  1. 指针类型

  • 常见类型char*int*float*void*等。
  • 作用

            解引用时访问的字节数char*访问1字节,int*访问4字节。

            指针运算的步长:p+1的偏移量为sizeof(指针类型)字节。

  • void*特性

    • 无具体类型,需强制转换后才能解引用。

    • 常用于泛型编程(如malloc返回值)。

     2.指针变量的定义与使用

  • 定义语法类型* 变量名;

    int* p;       // 定义指向int的指针
    char* str;    // 定义指向char的指针

  • 操作符

       &:取变量地址(如p = &a)。

       *:解引用,访问指针指向的值(如*p = 20修改a的值)。


二、指针运算
  1. 指针 ± 整数

  • 规则p ± n的地址偏移量为n * sizeof(指针类型)

int arr[5];
int* p = arr;     // p指向arr[0]
p = p + 3;        // p指向arr[3],地址偏移3*4=12字节

   2.指针 - 指针

  • 规则:结果为两指针之间的元素个数(需同类型指针)。

    int* p1 = &arr[2];
    int* p2 = &arr[5];
    int n = p2 - p1;  // n = 3(元素个数)


三、指针与数组
  1. 数组名的本质

  • 数组名是首元素地址,类型为元素类型指针(如int arr[5]arr的类型是int*)。
  • 例外情况

    sizeof(arr)返回整个数组的字节大小(如sizeof(int[5]))。

    &arr的类型是int(*)[5](数组指针)。

     2.指针访问数组元素

  • 等价性arr[i] ⇨ *(arr + i) ⇨ *(p + i)

    int arr[3] = {1, 2, 3};
    int* p = arr;
    printf("%d", *(p + 1));  // 输出2

  3.数组传参

  • 本质:传递首元素地址,形参退化为指针。

    void func(int arr[]);   // 等价于 void func(int* arr);


四、指针与字符串

字符指针与字符数组

  •  字符指针(不可修改)

char* str = "hello";   // 字符串常量存储在只读数据段
// str[0] = 'H';       // 错误!运行时崩溃

  • 字符数组(可修改)

    char str[] = "hello";  // 栈区分配内存,可修改内容
    str[0] = 'H';         // 合法


五、多级指针与指针数组
  1. 多级指针

  • 定义:指向指针的指针。

int a = 10;
int* p = &a;
int** pp = &p;        // 二级指针
printf("%d", **pp);   // 输出10

2.指针数组

  • 定义:元素为指针的数组。

    int* arr[3];          // 存放3个int*类型指针


六、野指针与安全性

1.野指针成因

  • 未初始化的指针(如int* p;)。
  • 指向已释放内存的指针(如free(p)后未置空)。

  • 指针越界访问(如数组越界后继续操作)。

2.解决方案

  • 初始化int* p = NULL;

  • 释放后置空free(p); p = NULL;


七、常量指针与指针常量
  1. 常量指针(指向常量的指针)

  • 语法const int* p 或 int const* p
  • 特点:不能通过指针修改指向的值,但指针本身可指向其他地址。

    int a = 10;
    const int* p = &a;
    // *p = 20;         // 错误!
    p = &b;            // 合法

    2.指针常量(指针本身不可变)

    • 语法int* const p

    • 特点:指针的指向不可变,但指向的值可变。

      
      int a = 10;
      int* const p = &a;
      *p = 20;           // 合法
      // p = &b;         // 错误!

      3.双重常量

      • 语法const int* const p

      • 特点:指针指向和指向的值均不可变。


八、关键细节与注意事项
  • 指针运算限制

指针相减仅在指向同一数组时有效。

  • 动态内存分配

malloc返回void*,需强制类型转换:

int* p = (int*)malloc(sizeof(int) * 5);

  指针数组 vs 数组指针

  • 指针数组int* arr[5];(元素为指针)。

  • 数组指针int (*p)[5];(指向长度为5的数组)。


九、总结

  • 内存操作:通过地址直接读写内存。

  • 类型匹配:指针类型决定解引用和运算行为。

  • 安全性:避免野指针和内存泄漏。

  • 灵活应用:结合数组、字符串、多级指针实现复杂数据结构。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值