【问题标题】:Pointer data types in CC中的指针数据类型
【发布时间】:2012-02-11 10:38:52
【问题描述】:

如果我有这样的指针:

int* ptr;

我愿意:

printf("%#x\n%#x\n%#x\n", ptr, ptr+1, ptr+2);

我得到的输出为:

some address
some address + 4bytes
some address + 8bytes

现在如果我将指针设为short int* ptr

我以与上面相同的方式打印并得到输出:

some address
some address + 2bytes
some address + 4bytes

这是为什么呢?地址不是无符号整数吗?如果是这样,那么指针指向的数据类型应该无关紧要。指针将始终存储一个无符号整数地址,因此它将占用 4 个字节。为什么短 int 指针占用 2 个字节,而 int 指针占用 4 个字节?最后,两个指针都只存储地址,不是吗?

【问题讨论】:

  • Pointer Arithmetic的可能重复
  • 我知道指针算法是如何工作的。我只是不明白为什么它的工作方式。
  • 这是编译器的一个特性。它在编译时计算字节数以将其添加到指针值。
  • "%x"打印地址是UB。要便携且符合标准,您需要 "%p" 并将地址转换为 void*
  • 以上所有值都是无符号整数。你能在这里指出任何浮动吗?顺便说一句,您应该接受正确的答案

标签: c pointers pointer-arithmetic


【解决方案1】:

指针算术(即ptr+n)以所指向的事物为单位执行。

记住ptr+n等价于&ptr[n],所以也等价于:

(T *)((char *)ptr + n*sizeof(T))

T 是您指向的任何类型。


顺便说一句,你应该使用%p来显示指针,而不是%#x

【讨论】:

    【解决方案2】:

    如果你这样做了

    int* ptr;
    printf("%#x\n%#x\n%#x\n", ptr, ptr+1, ptr+2);
    

    编译器说“嘿,ptr 指向一些 int,而程序员希望 ints 的偏移量分别为 1 和 2 个整数。所以,我得到了 sizeof(int)(在许多架构,包括你的,4 个字节)并将其添加到 ptr" 的值中。因此输出将偏移 4 个字节。

    内存中的布局:

    ptr --+
          |
          v
          +---------+---------+---------+
          |   int   |   int   |    int  |
          +---------+---------+---------+
            4 bytes   4 bytes   4 bytes
    

    什么时候做

    unsigned int* ptr;
    printf("%#x\n%#x\n%#x\n", ptr, ptr+1, ptr+2);
    

    编译器说“嘿,ptr 指向一些 unsigned int,而程序员希望 unsigned ints 的偏移量分别为 1 和 2 个整数。所以,我得到了 sizeof(unsigned int)(在许多架构,包括你的,2 个字节)并将其添加到 ptr" 的值中。所以输出会偏移 2 个字节。

    内存中的布局:

    ptr --+
          |
          v
          +---------+---------+---------+
          |unsigned | unsigned|unsigned |
          +---------+---------+---------+
            2 bytes   2 bytes   2 bytes
    

    【讨论】:

    • 好的,我想我现在明白了。 “ptr”的大小始终为 4 字节。谢谢!
    • 是的,sizeof(ptr) 是 -- 在包括你的在内的许多架构上 -- 4,但 ptr 指向的元素可能只是任意大小。
    【解决方案3】:

    指针算术不同于通常的整数算术。编译器会记住 this 指针指向的变量类型的长度,并将这个长度添加到地址中,而不仅仅是数字 1、2 等等

    【讨论】:

    • 如果一个指向短整数的指针每次都提前2字节,那么这是否意味着指针长度是2字节?如果确实是2bytes,那么它如何存储大于2^16的地址呢?
    • 不,指针的长度肯定不等于它指向的数据的长度。要么我说不清楚,要么你不明白我的意思。 )))
    • 我现在明白了。我一直将指针大小与其指向的数据类型的大小混淆。谢谢!
    【解决方案4】:

    你是对的,指针存储地址。但是当你说int* ptr时,它在内存中分配了4个字节,因此任何新的分配都不会触及这个区域。同样,short 占用 2 个字节,因此它在内存中分配 2 个字节。

    底线:指针存储所有数据类型通用的地址值,但容量各不相同

    您可以阅读:http://www.taranets.net/cgi/ts/1.37/ts.ws.pl?w=329;b=279

    【讨论】:

      【解决方案5】:

      是的,指针是无符号整数,现在考虑定义int *ptr

      ptr 不代表指针的地址,它代表指针指向的变量的地址,大小将取决于它指向的变量的类型。 如果你对指向任何类型的指针做了类似的事情,printf("%x %x %x",&ptr,&ptr+1,&ptr+2),那么地址之间的区别将是相同的

      【讨论】:

        猜你喜欢
        • 2023-04-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-11-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多