(C语言)指针运算 习题练习1.2(压轴难题)

在上一张已经练习了三道习题,小试牛刀了,那么在本章在来几题,练练手。(习题三是压轴难题)

习题一

cs 复制代码
int main()
{
    int aa[2][5] = { 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));

    return 0;
}

这里借助画图也可以更好的理解。

&aa是整个数组的地址,那么加一就是跳过整个数组,指向数组末尾之后的位置。强制转换为int*后,ptr1指向数组末尾后的地址。

看图。

欧克,那么ptr1 - 1回退一个int的位置,指向数组最后一个元素10。那么ptr1-1就指向10

所以第一个输出10.

第二个:1. aa在表达式中退化为int (*)[5](指向第一行的指针)。

2. aa + 1指向第二行的首地址(即元素6的地址)。

3.*****(aa + 1)解引用得到第二行的数组,退化为int*指向6

4.****ptr2 - 1回退一个int的位置,指向第一行的最后一个元素5,故*(ptr2 - 1)5。

所以本题的答案为 10,5

习题二

cs 复制代码
#include <stdio.h>
int main()
{
    char* a[] = { "work","at","alibaba" };
    char** pa = a;
    pa++;
    printf("%s\n", *pa);
    return 0;
}

数组名 a 在表达式中退化为 char** 类型(指向第一个元素 a[0] 的指针)。

cs 复制代码
char** pa = a; // pa 指向 a[0]

pa 的类型是 char**,指向 a 的第一个元素 a[0](即字符串 "work" 的地址)。

cs 复制代码
pa++; // pa 移动到 a[1]
  • pachar** 类型,指向 char* 元素。

  • 执行后,pa 指向数组的第二个元素 a[1](即字符串 "at" 的地址)。

cs 复制代码
printf("%s\n", *pa); // 输出 a[1] 指向的字符串
  • *pa 解引用 pa,得到 a[1] 的值(即字符串 "at" 的首地址)。

  • %s 格式输出时,会打印从该地址开始的字符串 "at"

  • 答案为 at

习题三

注意:此题为压轴题,请认真分析,一定一定要画图。
cs 复制代码
#include <stdio.h>

int main()
{
    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);

    return 0;
}

答案:

POINT
ER
ST
EW

做本题首先要画图,上图。

这是在运算前的必要流程,由此图我们可以相对容易理解。

那么接下来 SHOW TIME

一:

cs 复制代码
printf("%s\n",**++cpp);

这步先找突破口,cpp,

步骤如下:

  • ++cpp:将 cpp 增加1,使其指向 cp[1]
  • *cpp:解引用 cpp,得到 cp[1],即 c + 2
  • **cpp:解引用 *cpp,得到 *(c + 2),即 "POINT"

所以结果输出 POINT

二:

cs 复制代码
   printf("%s\n", *-- * ++cpp + 3);

做这道题之前可以将本题简化一下,简化后为 * --*++cpp +3

因此,第二个 printf 输出 "ER"

  • ++cpp:将 cpp 增加1,使其指向 cp[2]。(**PS:**在上一步已经将进行一次++cpp,所以这里初始状态就是cpp1
  • *cpp:解引用 cpp,得到 cp[2],即 c + 1
  • --*cpp:将 *cpp 减少1,使其指向 c,即 "ENTER"
  • *--*cpp + 3:解引用 --*cpp,得到 "ENTER",然后加上3,指向 "ENTER" 的第4个字符,即 "ER"

三:

cs 复制代码
printf("%s\n", *cpp[-2] + 3);

这里也可以进行一步简化,cpp-2:相当于 *(cpp-2):

  • cpp[-2]:由于 cpp 当前指向 cp[2],所以 cpp[-2] 指向 cp[0]
  • *cpp[-2]:解引用 cpp[-2],得到 cp[0],即 c + 3
  • *cpp[-2] + 3:解引用 *cpp[-2],得到 "FIRST",然后加上3,指向 "FIRST" 的第4个字符,即 "ST"

因此,第三个 printf 输出 "ST"

cs 复制代码
    printf("%s\n", cpp[-1][-1] + 1);
  • cpp[-1]:由于 cpp 当前指向 cp[2],所以 cpp[-1] 指向 cp[1]
  • cpp[-1][-1]:解引用 cpp[-1],得到 cp[1],即 c + 2,然后解引用 -1,得到 *(c + 1),即 "NEW"
  • cpp[-1][-1] + 1:解引用 cpp[-1][-1],得到 "NEW",然后加上1,指向 "NEW" 的第2个字符,即 "EW"

因此,第四个 printf 输出 "EW"

欧克 指针运算的习题就到这里了,大家可以在独立运算一下,更好的理解。

相关推荐
土狗TuGou5 分钟前
SQL内功笔记 · 第6篇:窗口函数的使用ROW_NUMBER等
java·数据库·后端·sql·mysql
啄缘之间5 分钟前
8.【学习】工业级详细接口约束&覆盖率
开发语言·笔记·学习·uvm·sv
Chase_______7 分钟前
【Java基础核心知识点全解·09】Java 内存布局与垃圾回收详解:栈、堆、栈帧、GC Roots 与对象回收
java·开发语言
武子康10 分钟前
Java-11 深入浅出 MyBatis 一级缓存详解:从原理到失效场景 Executor
java·后端
寻道码路24 分钟前
LangChain4j Java AI 应用开发实战(十):Embedding 模型与文本分类 - 语义向量化
java·人工智能·ai·embedding
江南十四行24 分钟前
并发编程(四)
开发语言·python
葱卤山猪27 分钟前
C++17 联合体
开发语言·c++
折哥的程序人生 · 物流技术专研27 分钟前
Java 23 种设计模式:从踩坑到精通 | 抽象工厂 —— 支付/收款如何成套创建?跨平台 UI 如何一键换肤?
java·开发语言·后端·设计模式
方也_arkling30 分钟前
【Java-Day11】抽象类和抽象方法
java·开发语言
XS03010634 分钟前
并发编程 七
java