我只是用C编写了一个简单的程序,如下所示:
#include <stdio.h>
void main()
{
int *pointer;
int number = 4;
printf("number = %d\n",number);
pointer = &number;
printf("number = %d and pointer = %d\n",number,pointer);
printf("pointer = %d and number = %d",pointer,number);
}
Run Code Online (Sandbox Code Playgroud)
执行后,将输出如下所示:
number = 4 and pointer = 8724
pointer = 8724 and number = 9415
Run Code Online (Sandbox Code Playgroud)
因此,为什么只为打印方向改变而改变值。我不能证明这个规则。
您使用的是64位编译吗?
int number = 4;
int *pointer = &number;
printf("number = %d and pointer = %d\n", number, pointer);
printf("pointer = %d and number = %d\n", pointer, number);
Run Code Online (Sandbox Code Playgroud)
如果是这样,则printf()上面代码中的第一个调用将4字节的int值和8字节的int *值压入堆栈,并告知printf()打印两个4字节的数量。这些显然是int8字节地址的4字节和4字节。第二个printf()调用将8字节int *和4字节压int入堆栈,并告知printf()再次打印两个4字节数量。但是这一次,它们是分别int *打印的8字节值的两半。严格来说,这是在调用不确定的行为,但这是一种可能的可能性,可以解释您看到的结果。
(有一些注意事项潜伏在我假设的64位编译。CHAR_BIT == 8,sizeof(int) == 4以及sizeof(int *) == 8;也是落实堆栈传递参数,并且可能不严格C标准但保证一些相关的假设通常适用于64位编译器。)
您应该决定要做什么。如果您想看4两次,则:
int number = 4;
int *pointer = &number;
printf("number = %d and pointer = %d\n", number, *pointer);
printf("pointer = %d and number = %d\n", *pointer, number);
Run Code Online (Sandbox Code Playgroud)
如果您想查看地址,则应使用%p该地址(并严格转换为void *):
int number = 4;
int *pointer = &number;
printf("number = %d and pointer = %p\n", number, (void *)pointer);
printf("pointer = %p and number = %d\n", (void *)pointer, number);
Run Code Online (Sandbox Code Playgroud)
如果要控制指针的格式,则需要C99 #include <inttypes.h>和:
int number = 4;
int *pointer = &number;
printf("number = %d and pointer = 0x%.16" PRIXPTR "\n", number, (uintptr_t)pointer);
printf("pointer = 0x%.16" PRIXPTR " and number = %d\n", (uintptr_t)pointer, number);
Run Code Online (Sandbox Code Playgroud)
#include <stdio.h>
#include <inttypes.h>
int main(void)
{
int number = 4;
int *pointer = &number;
printf("number = %d and pointer = %d\n", number, pointer);
printf("pointer = %d and number = %d\n", pointer, number);
printf("number = %d and pointer = %d\n", number, *pointer);
printf("pointer = %d and number = %d\n", *pointer, number);
printf("number = %d and pointer = %p\n", number, (void *)pointer);
printf("pointer = %p and number = %d\n", (void *)pointer, number);
printf("number = %d and pointer = 0x%.16" PRIXPTR "\n", number, (uintptr_t)pointer);
printf("pointer = 0x%.16" PRIXPTR " and number = %d\n", (uintptr_t)pointer, number);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
Mac OS X 10.8.5上的GCC 4.8.1。同样也给出了类似的警告clang。
gcc -O3 -g -std=c11 -Wall -Wextra -Wmissing-prototypes -Wstrict-prototypes -Wold-style-definition it.c -o it
it.c: In function ‘main’:
it.c:8:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 3 has type ‘int *’ [-Wformat=]
printf("number = %d and pointer = %d\n", number, pointer);
^
it.c:9:5: warning: format ‘%d’ expects argument of type ‘int’, but argument 2 has type ‘int *’ [-Wformat=]
printf("pointer = %d and number = %d\n", pointer, number);
^
Run Code Online (Sandbox Code Playgroud)
number = 4 and pointer = 1417245952
pointer = 1417245952 and number = 4
number = 4 and pointer = 4
pointer = 4 and number = 4
number = 4 and pointer = 0x7fff54797500
pointer = 0x7fff54797500 and number = 4
number = 4 and pointer = 0x00007FFF54797500
pointer = 0x00007FFF54797500 and number = 4
Run Code Online (Sandbox Code Playgroud)
有趣的是,系统设法4在输出的前两行中两次打印该数字。我没有研究汇编程序来了解它是如何工作的,但是调用“不确定行为”的优点之一是您不能抱怨结果。任何结果都是正确的,因为所需的行为是不确定的。