C 什么是(int*)&;什么意思?

C 什么是(int*)&;什么意思?,c,pointers,C,Pointers,(int*)&i的含义是什么 char i; int* p = (int*) &i; ... *p = 1234567892; ... 如果是*&i,我会理解的。但在本例中,这里有一个“int” 没有(int*),gcc会抱怨,因为指向胡萝卜的指针不是指向土豆的指针 警告:从不兼容的指针类型初始化[默认启用] 因此,这个符号仅仅表示OK,我知道我在这里做什么,把它看作是一个指向不同类型的指针,即INT.< /P> < P>构造>代码>(int *)和var < />

(int*)&i
的含义是什么

  char i;
  int* p = (int*) &i;
  ...
  *p = 1234567892;
  ...
如果是
*&i
,我会理解的。但在本例中,这里有一个“
int

没有
(int*)
,gcc会抱怨,因为指向胡萝卜的指针不是指向土豆的指针

警告:从不兼容的指针类型初始化[默认启用]

因此,这个符号仅仅表示OK,我知道我在这里做什么,把它看作是一个指向不同类型的指针,即INT.< /P> < P>构造>代码>(int *)和var < /> >,其中<代码> var >代码>是一个<代码> char < /代码>,取一个指针指向<代码> var >代码>,然后将其转换为不同类型的指针(即代码> int <代码>)。程序随后将

int
值写入指针。由于指针实际上指向一个
char
,因此
int
值不合适,这会触发未定义的行为,这是一个花哨的名称,表示“任何(计算机可以实际完成的)事情都可能发生,这个程序有缺陷”

编辑:根据要求,提供一些标准来解释此程序具有未定义行为的原因。以下所有章节参考均为,与C2011的官方文本最接近,可在线免费访问

作为序言,在阅读C标准文本时,您需要知道“应”一词具有特殊意义。任何包含“应”一词的句子都对程序或编译器和运行时环境提出了严格要求;你必须从上下文中找出哪一个。对程序有两种硬要求。如果“约束”部分出现“应”一句,则要求编译器诊断违规行为(§5.1.1.3)(《永不泄气标准》规定必须拒绝程序,但这是硬错误和警告之间的通常界线)。如果“应”语句出现在其他地方,则不要求编译器对其进行诊断,但违反该要求的程序具有未定义的行为(§4p1,2)。有时文本会说“如果X,那么行为是未定义的”;后果没有区别

首先,转换
(int*)&var
char*
转换为
int*
,这是§6.3.2.3p7明确允许的,当且仅当指向
char
的指针的值与
int
类型的对象正确对齐时

指向对象类型的指针可以转换为指向不同对象类型的指针。如果结果指针与引用的类型未正确对齐,则行为未定义。否则,当再次转换回时,结果应与原始指针进行比较

显示的代码中没有任何内容可以确保
var
针对
int
进行了适当的对齐,因此程序可能已经在此时触发了未定义的行为,但我们假设它已正确对齐。将
int*
类型的值保存到使用该类型声明的变量中是没有问题的。下一个操作是
*p=integer\u literal
。这是对对象
var
存储值的写入访问,必须遵守§6.5p6,7中的规则:

  • 访问其存储值的对象的有效类型是该对象的声明类型(如果有)。[…更多关于对象没有声明类型时会发生什么的文本;此处不相关…]

  • 对象的存储值只能由具有以下类型之一的左值表达式访问:

    • 与对象的有效类型兼容的类型
    • 与对象的有效类型兼容的类型的限定版本
    • 与对象的有效类型相对应的有符号或无符号类型
    • 一种类型,它是与对象的有效类型的限定版本相对应的有符号或无符号类型
    • 在其成员中包含上述类型之一的聚合或联合类型(递归地包括子聚合或包含的联合的成员),或
    • 字符类型
  • 对于简单的算术类型,如
    int
    char
    ,compatible type表示剥离
    typedef
    s后的相同类型。(准确的定义扩展到§§6.2.7、6.7.2、6.7.3和6.7.6。)对于该分析而言,重要的是所声明的
    var
    类型是
    char
    ,但左值表达式
    *p
    具有类型
    int
    int
    char
    不兼容,
    int
    不是字符类型。因此,该程序违反了“应”一词的要求,该词不在“约束”一节中,其行为未定义

    注意最后一个要点的不对称性。具有字符类型的左值表达式可以访问任何对象的存储值,但具有不兼容类型的左值表达式不能访问声明为具有字符类型的对象。是的,这意味着通过指向
    int
    的指针“一次四个”访问大型字符数组(例如从文件读取的数据缓冲区)的常用习惯用法严格来说是无效的。许多编译器对这种情况下的指针别名规则做了一个特殊的例外,以避免使该习惯用法无效


    但是,通过指向
    int
    的指针访问单个
    char
    也是无效的,因为(在大多数系统上)
    int
    大于
    char
    ,因此您读取或写入的字节超出了对象的末尾。该标准并不费心将该大小写与数组大小写区分开来,但无论如何它都会影响到您。

    int*
    是一种类型,特别是指向int的指针

    (type)x
    是c型