打印指针变量的地址

时间:2014-10-04 12:16:12

标签: c++ c pointers

我了解到在c中打印变量的地址时,我们使用unsigned int(格式字符串为%u)。
它的范围是0到65535.现在一个整数需要4个字节的内存,这意味着最多可以存储16384(65536/4)个整数。如果我们尝试声明一个数组int a[20000]并获取其每个元素的地址会发生什么?

#include<stdio.h>
int main(void)
{
    int a[20000];
    for(i=0; i<19999; i++])
        printf("%u", &a[i]);
}

3 个答案:

答案 0 :(得分:1)

在C的早期,一个指针和一个类似类型的int,你可以安全地从一个转换到另一个并再回来。在那个早期的时候,指针和int都是16位长。在32位系统上仍然如此,其中int现在是32位。但它在64位系统上是错误的,因为指针长64位,只有32位。

所以我不知道在c中打印变量地址时你在哪里以及如何学习,我们使用unsigned int(%u),但是尽快忘记它,因为在一般情况下它是错误。打印地址的唯一简单方法是%p,因为系统会自动调整大小为16位,32位或64位。

并且不再将指针转换为int或对面,因为它非常不可移植。从其他post开始,更便携的方式(在C99标准变体上)是#include <stdint.h>,然后将指针转换为intptr_t(和返回)。这个整数类型保证是指针的大小。

而且,我几乎忘了65536 = 0x10000 = 2 16 ,2 32 = 4294967296。所以你离现实并不那么远,而且确实在较旧的16位系统你不能拥有int array[40000]因为int是16位长而且数组会耗尽所有可用内存。

但是在32位系统上,你可以处理4 Gb的内存,因此int array[20000]是无害的。

答案 1 :(得分:1)

指针是一个内存地址,您可以在其中找到一些数据。我们可以使用sizeof()运算符找到指针变量的大小。因此它的大小并不取决于它所指向的内容。但是它依赖于系统上占用的内存地址的许多字节,32位编译器为4,64位编译器为8。

如果我们已经声明了一个指针,那么双重 j,j的类型是双,即“指向double&#34的指针;。

%p是打印指针的正确格式说明符。 %p以十六进制表示法输出地址。

有时人们使用%u和%x(十六进制形式的unsigned int)说明符来打印指针变量。但是,为%x或%u参数传递指针是一种未定义的行为。

然而,它适用于32位编译器,如代码块。这是因为unsigned int和指针的大小在这里相同。 (两个4字节)

(假设int和指针具有相同的宽度是错误的。对于在x64上运行的GCC 64位和MSVC 64位,sizeof(void *)== 8,而sizeof(unsigned int)== 4。事实上,在某些体系结构中,指针和整数的大小相同,例如PDP-11 / 34a,或者现在的大多数32位体系结构。但是编写依赖它的代码是非常不明智的。

您可以添加额外的2行,如下所示并验证:

printf(&#34; unsigned int的大小是%lu \ n&#34;,sizeof(unsigned int)); printf(&#34;指针的大小是%lu \ n&#34;,sizeof(int *));

在具有64位操作系统的64位GCC机器上,这应该分别为4和8)

在GCC 64位机器上 - %x将指针强制转换为无符号整数(32位长度)。指针的大小为8字节(64位)长度。使用%p打印时会打印整个指针,其大小为64位。但是当使用%x打印时,只打印低32位。因此,使用%p打印指针总是安全的。

答案 2 :(得分:-1)

实际上,无符号整数在较旧的16位编译器(例如turbo c)上的范围为0到65536。现在所有系统都有32或64位架构,其中无符号整数范围为0到4G(千兆)。所以这段代码应该可以在最新的编译器中运行,例如gcc(在linux下)或visual studio(在windows下)。尝试切换到这些编译器。它们非常好,现在被广泛使用了一天。 16位编译器已经过时了。避免使用此类编译器。如果你正在使用windows,那么代码块或dev c ++是一些很好的编程IDE,用于学习c。

P.S。避免使用%u来打印地址。请改用%p。