【问题标题】:Pointer arithmetic and malloc()/calloc() functions [duplicate]指针算术和 malloc()/calloc() 函数
【发布时间】:2014-11-13 12:06:33
【问题描述】:

有两件事我不明白,通常在使用 malloc() / calloc() 时,我们将它类型转换为它,因为它们返回一个 void 指针,所以我们将它类型转换为我们的指针类型,这样我们就可以进行指针运算用它。 所以我做了一个代码示例,我使用 malloc() 并且我不键入它并且指针算术仍然有效:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *p = malloc(8);
    *p++ = 30;
    *p = 40;
    printf("p points to address [%p] which holds a value of %d, p points to address [%p] which holds a value of %d\n", p, *p++, p, *p--);
    return 0;
}

这是为什么?

我的另一个关于指针算法的问题是我上面给你看的代码,我最初是这样写的:

#include <stdio.h>
#include <stdlib.h>

int main()
{
    int *p = malloc(8);
    *p++ = 30;
    *p-- = 40;
    printf("p points to address [%p] which holds a value of %d, p points to address [%p] which holds a value of %d\n", p, *p++, p, *p--);
    return 0;
}

注意差异是 *p-- = 40。 我使用了 p-- 因为我想打印指针指向的正确地址,我假设在使用 p++ 之后我需要使用 p-- 所以指针将指向值 30 的地址,但是如果我添加了 p-- 并打印了它,我注意到它打印了另一个值。 所以这里的东西对我来说没有点击是怎么回事?此外,如果我删除 -- 然后打印,它会打印 30 和 40,正如我预期的那样但地址保持不变,我预计它是以前的地址+4,它的值还没有改变,什么继续?

http://imgur.com/GRRInBL

【问题讨论】:

  • 转换malloc 的结果是不好的做法。它返回void * 的全部意义在于它将隐式转换为您需要的任何类型。
  • 至于你问题的第二部分,它是关于未排序的++-- 运算符的近乎日常问题的重复。
  • “我们键入它是因为” - C 自 1970 年以来变得更好
  • 有人知道要标记的正确副本吗? SO的搜索没有帮助...

标签: c pointers malloc dynamic-allocation calloc


【解决方案1】:

指针算法取决于声明指针的类型。由于您的指针是int *,那么++-- 会将指针的(原始)值递增和递减sizeof(int),以便您可以访问相邻的int 值。

在 C 中,可以将 void * 分配给另一种类型的指针(例如 int *)而不会触发警告(这在 C++ 中不是这样)。在这种情况下,转换由编译器隐式执行。

【讨论】:

  • 我知道指针算术取决于类型,但请阅读我尝试过的内容以及我的结果,这在我看来很奇怪。关于类型转换,所以它是由我的编译器自动完成的(仅谈论 C)
  • 我认为您的大部分困惑源于您的 printf 调用中未定义的行为,如 cmets 中所述。解决这个问题,事情可能会更有意义。
  • 我添加了一张我如何看待它的图片,所以首先我们有一个指向 8 个字节(2 个连续整数)的指针。我们的指针指向我们的第一个整数(如图 #1 所示),在图 2 中,我们将 30 放入第一个整​​数并递增指针以指向第二个整数(如图 #2 所示),在最后一张图像中,我们放入 40在该地址中,我们递减指针以指向原始整数。这就是我认为如果我执行 p++ = 30 然后 *p-- = 40 会发生的事情,但是如果我执行 *p*--** = 40,printf 函数会在第一次,第二次30,
  • 据我了解,这就像我第一次增加指针 *p++ = 30 然后使用 *p-- = 40 为该地址分配一个值后,就像我分配一个递增指针的值 指针指向原始地址,然后递减发生并递减以指向不相关的地址,我刚才说的是真的吗?如果我们有一个指向我们的第一个 int 的指针,那么我们增加指针并为第二个整数赋值,指针将重置并指向原始地址? (对先前评论的跟进)
  • 相信您的理解是正确的。但是,您的 printf 声明给了您误导性的答案,因为如果您在声明中使用 p++p--,那么您不能在同一声明中以任何其他方式使用 p。这是未定义的行为。在做任何其他事情之前修复你的 printf 语句。
猜你喜欢
  • 2020-07-22
  • 2016-07-30
  • 1970-01-01
  • 2012-03-02
  • 1970-01-01
  • 1970-01-01
  • 2016-04-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多