【问题标题】:How is Memory Allocated to variables of different data types?内存是如何分配给不同数据类型的变量的?
【发布时间】:2016-04-18 21:04:10
【问题描述】:

我编写了以下代码。

#include<stdio.h>

int main()
{
    int x = 1 ;
    int *j = &x ;
    int y =  2 ;
    int *t = &y ;

    printf("%p\n" , (void *)j);
    printf("%p" , (void *)t);
}   

输出为0028FF14 0028FF10

我想说的是地址之间的差异是'4'。

而在这种情况下

#include<stdio.h>

int main()
{
    char x = 't' ;
    char *j = &x ;
    char y =  'f' ;
    char *t = &y ;
    printf("%p\n" , (void *)j);
    printf("%p" , (void *)t);    

   }   

输出为0028FF17 0028FF16

区别是1

第一种情况的差异是4。而在第二种情况下,它是1。为什么会这样?

如果我在所有内存地址单独打印值,我会得到什么?

也许真的很笼统,众所周知,但是我刚开始C,所以程序的输出让我很困惑。

更新
现在使用 %p 格式并将指针值转换为 void* 以按照 Keith Thompson 的建议打印指针值。

【问题讨论】:

  • @SergeyK.: 不,我不认为这是重复的。没有指针被递增。代码只是检查声明对象的地址。
  • @SergeyK.:我不同意。对于pointer ++,关系定义明确。两个单独定义的对象的地址之间没有定义的关系。 char x;char y; 的地址很容易相差 4,例如 - 或 42。
  • @SergeyK.: 这是怎么复制的?在这个问题中没有使用++ 或任何其他指针算法。
  • @SergeyK.:你已经说过了。我是说这个问题不是那个问题的重复。另一个问题是关于指针上的++。这个没有;这根本与指针算术无关。 (关闭此问题可能还有其他原因,但不能重复有关 ++ 的问题。)
  • 嗯?你是说你问的问题和++关于指针的问题一样吗?我真的不认为你是。

标签: c pointers allocation memory-address


【解决方案1】:

每个整数占用四个字节,因此,每个整数内存地址偏移4。一个char只占用一个字节,因此它的内存地址偏移1。

【讨论】:

  • 如果我在它们之间的地址打印值会发生什么?
  • 您将获得组成数字的各个字节。例如,如果 int 值为 1,那么它会以十六进制表示 0x00000001,这将分解为以下字符数组 0x00,0x00,0x00,0x01。
【解决方案2】:

对于初学者来说,差异并不总是四个,只是碰巧是四个,很巧合。允许编译器将变量粘贴到内存中任何它想要的位置。在这种情况下,它已将您的两个变量彼此相邻放在内存中,差异可以解释为系统上的整数有多大(4 个字节)和系统上的字符有多大(1 个字节)。在其他系统上,它们可能具有不同的大小并放置在不同的位置。

【讨论】:

    【解决方案3】:

    声明的对象在内存中的布局顺序没有要求。显然,您使用的编译器恰好将xy 放在一起。它可以在它们之间放置j,但它没有。

    另外,打印指针值的正确方法是使用%p格式并将指针值转换为void*

    printf("%p\n", (void*)j);
    printf("%p\n", (void*)t);
    

    这会生成一个实现定义的人类可读的指针值表示,通常但不总是以十六进制表示。

    如果您关心已声明变量在内存中的分配顺序,那么您可能做错了什么,或者至少没有用处。让编译器担心把东西放在哪里。它知道自己在做什么。

    【讨论】:

    • 我不确定你的意思。 char 对象恰好分配了 1 个字节。一个int 对象被分配sizeof (int) 字节。对象可以按任何顺序分配,它们之间可能有也可能没有额外的填充。
    • 我不明白你的意思。 int* 类型的地址是指int 对象的位置。该对象占用sizeof (int) 个字节,通常为4。但是当您打印指针的值时,它通常反映它指向的对象的第一个字节的地址。你有什么特别的问题要在这里解决吗?在我看来,您的问题不是重复的。
    • @SurajJain:int* 包含int 对象的地址。如果将int* 值转换为char*,则结果包含int 对象的第一个字节的地址。
    • 指针的类型告诉你它指向什么类型的对象。 int* 指向 int 对象。您可能想阅读comp.lang.c FAQ 的第 4 部分。
    • 好的,这就是混乱的根源。您在问题中使用了 C 代码,而在 C 中,“地址”是一个(类型化的)指针值。在机器术语中,“地址”通常表示单个字节。 4 字节对象的地址与这 4 个字节的 first 的地址相同。如果该基地址是 1000,则地址 1001、1002 和 1003 将指定该 4 字节对象内的连续字节。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-03
    • 2020-03-19
    • 1970-01-01
    相关资源
    最近更新 更多