C语言 变量的地址值异常大或为负值



所以我在学习和练习C语言中变量的指针和地址的概念。但有一件事让我很好奇。我运行的代码是-

#include <stdio.h>
int main()
{
int *p, n;
p = &n;
int *c = NULL;
printf("Address of variable = %pn", p);
printf("Address of variable = %lun", p);
printf("Address of c variable = %lun", c);
return 0;
}

我确信这段代码是正确的打印地址,我得到的输出是-

pointer.c: In function ‘main’:
pointer.c:10:37: warning: format ‘%lu’ expects argument of type ‘long unsigned 
int’, but argument 2 has type ‘int *’ [-Wformat=]
10 |     printf("Address of variable = %lun", p);
|                                   ~~^     ~
|                                     |     |
|                                     |     int *
|                                     long unsigned int
|                                   %ls
pointer.c:11:39: warning: format ‘%lu’ expects argument of type ‘long unsigned 
int’, but argument 2 has type ‘int *’ [-Wformat=]
11 |     printf("Address of c variable = %lun", c);
|                                     ~~^     ~
|                                       |     |
|                                       |     int *
|                                       long unsigned int
|                                     %ls
Address of variable = 0x7fffc5a57474
Address of variable = 140736509342836
Address of c variable = 0

所以,我想知道这些编译器警告是什么意思,我应该关心这些警告吗?

另外,当我使用%d而不是%p%lu时,我得到的地址值为"负的";值,那么内存中是否可以存在负地址?

此外,输出中的地址值异常大。它们甚至比我的16gb RAM的大小还要大,我的变量怎么可能存储在一个不存在的位置?

如果您将指针视为数字,则必须小心。在内部,它们通常是地址,它们通常是数字,但它们是无符号数字。所以,不,你通常不会有"否定地址"。

你可能还没有学过计算机是如何表示负数的。下面是常见的"二互补"的快速演示。表示,只使用三个比特。关键是相同的位模式可以有两种不同的解释,这取决于您是否关心负值:

<表类> 位模式 signed int unsigned int tbody><<tr>0000000111010220113310044101351102611117

您的代码不正确。

转换说明符lu期望其对应的实参类型为unsigned long,d期望其对应的实参类型为int;pc的类型为int *,因此有警告。是的,这些警告很重要——至少您会得到乱码的输出,正如您已经发现的那样。

指针类型不是整型;它们不必具有与整数类型相同的大小或表示(在x86_64上,int是32位宽,但指针类型是64位宽)。唯一为指针类型定义的转换说明符是p,它期望其对应的实参类型为void *

你的代码应该写得更像
printf( "p = %pn", (void *) p );
printf( "c = %pn", (void *) c );

相关内容

  • 没有找到相关文章

最新更新