C语言:指针题型总结

题型1:二维数组初始化 + 逗号表达式陷阱(最高频坑!)

代码:

int a32 = { (0, 1), (2, 3), (4, 5) };

int* p;

p = a0;//*(a+0) 本来串的是第一行元素, a会退化成首元素地址

printf("%d", p0);

✅ 考点: () 里面是逗号运算符,不是行分组!逗号表达式只保留最右侧值

(0,1) → 结果是 1 ; (2,3) → 3 ; (4,5) → 5

内存填充: a32 = {1,3,5,0,0,0} //剩余的填充0进去

输出: 1

❌ 误区:误以为 (0,1) 是一行两个元素(只有 {} 才是分组)

int a32={{0,1},{2,3},{4,5}};这个才是分组

题型2:数组指针 + 指针减法(求元素个数,不是字节差)

int a55;

int (*p)5; // 数组指针:一步跨过一整行5个int

p = a;

printf("%d, %d", &p42 - &a42, &p42 - &a22);

答案:0 10

每一行有5个元素,然后它跳过了两行,一共10个元素。

✅ 考点:

  1. 同类型指针相减,结果 = 中间相隔元素数量,不是字节
  2. int ()5 步长: 5sizeof(int) ; int* 步长:1个int

重点:小地址 - 大地址 → 负数

题型3:二维数组 + &aa+1 / *aa+1 区分(必考)

c

int aa25 = {1,2,3,4,5,6,7,8,9,10};

int* ptr1 = (int*)(&aa + 1);

int* ptr2 = (int*)(*(aa + 1));

printf("%d,%d", *(ptr1 - 1), *(ptr2 - 1));

✅ 考点拆分:

  • &aa :整个二维数组的地址,类型 int (*)25 ; &aa+1 直接跳过整个二维数组
  • aa 是数组名, aa+1 :数组指针,跳过一行(5个int)
    输出: 10,5

题型4:三级指针 char*** 多级指针链式解引用(你那个ENTER/NEW题)

c

char* c\[\] = { "ENTER","NEW","POINT","FIRST" };

char** cp\[\] = { c + 3, c + 2, c + 1, c };

char*** cpp = cp;

printf("%s\n", ***cpp);

printf("%s\n", * ++cpp + 3);

printf("%s\n", *cpp-2 + 3);

printf("%s\n", cpp-1-1 + 1);

先 画图:

c enter new point first

cp first point new enter

cpp =cp0=c3 printf("frist");

*(++cpp)= cp1 =c2 point ->3 printf("nt");

cpp-2 =cp-1=c3 frist->printf("st");
cpp-1-1 = ((cpp-1)-1)+1=
(c+3-1)+1=oint

✅ 考点:

  1. 运算符优先级: ++/-- > * > +
  2. cppi 等价 *(cpp+i) ;多层解引用逐层降一级指针
  3. char* + n :在字符串内部向后跳字母(步长1字节)
  4. char** + n :跳到下一个字符串首地址(步长是地址宽度)

核心口诀:解引用降一层;什么类型指针,+1就跳这个类型的大小

题型5:char*指针数组,指针自增

c

char* a\[\] = {"work","at","alibaba"};

char** pa = a;

pa++;

printf("%s\n", *pa);

✅ 考点: pa 是 char** ,pa++ 跳过一个 char* ,指向第二个字符串

输出: at

题型6:结构体指针 + 指针步长(强制转换指针,步长由类型决定)

c

struct Test

{

int Num;

char* pcName;

short sDate;

char cha2;

short sBa4;

}p;
// 题目给定:结构体大小20字节
p = (struct Test
)0x100000;

printf("%p\n", p + 0x1);

printf("%p\n", (unsigned long)p + 0x1);

printf("%p\n", (unsigned int*)p + 0x1);

✅ 考点(超级重要):

  • p + 1 :结构体指针,+1 跳整个结构体大小20字节,转16进制后是014
  • 转成普通整数 unsigned long 再加1:只+1个字节
  • unsigned int* 指针+1:跳4字节

本质:指针加法的步长,完全由指针本身的类型决定,和原始地址无关

配套通用考点笔记

  1. ✅ 数组名什么时候不退化: sizeof(数组名) 、 &数组名 ;其余全部退化成首元素指针
  2. ✅ 指针减法硬性规则:必须指向同一块连续内存,结果是元素个数,不是字节;小地址减大地址为负
  3. ✅ 逗号表达式: (a,b,c) ,顺序执行a→b→c,整个表达式的值 = 最右边c的值;只有 () 里逗号才是逗号运算符, {} 里面逗号只是分隔符!(本题最大坑)
  4. ✅ 多级指针分层:
  • char* → 存字符串首地址,+1跳1个字符
  • char** → 存 char* 的地址,+1跳一个字符串指针
  • char*** → 存 char** 的地址,+1跳一个char**
  1. ✅ \[\] 等价: pi == *(p+i) ,正负下标都合法(只要内存有效,考试随便考负数下标)

刷题顺序建议

  1. 先搞定【逗号表达式二维数组初始化】(最容易掉坑)
  2. 然后 &aa+1 vs aa+1 二维数组行指针题(aa为二维数组,实际为int()\[\],+1就直接跳到下一行了)
  3. 结构体指针步长(很多人分不清强制转换之后步长变了)
  4. 三级指针链式解引用(ENTER那道,运算符优先级地狱题)
  5. 指针减法+补码(负数地址打印)
相关推荐
饮水桶_T3 小时前
JAVA IO流笔记
开发语言·数据结构·算法
Felven6 小时前
C. Brr Brrr Patapim
c语言·开发语言
路溪非溪7 小时前
python标准库使用总结
开发语言·python
Zwawa8 小时前
嵌入式OLED表驱动菜单:用一张表、一个栈和一个窗口重写表驱动菜单
c语言·单片机·嵌入式
SomeOtherTime9 小时前
Rust 面向对象介绍(AI回答)
开发语言·python·rust
zh_xuan9 小时前
kotlin常见面试题
开发语言·kotlin·面试题
草莓熊Lotso11 小时前
【C++ 基于微服务的即时通讯系统】文件存储子服务实战:UUID生成、文件IO封装与全接口单元测试
开发语言·网络·数据库·c++·微服务·架构·单元测试
huaqianzkh12 小时前
WinForm C#:循环修改控件UI闪烁卡顿?SuspendLayout / ResumeLayout 与 BeginUpdate 优化
开发语言·ui·c#
沐晓时光1 天前
C语言入门,内存函数知识讲解
c语言·开发语言
Zwawa1 天前
C语言函数指针与宏实战:从回调、表驱动菜单到X-Macro,讲透嵌入式代码解耦
c语言·单片机·嵌入式