这两个语句之间有什么区别
int *p = (int*) i; and int *q=&i;
这是整个程序
#include<stdio.h>
int main(){
int i;
int *p = (int*) i;
printf("\n p is %d ",p);
int *q = &i;
printf("\n q is %d ",q);
return 0;
}
获得的输出为
p is 22092
q is 1002476148
我认为这里p和q都存储了i的地址,但是它们显示的值不同,有人可以解释为什么会这样吗?
答案 0 :(得分:2)
首先:指针必须强制转换为(void*)
并用%p
打印。 %d
以10为底打印int
。即
#include <stdio.h>
int main(){
int i;
int *p = (int*) i;
printf("\n p is %p ", (void*)p);
int *q = &i;
printf("\n q is %p ", (void*)q);
}
现在让我们尝试通过以下更改来编译程序:仅2个错误:
% gcc ptr.c -Wall -Wextra
ptr.c: In function ‘main’:
ptr.c:5:14: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
int *p = (int*) i;
^
ptr.c:5:14: warning: ‘i’ is used uninitialized in this function [-Wuninitialized]
int *p = (int*) i;
^~~~~~~~
都对int *p = (int*) i;
保持坦白;第二个说使用了i
的值,但是我们没有为i
设置任何值(这会导致 undefined behaviour ),而另一个我们试图将整数转换为指针,并且该整数与该平台上的指针没有相同的位数。
即
int *q = &i;
使用变量q
的地址初始化指向整数i
的指针,而
int *p = (int*) i;
以实现定义的方式将i
中包含的垃圾值解释为地址,并以此初始化p
。
不太相等。
答案 1 :(得分:1)
这里
int *p = (int*) i; /* i is not initialized */
指针p
被分配了值为i
的值,该值是一些垃圾数据,并试图将某些垃圾数据转换为int*
类型并分配给p
。如果您尝试取消引用p
,则会出现分段错误,并导致未定义的行为。
还有这里
int *q = &i;
指针q
被分配了有效地址。
例如,在打印指针变量时,请使用%p
代替%d
格式说明符,例如
printf("\n q is %p ",(void*)q);
关于为指针(例如int *p = (int*) i
分配整数值, C标准说
6.3.2.3指针
(5)可以将整数转换为任何指针类型。除了作为 先前指定的结果为实施定义 未正确对齐,可能未指向 引用的类型,并且可能是陷阱表示。
答案 2 :(得分:0)
根据C标准ISO / IEC 9899:2011,第6.3.2.3节:
整数可以转换为任何指针类型。除非先前指定,否则结果是实现定义的,可能未正确对齐,可能未指向引用类型的实体,并且可能是陷阱表示。
因此,当您将i
转换为pointer-to-int
类型时,其内容通常是不确定的。