【问题标题】:how does following program work pointer manipulation [duplicate]以下程序如何工作指针操作[重复]
【发布时间】:2011-06-16 10:10:38
【问题描述】:

可能重复:
A c program from GATE paper

这是一个正在运行的程序

#include<stdio.h>
int main ()
{
char c[]="GATE2011";
char *p=c;
printf("%s",p+p[3]-p[1]);
}

输出是

2011

现在问题来了,我无法理解操作 p+p[3]-p[1] 那是什么意思?

我的理解是当我声明类似的东西时

char c[]="GATE2011"

那么c是指向字符串常量的指针,字符串以G开头。 在下一行*p=c; 指针 p 指向的地址与 c 指向的地址相同。 那么上面的算法是如何工作的呢?

【问题讨论】:

    标签: c pointers string


    【解决方案1】:

    p[3] 是“E”,p[1] 是“A”。 ASCII码A和E的差是4,所以p+p[3]-p[1]等价于p+4,又等价于&amp;p[4],所以指向char数组中的'2'字符。

    不过,任何发现在生产代码中写这种东西的人都会被枪杀。

    【讨论】:

      【解决方案2】:

      这是非常可怕的代码。 (p+p[3]-p[1]) 只是对p 添加和减去偏移量。 p[3](char)'E',在 ASCII 中是 69。 p[1](char)'A',在 ASCII 中是 65。所以代码相当于:

      (p+69-65)
      

      这是:

      (p+4)
      

      所以它只是将指针偏移 4 个元素,然后将其传递给 printf

      从技术上讲,这是未定义的行为。该表达式的第一部分 (p+69) 将指针偏移到数组末尾之外,这是 C 标准所不允许的。

      【讨论】:

      • Err ...谢天谢地标准允许 UB :-)
      【解决方案3】:

      那是

      pointer + char - char
      

      有一个指针值

      这是基本的指针运算...

      您可以添加一些括号(与语言指定的顺序不同但产生相同的值)以使其更易于理解

      pointer + (char - char)
      

      p + ('E' - 'A')
      

      p + 4
      

      这是

      &p[4]
      

      或字符串"2011"

      【讨论】:

      • 括号应该反过来,因为加法和减法是左结合的......
      • @pmg 谢谢,我正在努力改进我的 CI 阅读并重新阅读 Kernighnan Ritchie 但我无法解决上述问题是否可以参考任何我可以理解的书籍或链接这样的指针操作?
      • @Oli: 是的,你是对的......但是(p + 'E') 是UB :)
      • @pmg:不,不是!这很可怕,但它不是UB。
      • @Oli:想象一下原始的c 数组(9 个字节长)位于地址0xFFFFFFF0p + 'E' 跨越0x100000000 边界。
      【解决方案4】:

      简单的数学。

      p[3] = 'E',p[1] = 'A'

      整个是p+'E'-'A',即'p+4',它指向'2'。

      【讨论】:

        【解决方案5】:
        #include<stdio.h>
        
        int main ()
        {
        char c[]="GATE2011";   
        char *p=c;  // here you allocated address of character array c into pointer p
        
        printf("%s",p+p[3]-p[1]); 
        /*  p refers to the memory location of c[0],if you add any thing in p
            i.e p+1 it becomes next block of memory,in this case p+p[3]-p[1]
            takes 4 bytes forward and gives 2011 as output    */
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-11-23
          • 1970-01-01
          • 1970-01-01
          • 2016-02-03
          相关资源
          最近更新 更多