题
在C,我试图打印出一些函数的变量和地址的地址。 我有一个是负值,另一种是正值。 我的问题是:为什么C并非所有负面或全部正值代表
下面是我的代码:
int foo() {
return 0;
}
int main() {
int a;
printf("%d\n",&a);
printf("%d\n",foo);
return 0;
}
下面是结果:
-1075908992 134513684
解决方案
存储器地址不应该被解释为以这种方式符号整数。数的符号取决于最高位组(假设2的补码表示,其用于通过广大的当前使用系统),所以在32位的系统上以上0x80000000的一个存储器地址将是负的,和存储器下面为0x80000000地址将是积极的。有没有真正的意义了这一点。
您应该打印使用%p
改性剂存储器地址;可替代地,一些人使用用于打印存储器地址%08x
(或%016llx
在64位系统)。这将始终打印出作为十六进制的无符号整数,其远小于一个符号十进制整数更加有用。
int a;
printf("%p\n", &a);
其他提示
要成为最符合标准可能,通过“%P”格式字符串printf()
并浇铸到void*
参数。
printf("%p\n", (void*)&a);
printf("%p\n", (void*)foo);
从标准草案(n1401.pdf)引用
7.20.6.1 The fprintf function 8 The conversion specifiers and their meanings are: p The argument shall be a pointer to void. The value of the pointer is converted to a sequence of printing characters, in an implementation-defined manner.
您应该通过指针格式化器:
printf("%p\n",foo);
您正在以十进制打印出来。你可能想打印出十六进制的内存位置(使用“%P”)(最大内存地址按照惯例以十六进制)。
都不是,指针不具有标志,但是当转换为一个符号整数它可能是正的或负的。
顺便提及,传递指针与格式可变设计为可以打印的整数printf
导致未定义的行为。你应该总是明确地强制转换为正确的类型来获得未指定或实现定义的行为(根据投)。
指针没有符号的整数,是更像无符号整数。但是,你打印出来,好像他们是有符号整数。在32位系统中,有几件事情,很可能是32位长:int
,unsigned int
,float
和指针。你不能在一般的说这些都只是看着他们,但他们都意味着不同的事情。 (作为一个实验,你可以通过在不同的整数和打印他们像花车,反之亦然。这是一般不好的做法,但它可以告诉你的是不同的数据类型做意味着不同的事情)
这需要可变数量的参数(“可变参数”函数)的函数以复杂的方式排序这样做。特别是,他们不检查参数类型。你可以通过你喜欢printf()
和类似功能的任何参数,但让他们与格式说明同意是你的问题。这意味着功能没有得到正确类型的方式(因为它会如果你通过了float
像int foo(int)
功能)。
传递错误类型的参数会导致不确定的行为,并且是特别容易,如果你传递了错误尺寸的参数会导致出现问题。在大多数64位系统,指针是64位,并且int
s是32。
因此,你需要使用正确的格式字符串。 printf("%p", &a);
将打印出a
的地址作为指针,这是你想要的。该标准要求像printf("%p", (void *)&a);
,但因为这是任何一台计算机上不必要的一个实际问题,你永远都可能遇到。
您也可以使用printf("%p", &a)
为好。 %p
是指针格式说明,以输出在一个实现定义方式指针的值。实际上来说,它的几乎一样%的x,但是其中一个指针是大于int将处理的情况。
printf的是不是有些神奇解释工具。所有它是做,如果你给它“%d”是显示你坐在那个变量的位模式看起来像一个整数。
至于为什么一些指针是阴性和阳性的一些,全部的意思是,一些具有高阶位置和一些没有。什么地址提供给的对象是你的操作系统真的只有业务(通常与一些硬件的帮助)。编程语言中有没有真正的发言权。
如果我是你,我就不会被打印出来的地址的方式。如果你真的觉得有必要去看待他们,用“%X”,而不是“%d”。这将打印出来的十六进制,这使得它更容易找出哪些位上,哪些不是。 Generaly所有你会与地址关心的是,如果他们是0与否,如果两者匹配,一些其他地址的值。
除了使用%p
,你也可以转换为uintptr_t
,以确保得到一个unisgned整数。
使用PRIuPTR
(或PRIXPTR
为十六进制)形式<inttypes.h>
以获得正确的格式说明:
printf("%" PRIuPTR "\n", (uintptr_t)(void *)&foo);
使用以下代码:
printf("%u",&a);