(int *)p和&p

时间:2018-10-27 17:49:29

标签: c pointers memory-address

这两个语句之间有什么区别 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的地址,但是它们显示的值不同,有人可以解释为什么会这样吗?

3 个答案:

答案 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类型时,其内容通常是不确定的。