【问题标题】:Complex Pointer Statements in CC 中的复杂指针语句
【发布时间】:2017-05-03 18:02:26
【问题描述】:

我得到了这个代码:

#include <stdio.h>

int main(void)
{
    char *p[2][3] = {{"zyx","wvu","ts"},{"rqponm","lkjihgfe","dcba"}};

    printf("%c \n",***p);
    printf("%c \n",(*(*(p+1)+1))[6]);
    printf("%c \n",**(p[1]+2));
    printf("%c \n",*(*(p+1)+1)[6]);
    printf("%c \n",**p[1]);
    printf("%c \n",*(p[1][2]+2));
    return 0;
}

我运行了该代码,但我不明白为什么每行都打印出它打印的内容。另外,我知道第四个printf 不打印任何东西并且出错;应该是这样的。

【问题讨论】:

  • 那么它打印的是什么
  • @alk for exmaple ,在最后一次打印时,我似乎无法理解指针的运行方式。因为p 是一个指针,但是当我写 p[1][2] 时它会进入矩阵。它认为应该是 (*p)[1][2]。
  • 您应该解释您对来自 GCC 的警告(错误,因为我使用 -Werror 以便将警告视为错误)的理解:pmp11.c:10:19: error: ‘*((void *)&amp;p+80)’ is used uninitialized in this function [-Werror=uninitialized] 标识行中的第一个 * printf("%c\n",*(*(p+1)+1)[6]); .您还应该说明您认为应该打印什么以及为什么(以及这是否与您获得的实际输出一致)。对于 5 条语义正确的行,我得到输出 zfdrb — 你最好的理解是什么?这比许多松散相似的问题要棘手。

标签: c arrays pointers matrix


【解决方案1】:
char *p[2][3] = {{"zyx","wvu","ts"},{"rqponm","lkjihgfe","dcba"}}

将打印z,f,d,垃圾,rb

在底层我们有字符'z','y','x','w',......。 现在根据定义 char *p[][] ,我们制作了一个二维字符指针数组。即二维数组将只包含地址。

二维数组是如何实现的:它是一维数组,包含其他一维数组的地址。所以这里我们有p[2][3],即将创建一个包含两个元素的一维数组,这两个元素中的每一个都将包含另一个包含三个元素的一维数组的地址(基地址)。 由于我们将这个二维数组创建为字符指针数组,因此这 3 个元素将包含保存我们字符值的其他一维数组(大小未定义)的地址。 这是创建的所有数组和存储在这些数组中的值的图像:

待打印:

1)。 ***p*(*(*p))

  • 这里 p 包含两个元素的一维数组 (P) 的基地址。 *p 将提取存储在该基地址的值,即“G 的地址”。

  • *(*p)”将是存储在“G 的地址”所指向的位置的值,该地址是数组 G 的基地址,即“A 的地址”

  • *(*(*p)) 将是存储在由 “A 的地址”,即字符“z”。
  • 因此***p 将返回“z”。

2)。 (*(*(p+1)+1))[6]

  • 因为 p 包含一维数组的基地址,即 一维数组 P 的第一个元素。
  • p+1 将是 p 的下一个地址,即第二个地址 一维数组 P 的元素。
  • *(p+1) 将是存储在“p+1”中的值,即“H 的地址”,其中包含 H 数组的基地址(地址如果是 H)。
  • *(p+1)+1 将是下一个地址,即 H 的第二个元素的地址。
  • *(*(p+1)+1) 将是存储在 H 的第二个元素的值,即 E 的地址(E 数组的基地址。
  • *(*(p+1)+1)[6] 将是该数组中的第 7 个术语,即“f”。

3)。 **(p[1]+2):

  • 这里p[1]指向p指向的数组的第二个值,即 是“H 的基地址”(指向 H 中的第一个元素 数组)。
  • p[1]+2 将是“H 的基地址”的第二个下一个值(或 地址指向 H 数组中的第一个元素),即 ‘H 数组中第三个元素的地址’。
  • *(p[1] + 2) 将是“H 数组中第三个元素的地址”的值点,这将是“H 的第三个元素的值” 是“F 的基地址”。
  • **(p[1] + 2) 将是存储在“F 的基地址”的值,即“d”。

4)。 *(*(p+1)+1)[6])

  • 如上例2计算,‘*(p+1)+1’包含‘地址 H'的第二个元素。现在这里“*(p+1)+1)[6]”表示旁边的第 7 个值 它会指向一些垃圾地址。和'((p+1)+1)[6])' 将是存储在该垃圾地址中的值,可以是任何 垃圾值。
  • 注意这里的区别:它不是询问 H 的第 2 个元素的值旁边的第 7 个值,(如果是,答案将是 ‘f’) 而是询问旁边的第 7 个值 H 的第二个元素的地址。

5)。 **p[1]

  • 这里p[1] 将是指向数组的第二个元素的值 ‘p’是‘H的基地址’。
  • *p[1] 将是“H 的基地址”所指向的值,即“D 的基地址”。
  • **p[1] 将是“D 的基地址”指向的值,即“r”。

6)。 *(p[1][2]+2):

  • 这里p[1][2] 将是第二行(H 数组)第三个元素的值 这是'F的基地址,进一步是'd'的地址 字符)。

  • p[1][2]+2’将是‘d地址’的第二个下一个值 是‘b的地址’

  • *( p[1][2]+2) 将是“b 地址”处的值,即“b”。

【讨论】:

  • 非常感谢您的解释。你真的帮了我很多。你成功地解释了这个话题,而且非常容易理解。
猜你喜欢
  • 1970-01-01
  • 2021-04-09
  • 2015-12-05
  • 1970-01-01
  • 2013-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多