我了解到在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]);
}
答案 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。