试图理解指针算术

时间:2014-02-26 19:55:19

标签: c pointers

#include <stdio.h>

const char *c = "hello";
const char *cp = (unsigned char*)&c;
const char *cpp = (unsigned char*)&cp;



int main (){

        printf("PTR    c      %p \n",c);
        printf("PTR    cp     %p \n",cp);
        printf("PTR    cpp    %p \n",cpp);

        printf("\n\n");

        printf("CONTENTS cp   0x%x \n",*(unsigned int*)cp);
        printf("CONTENTS cpp  0x%x \n",*(unsigned int*)cpp);

        printf(" \n\n Demonstrating pointer arithmetic. \n\n");

        printf("PTR     c     %p \n ",c);
        printf("PTR    (c+1)  %p \n ",(c+1));


        printf("PTR     c     %p \n ",(unsigned int*)c);
        printf("PTR    (c+1)  %p \n ",(unsigned int*)(c+1));


        printf("PTR     c     %p \n ",(unsigned long*)c);
        printf("PTR    (c+1)  %p \n ",(unsigned long*)(c+1));

        return 0;
}

程序的输出如下:

PTR    c      0x4007a0 
PTR    cp     0x601028 
PTR    cpp    0x601030 


CONTENTS cp   0x4007a0 
CONTENTS cpp  0x601028 


Demonstrating pointer arithmetic. 

 PTR     c     0x4007a0 
 PTR    (c+1)  0x4007a1 
 PTR     c     0x4007a0 
 PTR    (c+1)  0x4007a1 
 PTR     c     0x4007a0 
 PTR    (c+1)  0x4007a1 

如果你看一下演示指针算法的部分,我希望得到以下结果

1)前两行打印'char指针'一个地址分开,因此差异应为'1' - 这就是我们得到的

2)接下来的两行打印'int pointers'一个地址分开,因此差异应该是'4' - 什么错了?

3)接下来的两行打印'长指针'一个地址分开,因此差异应该是'4/8' - 什么错了?

2 个答案:

答案 0 :(得分:4)

在将值转换为所需指针

之前,您正在递增值

要将'c'解释为另一个指针,你应该做

printf("PTR    (c+1)  %p \n ",(unsigned int*)c+1);

否则括号将优先考虑之前的增量。

如果没有这些括号,则铸造的优先级高于添加,如下所示

item = (char*)heap + offset;

相当于

item = ((char *)heap) + offset

参考:优先表C type casts and addition precedence

答案 1 :(得分:0)

在添加const值之前,应该将var转换为正确的指针。另外我建议使用未加工的long long来确定64位宽度:

    printf("PTR     c     %p \n ",c);
    printf("PTR    (c+1)  %p \n ",(c+1));


    printf("PTR     c     %p \n ",(unsigned int*)c);
    printf("PTR    (c+1)  %p \n ",((unsigned int*)c+1));


    printf("PTR     c     %p \n ",(unsigned long long*)c);
    printf("PTR    (c+1)  %p \n ",((unsigned long long*)c+1));

结果是:

PTR     c     0x80485f0
 PTR    (c+1)  0x80485f1
 PTR     c     0x80485f0
 PTR    (c+1)  0x80485f4
 PTR     c     0x80485f0
 PTR    (c+1)  0x80485f8