(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,所以这里初始状态就是cpp[1])
  • *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"

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

相关推荐
_Coin_-1 分钟前
代码训练营DAY53 第十一章:图论part04
算法·图论
এ᭄画画的北北15 分钟前
力扣-208.实现Trie(前缀树)
算法·leetcode
欲儿22 分钟前
Kotlin Native调用C curl
c语言·开发语言·kotlin·语言调用
草莓熊Lotso22 分钟前
【数据结构初阶】--排序(四):归并排序
c语言·数据结构·经验分享·其他·算法·排序算法
努力努力再努力wz25 分钟前
【Linux内核系列】:信号(上)
java·linux·运维·服务器·c语言·开发语言·c++
啊吧怪不啊吧32 分钟前
C++之vector类的代码及其逻辑详解 (下)
开发语言·数据结构·c++
User_芊芊君子40 分钟前
【Java String】类深度解析:从原理到高效使用技巧
java·开发语言
fbbqt1 小时前
Go语言 单元测试
开发语言·golang·单元测试
xiaobin889991 小时前
IDEA 2025下载安装教程【超详细】保姆级图文教程(附安装包)
java·ide·其他·intellij-idea