初级指针(一)

一、指针到底是什么?—— 内存的 “门牌号”

核心概念

  • 内存:计算机中存储数据的空间,像一个超大的 “抽屉柜”,每个抽屉(内存单元)都有唯一编号(地址)。
  • 指针:就是这个 “抽屉” 的编号(地址),通过编号能精准找到对应内存单元。
  • 指针变量:专门用来存放地址的变量,相当于 “门牌号登记本”。

一句话总结

地址 = 指针指针变量 = 存储指针的变量

举个栗子

int a = 10;         // 定义变量a,在内存中占4个字节(int类型)
int* pa = &a;       // pa是指针变量,存储a的首字节地址(&a取a的地址)
*pa = 20;           // 通过指针pa找到a的内存单元,修改值为20(*是解引用操作符)

  • pa:指针变量(存放地址的变量),简称 “指针”。
  • *pa:通过指针访问内存中的数据,类似 “按门牌号打开抽屉”。

指针的大小

  • 32 位平台:4 字节(32 位地址总线,可寻址 2^32 个地址)。
  • 64 位平台:8 字节(64 位地址总线,可寻址 2^64 个地址)。
    关键:指针大小仅由平台决定,与指向的数据类型无关!

二、指针类型的意义 —— 为什么需要不同类型的指针?

指针类型 = 操作权限 + 移动步长

指针类型(如int*char*)决定了两件大事:

1. 解引用权限:能操作多少字节的数据?

  • 例子:用不同类型指针修改数据

    int a = 0x11223344;  // a的内存数据(4字节):0x11 0x22 0x33 0x44(小端模式)
    int* p1 = &a;        // int*指针,解引用时操作4字节
    char* p2 = &a;       // char*指针,解引用时操作1字节
    
    *p1 = 0x00000000;    // 整个a被赋值为0(修改4字节)
    *p2 = 0x55;         // 仅修改a的第一个字节为0x55(a变为0x55223344)
    

    ✅ 结论int*能一次操作 4 字节,char*只能操作 1 字节,类型决定解引用的 “权限范围”。

2. 指针步长:指针 + 1 能走多远?

  • 例子:指针移动时的地址变化

    int arr[3] = {1, 2, 3};
    int* p_int = arr;       // p_int指向arr[0],地址假设为0x1000
    char* p_char = (char*)arr; // p_char指向arr[0],地址0x1000
    
    p_int++;                // 地址变为0x1004(int占4字节,+1走4字节)
    p_char++;               // 地址变为0x1001(char占1字节,+1走1字节)
    
    printf("int指针地址:%p\n", (void*)p_int); // 输出:0x1004(指向arr[1])
    printf("char指针地址:%p\n", (void*)p_char); // 输出:0x1001(指向arr[0]的第二个字节)
    

    ✅ 结论:指针 + 1 的步长等于指向类型的大小(int*+1 跳 4 字节,char*+1 跳 1 字节)。

新手必看!指针使用的 3 大易错点

1. 指针未初始化 —— 指向 “未知区域”

int* p;       // 危险!p未初始化,是野指针(指向随机地址)
*p = 10;      // 解引用野指针,可能导致程序崩溃

✅ 正确做法:指针定义时要么指向合法地址,要么置空:

int a = 10;
int* p = &a;   // 指向合法变量
// 或
int* p = NULL; // 置空指针(NULL表示空地址)

2. 解引用权限错误 —— 小权限指针改大区域

char a = 'A';  // a占1字节
int* p = &a;   // 危险!用int*指针指向char变量
*p = 0x1234;   // 试图修改4字节,但a只占1字节,导致内存越界

✅ 原则:指针类型要与指向的数据类型匹配,避免越权操作。

3. 指针大小误区 —— 误以为类型影响大小

printf("int*大小:%d\n", sizeof(int*));  // 输出:4(32位平台)
printf("char*大小:%d\n", sizeof(char*)); // 输出:4(32位平台)

✅ 真相:所有指针变量的大小只由平台决定(32 位 4 字节,64 位 8 字节),与类型无关!

代码示例:指针操作全流程

#include 

int main() {
    // 1. 定义变量和指针
    int num = 100;          // 普通变量
    int* ptr = #        // 指针指向num的地址

    // 2. 通过指针修改值
    printf("修改前:%d\n", num);  // 输出:100
    *ptr = 200;               // 解引用指针,修改num的值
    printf("修改后:%d\n", num);  // 输出:200

    // 3. 指针大小验证
    printf("指针大小(32位平台):%d字节\n", sizeof(ptr)); // 输出:4

    // 4. 指针步长演示
    int arr[2] = {1, 2};
    int* p_arr = arr;
    printf("p_arr+1地址:%p\n", (void*)(p_arr + 1)); // 地址增加4字节(int大小)

    return 0;
}

总结:指针核心知识点速查表

概念 说明
指针 内存单元的地址(相当于 “门牌号”)
指针变量 存储地址的变量,大小由平台决定(32 位 4 字节,64 位 8 字节)
解引用 *指针 表示通过地址访问数据,权限由指针类型决定(如int*操作 4 字节)
指针步长 指针 + 1 的跨度等于指向类型的大小(char*+1 跳 1 字节,int*+1 跳 4 字节)
易错点 未初始化指针(野指针)、类型不匹配、误解指针大小

给新手的 3 个学习建议

  1. 画图理解内存:把变量、指针、内存地址画成抽屉和门牌号,直观理解指针指向关系。

  2. 多写测试代码:通过printf("%p", &变量)打印地址,观察指针移动时的变化规律。

  3. 牢记权限原则:指针类型决定能操作的内存范围,避免越界操作导致程序崩溃。

掌握指针,就像掌握了直接操作内存的 “钥匙”,是 C 语言进阶的关键!动手试试代码,你会发现指针其实没那么难~ ️

你可能感兴趣的:(C语言基础,数据结构,c语言,c++,visual,studio,算法)