6、C 语言指针初阶知识点总结

发布于:2025-08-15 ⋅ 阅读:(13) ⋅ 点赞:(0)

指针的基础概念、特殊指针类型、指针运算等方面,指针初阶的核心知识点,补充实用注意事项

C 语言指针初阶核心知识点总结

一、指针入门

1. 基础概念:内存与地址

内存地址与字节
  • 字节(byte):内存的基本单位,1 字节 = 8 位(bit),可表示 0~255 的数值(二进制00000000~11111111)。
  • 地址:系统为每个字节分配的唯一编号(如0x00000000~0xFFFFFFFF),用于区分不同内存位置。
  • 地址特性:地址 + 1 表示偏移 1 个字节(即下一个字节的编号),与数据类型无关。
基地址
  • 单字节数据:地址就是其自身字节的编号(如char ch = 'a'&ch即为该字节的地址)。
  • 多字节数据:由多个连续字节组成,其地址为所有字节中最小的编号(称为基地址)。

示例:int num = 100(4 字节),基地址为第一个字节的编号(如0x0A33FF04),后续字节地址依次为0x0A33FF050x0A33FF060x0A33FF07

取址符(&)
  • 功能:获取变量所占用内存的基地址。

示例:int num = 100; printf("%p", &num); 输出num的基地址。

  • 特性
    • 无论变量类型(int、char 等),地址的尺寸固定(32 位系统 4 字节,64 位系统 8 字节)。
    • 地址的逻辑含义由指向的数据类型决定(如int*char*地址数值可能相同,但指向的内存尺寸不同)。

2. 指针的定义与本质

指针的双重含义
  • 地址:变量的内存地址(如&num是指向num的指针)。
  • 指针变量:存储地址的变量(简称为 “指针”),定义语法为类型* 指针名(如int* p表示p是存储 int 型变量地址的指针)。
指针的初始化
  • 核心原则:指针必须指向合法内存,否则会成为野指针(危险)。
  • 初始化方式
    1. 指向已定义的变量:int num = 100; int* p = #p存储num的地址)。
    2. 指向空地址(安全的初始值):int* p = NULL;NULL是定义为(void*)0的宏,代表零地址的保留区)。
指针的解引用(*)
  • 功能:通过指针访问其指向的内存内容(“降级操作”,从地址获取值)。

示例:int num = 100; int* p = # *p = 200;(通过p修改num的值为 200)。

  • 注意*在定义时表示 “指针类型”(如int* p),在使用时表示 “解引用”(如*p = 200)。

二、特殊指针

1. 野指针

  • 定义:指向未知或非法内存的指针(未初始化、指向已回收内存或越界)。
  • 危害
    • 访问野指针可能导致段错误(Segmentation fault)
    • 可能修改系统关键数据,导致程序崩溃或系统异常。
  • 产生原因
    1. 指针未初始化:int* p; *p = 100;p乱指)。
    2. 指向已释放的内存:char* p = malloc(10); free(p); *p = 'a';p指向的内存已被回收)。
    3. 指针越界:char buf[5] = "abc"; char* p = buf; *(p+10) = 'd';(访问超出buf范围的内存)。
  • 预防措施
    • 定义时立即初始化(如int* p = NULL;)。
    • 释放内存后将指针置为NULL(如free(p); p = NULL;)。
    • 操作数组时检查边界(如用宏计算长度#define LEN sizeof(arr)/sizeof(arr[0]))。

2. 空指针(NULL)

  • 定义:指向零地址(0x00000000)的指针,该地址是系统保留区(不可访问)。
  • 作用:作为指针的安全初始值,避免野指针(如int* p = NULL;表示p暂时无有效指向)。
  • 注意:访问NULL会触发段错误(提示指针未正确初始化),便于调试。

三、指针运算

1. 指针的大小

  • 特性:指针的尺寸仅由系统位数决定,与指向的数据类型无关。
    • 32 位系统:所有指针均为 4 字节。
    • 64 位系统:所有指针均为 8 字节。
  • 示例

char* p1; int* p2; double* p3;

printf("%lu, %lu, %lu", sizeof(p1), sizeof(p2), sizeof(p3));

// 64位系统输出:8, 8, 8

2. 指针的加减运算

  • 本质:指针的偏移量由指向的数据类型决定(“按类型尺寸移动”)。
  • 规则
    • 指针 + 1:地址增加 “指向类型的字节数”(如int* pp+1表示地址 + 4 字节)。
    • 指针 - 1:地址减少 “指向类型的字节数”(如char* pp-1表示地址 - 1 字节)。
  • 示例

int num = 100; int* p = #

printf("p: %p, p+1: %p", p, p+1);

// 输出地址相差4字节(如0x7ffd12345678 和 0x7ffd1234567c)

3. 指针运算的应用

  • 遍历数组:通过指针加减访问数组元素(数组名本质是首元素的指针)。

int arr[3] = {1,2,3}; int* p = arr;

for (int i=0; i<3; i++) {

    printf("%d ", *(p+i)); // 等价于 arr[i],输出1 2 3

}

四、核心注意事项

  1. 指针与数组的关系:数组名是首元素的指针(常量指针,不可修改),如int arr[5]; int* p = arr;parr均指向arr[0])。
  2. 避免指针越界:访问数组或动态内存时,严格限制指针范围在申请的内存内(如for (int i=0; i<LEN; i++))。
  3. 指针初始化检查:使用指针前判断是否为NULL(如if (p != NULL) { *p = 100; })。
  4. 动态内存管理malloc申请的内存需用free释放,释放后立即置为NULL(避免野指针)。

总结

指针是 C 语言的核心,其本质是 “存储地址的变量”,通过地址间接访问内存。掌握指针需理解:地址与指针变量的区别、初始化的重要性、解引用的作用,以及野指针的危害与预防。指针运算的关键是 “按类型偏移”,这是数组遍历、动态内存操作的基础。正确使用指针能提升程序效率,但需严格遵循安全规则,避免内存错误。


网站公告

今日签到

点亮在社区的每一天
去签到