如果我们只是为指针变量分配一个整数,为什么没有错误?这段代码会发生什么:
controller
答案 0 :(得分:4)
如果我们只是为指针分配一个整数,为什么没有错误 变量?
因为隐含地关闭了-pedantic
(或-pedantic-errors
)标记。
来自man gcc
:
发出严格的ISO C和ISO C ++要求的所有警告;拒绝 所有使用禁止扩展的程序,以及其他一些程序 不遵循ISO C和ISO C ++。对于ISO C,请遵循该版本 使用的任何
-std
选项指定的ISO C标准。
根据C标准,不允许在没有显式强制转换的情况下将整数分配给指针类型的对象(空指针常量除外)。相关条款是(强调我的):
C11§6.5.16.1/ 1简单分配
以下中的一个持有:
- 左操作数具有原子,限定或非限定指针类型, 和(考虑左值操作数在左值后的类型 转换)两个操作数都是限定或不合格的指针 兼容类型的版本,以及左侧指向的类型 右边指出的所有类型的限定符;
接下来的两个子弹大约是void
指针和NULL
。这里都不适用,因此发生约束违规。
答案 1 :(得分:1)
在C中,int *
之类的对象指针可以转换为void *
。 void *
指针可以转换为整数/从整数转换。但并非所有整数值都可以转换为指针。
可选类型intptr_t/uintptr_t
允许往返int * --> void* --> intptr_t/uintptr_t --> void* --> int*
OP的代码可能会失败,因为未明确指定直接转换。
int i=19;
int *ptr;
ptr=i; // problem - 19 may cause UB
printf("Value of ptr is %d",ptr); // problem, wrong printf specifier.
更好的例子
#include <stdint.h>
int i = 867-5309; // some integer
printf("Value of i is %d\n", i);
int *i_ptr = &i;
printf("Value of i_ptr is %p\n", (void*) i_ptr);
intptr_t i_ptr_i = (intptr_t)(void*) i_ptr;
// C lacks a specifier for intptr_t/uintptr_t, so use a wide type
printf("Value of i_ptr_i is %jd\n", (intmax_t) i_ptr_i);
int *i_ptr2 = (void*) i_ptr_i;
printf("Value of i_ptr2 is %p\n", (void*) i_ptr2);
答案 2 :(得分:0)
指针更正式地是指针变量&#34;。这意味着存储值的存储位置,就像任何其他变量一样。
就像任何其他变量一样,为变量类型定义了操作。对于指针变量,您可以指定应该表示内存地址的(无符号)整数值。获取另一个变量的地址并将其分配给指针变量就是一个例子。
取消引用指针变量意味着查看指针指向的内容。如果指针未指向有效地址,则硬件和操作系统可能会中止您的程序(&#34; seg fault&#34;)。
答案 3 :(得分:0)
其他答案已经很好地解释了它是允许的以及当你这样做时会发生什么。
但我认为提及它为何被允许也很重要。您可以为指针设置特定地址,因为在实现嵌入式软件时,使用微控制器,您需要多次写入非常具体的地址。与控制外设的寄存器地址一样,如端口,时钟操作,A / D转换器等