指针存储哪些地址?

时间:2021-04-24 09:50:33

标签: c pointers memory memory-address

我目前正在学习 C 中的指针。 我开始知道,指针是一个变量,它存储另一个变量的地址。 所以当我做类似的事情时,

#include <stdio.h>

int main()
{
    int x = 10;
    int *ptr;
    ptr = &x;
    printf("%d" ,ptr); 
   

上面给了我整数值的地址。
我的问题是,指针变量 ptr 存储类型为 int 的变量的地址。 根据我的 PC, int 占用 4 个字节,即 32 位。根据我的理解,每一位都有一个单独的内存地址。

那么地址指针会指向什么?它会指向第一位内存地址还是其他什么?请告诉我。

如果我的理解有误,请指正。

4 个答案:

答案 0 :(得分:2)

内存地址是一个字节的位置。 32 位位置是四字节边界上的位置。

因此内存地址 0x0000 等于第一个 32 位内存位置。地址 0x0004 将等于下一个四字节边界,即下一个 32 位位置。

那么就剩下 big-endian and little-endian 的问题了。

答案 1 :(得分:1)

<块引用>

根据我的理解,每一位都有一个单独的内存地址。

不,每个字节都有一个内存地址。您必须使用额外的偏移量来获取单个位。你不能让一个指针指向一个位。

<块引用>

那么地址指针会指向什么?它会指向第一位内存地址还是其他什么?请告诉我。

没有。它指向整个对象。您不能说出对象中的哪个字节,因为这取决于字节顺序。

此外,当使用 -Wall -Wextra 编译时,会发出警告。

warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’

您在打印指针时使用了错误的格式说明符。 %d 用于 int。但是,您的指针的类型为 int*,而不是 int。如果要打印地址,请改用:

printf("%p", (void*)ptr); 

答案 2 :(得分:1)

最小可寻址单位是字节。与 int 类型的对象占用多少字节无关,指向此类对象的指针指向该对象所占用内存范围的第一个字节。

来自 C 标准

<块引用>

3.5 1 位

执行环境中的数据存储单元足以容纳 可能具有两个值之一的对象

2 注意 不需要可以表达每个人的地址 对象的单个位。

3.6 1 个字节 大到足以容纳任何成员的数据存储的可寻址单元 执行环境的基本字符集

注意这个调用

printf("%d" ,ptr); 

调用未定义的行为。

如果你想输出一个指针的值,你应该使用转换说明符p。例如

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

答案 3 :(得分:1)

在像 x86 这样的系统上,每个单独的字节都有自己的地址。对于 ints 或 doubles 等多字节对象,对象的地址是其第一个字节的地址。在像 x86 这样的小端系统上,第一个字节是最低有效字节,而在像 Power 这样的大端系统上,第一个字节是最高有效字节:

int x = 0x01234567;

 A      A+1    A+2    A+3      big-endian
+––––––+––––––+––––––+––––––+
| 0x01 | 0x23 | 0x45 | 0x67 |
+––––––+––––––+––––––+––––––+
 A+3    A+2    A+1    A        little-endian

大多数架构都有对齐限制,因此多字节实体的地址必须是 2 或 4 的倍数。这就是 struct 类型可能在成员之间具有“填充”字节的原因。

寻址和字节排序是底层架构的功能,而不是 C 语言。在某些字寻址系统中,每个单独的字节没有有自己的地址,因此指向较小类型(如 char)的指针可能需要在字中包含偏移量。指针类型的表示可能会有所不同。

除非您在裸机上工作,否则您使用的地址值是虚拟地址,而不是物理地址。

相关问题