【问题标题】:C Issue with understanding an array of pointers理解指针数组的C问题
【发布时间】:2017-09-15 12:37:36
【问题描述】:

我已经对此进行了一些谷歌搜索。问题是我只是找到解释 char 指针或 char 指针指针的作用以及 char 指针数组是什么。 实际上我的程序正在运行。只是当我闭上眼睛,接受世界上的一切,一切都很好,但我不断有一些问题在我脑海中闪现,我无法回答。长话短说,我希望没有人会因为我的问题而杀了我,因为这对你们中的一些人来说似乎微不足道,显然对我来说不是! 所以她我们走了:

char *pc;
char **ppc;
char *string[2] = {"Hello","World",};
ppc = string;
pc = *ppc;


printf("%p\n",ppc);
printf("%p\n",&pc);
printf("%p\n",*ppc);   
printf("%p\n",pc);
printf("%p\n",&string[0]);  //or &string
printf("%c\n", **ppc);
printf("%s", *ppc);

运行后,我期望 *ppc 是第一个字符串的地址(第一个字符串的第一个字符),但事实并非如此,我还期望 &pc 和 ppc 之间存在某种关系,但事实并非如此。 ppc 是一个指向指针的指针,但我真的不知道在到达字符串的第一个元素之前 ppc 指向的指针是什么? 如果这一切听起来很愚蠢,我很抱歉,但我真的很想理解它。 任何帮助将不胜感激!

【问题讨论】:

  • *ppc 是第一个字符串的地址 - 查看你最后一个 printf 的输出
  • 相关:stackoverflow.com/questions/4832082/…。如果您稍微搜索一下,可以找到很多几乎重复的内容。
  • 另外,%p 需要一个 pointer-to-void,因此您必须将每个参数强制转换为 (void*)。此外,&string[0]&string 指向相同的地址,但不同的东西。一个说:“那是字符串先生”,另一个说“那是字符串先生的头”。
  • 所有%p 行都会调用未定义的行为。仔细阅读手册页并使用正确的类型。

标签: c arrays string pointers memory


【解决方案1】:

您的代码调用未定义行为,因为 %p 排除了指向 void 的指针,因此 所有您的打印语句必须将其参数转换为 void*,例如 printf("%p\n", (void*) ppc);。 p>

修复此问题,现在绘制指针,例如:

我期待*ppc 是第一个字符串的地址(第一个字符串的第一个字符),但不是

是的!

检查printf("%p\n", (void*) ppc);printf("%p\n", (void*) &string[0]);——它们产生相同的输出。

我也期待 &pcppc 之间的关系

  • ppc 具有第一个字符串(“Hello”)的地址。
  • *ppc 具有字符串的第一个字符 ('H') 的地址。
  • pc 具有字符串第一个字符 ('H') 的地址。
  • &pc 的地址为pc

所以你的期望是错误的,pc*ppc 应该有相同的地址,而不是 &pc


进一步解释:

string 是一个char 指针数组。 char **ppc; 是一个指向 char 的双指针。

这里:

ppc = string;

您将ppc 设置为指向string 的第一个元素的地址。

这个:

pc = *ppc;

使pc 指向ppc 实际指向的位置,即string 的第一个元素,即string[0]

【讨论】:

    【解决方案2】:

    图片等chars 为黄色,char* 橙色,char** 蓝色

    字母“e”可以通过pc[1]string[0][1]*ppc[1]等方式获取。

    【讨论】:

    • 我非常喜欢你的图片,颜色比我的好,很好的答案!我也发了一篇,需要的可以看一下! =)
    • 有一个重要的细节:pc 是包含地址的“盒子”的名称,字符串是 地址 的名称,其中有 2 个连续的盒子。 C 所谓的“数组”在历史上是围绕指针(常量指针,除非用作参数)而不是真正的“变量”。
    • @gsamaras 我在 Linux 下使用“dia”
    【解决方案3】:

    变量string 是一个指向字符的数组,显然它必须去某个地方,即实际的数组。

    当你这样做时

    ppc = string;
    

    你把string的第一个元素的地址复制到ppc,然后

    pc = *ppc;
    

    复制它的内容,即string[0]的值。

    【讨论】:

      【解决方案4】:

      ppc = string;之后,ppc指向数组string的第一个字符串,即指向字符串"Hello"(注意数组string在这种情况下会衰减为指向其第一个元素的指针) .

      *ppc 是指向数组"Hello" 的第一个字符的指针。
      pc = *ppc; 使pc 指向同一字符串“Hello”的同一字符`。

      这使得:
      ppc 将具有第一个字符串的地址
      *ppc 将具有第一个字符串的第一个字符的地址.

      【讨论】:

      • 那么问题来了,它们是一样的吗?
      • 没有。他们不是。 ppc*ppc 虽然具有相同的地址值,但它们是不同的。
      【解决方案5】:

      | | 内部是值,* * 内部是地址。

      | H | E | L | L | O |
      *100*
      
      | W | O | R | L | D |
      *200*
      
      | 100 | 200 |   //string
       *300*  
      

      现在ppc = string,所以

       ppc=>
             | 300 |
              *400*
      

      现在是pc = *ppc,所以pc = *300100

       pc=>
            | 100 |
             *500*
      

      现在,如果您执行printf("%s", pc);,您将在 100 处获得字符串存储,即HELLO

      【讨论】:

      • 不应该ppc=> | 100 |ppc=> | 300 |
      • 当您执行int a = b 时,您希望a 具有b 的值,因此ppc 指向string 指向的内容。
      • 也许我对你的ppc=> 表示法感到困惑。它的意思是“这是ppc 的值”,还是“这是ppc 指向的值”?
      • 我知道这是误导。ppc=> 没有任何意义。它只是说,你想看看ppc 在内存中的样子吗?继续往下看。
      • 对我来说,这似乎表明ppc 存储在地址 400 并包含地址 100。但它应该包含地址 300,因为这是string 的第一个元素的地址在你的图表中。
      猜你喜欢
      • 1970-01-01
      • 2015-02-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-02-06
      • 2013-03-02
      • 2011-05-24
      • 2018-03-10
      相关资源
      最近更新 更多