C 理解指针的类型和值

C 理解指针的类型和值,c,pointers,types,C,Pointers,Types,我试图理解指针,它们的值和类型 假设我有一个int x: int x = 0; int* ip = &x; 我知道这里的值是x的地址,假设它是123 *ip += 1 现在的值是124吗?(地址+1)。我试图理解此处的值和类型发生了什么变化: float *fp = (float*)ip; *fp = 1.0; int y = *ip; 如果将指针设置为变量的地址,然后执行解引用赋值,则将更改指针处的值,而不是地址本身。因此,如果您编写更改地址的ip+=1,并且*ip+=1

我试图理解指针,它们的值和类型

假设我有一个int x:

int x = 0;
int* ip = &x; 
我知道这里的值是x的地址,假设它是123

*ip += 1 
现在的值是124吗?(地址+1)。我试图理解此处的值和类型发生了什么变化:

float *fp = (float*)ip; 
*fp = 1.0; 
int y = *ip;

如果将指针设置为变量的地址,然后执行解引用赋值,则将更改指针处的值,而不是地址本身。因此,如果您编写更改地址的
ip+=1
,并且
*ip+=1
更改地址处的值

下面是一组示例,这些示例有助于明确指针是如何工作的,包括浮点值。您应该阅读32位浮点的IEEE754表示法,以便更好地理解为什么
1.0
表示为
0x3f800000

请注意,这段代码对类型(由实现定义!)的大小做了很多假设,并忽略了别名规则(不允许指向内存中指针类型与声明的对象类型不匹配的对象,然后取消引用该指针)。也就是说,在实践中,您总是可以将任何内存解释为位,即使它是“不安全的”或“非法的”


我这里不解释浮点和int之间的内部转换。仅解释指针如何工作

未定义的行为,因为当您将ip强制转换为fp时,*fp=1.0赋值后修改的ip内容将不正确,因为整数的存储与浮点的存储完全不同。int是16位或32位,根据系统,浮点总是32位。@splaten:不完全是;64位
int
现在正在出现(其他尺寸很少,但它们已经出现了),而
float
可以与
double
的大小相同@Bathsheba,我对此不太确定。C11的附录F(规范性附录)明确说明了哪些类型等同于浮点和双精度:“浮点类型匹配IEC 60559单格式”和“双精度类型匹配IEC 60559双格式”。@paxdiablo:附录F是可选的。该答案没有提到严格的别名冲突,在这段代码能够可靠地工作之前,必须在编译器上禁用基于类型的别名分析。@user694733我只是想演示一系列案例,以明确指针是如何与其类型相关联地工作的。我在任何地方都使用了
这个词,所以我认为它很清楚:p,但我要添加一个注释。@Sanderedycker如果我试图谈论别名规则时出错,请建议/纠正我。我编程时喜欢一切都是
void*
8)@okovko:minor nitpick:你可以指向一个指针类型不兼容的对象-它通过一个不兼容的指针访问指向的值,该指针给出了未定义的行为。“您得到一个编译时错误,并通过添加一个编译器标志在五秒钟内修复它。”问题是您并没有得到编译时错误。严格的别名会影响编译器生成指令的方式。这个问题的一个例子可能是,编译器没有将变量的值从内存刷新到CPU寄存器,因为它假设变量自上次引用以来无法修改。其他地方看似无辜的更改可能会导致指令丢失,代码会停止正常工作。这就是为什么处理严格的别名问题如此痛苦的原因。
int x = 0;
int* ip = &x;
*ip += 1; // x = 1
ip += 1; // ip is now increased by sizeof(int) and probably points to
        // the gap in the stack between x and ip, since sizeof(x) is probably 4
        // and ip is probably 8 byte aligned
ip += 1; // now ip probably points to itself! (the address points to its own address value)
ip -= 2; // now ip points to x again
*ip += 2; // now x = 3

float *fp = (float*)ip; // the value *fp is the same in binary, 0b11
int z = *(int *)fp;    // z is 3, because we're preventing the conversion
*fp = 1.0;            // in hex, *fp is 0x3f800000
int y = *fp;         // 1.0 is converted to int and stored in y as 1
int a = *(int *)fp; // a is 0x3f800000
int x = 0;
int* ip = &x;  /*I know the value here is the address of x, let's say it is 123*/
printf("\n%u",ip); //value is 123
printf("\n%u",*ip);// value is 0
*ip += 1; //*ip points to the value of the stored address i.e. x and increase it by 1 
printf("\n%u",ip); //value is 123
printf("\n%u",*ip); //value is 1

float *fp = (float*) ip; converting address inside ip i.e. 123 into float type and store in fp
printf("\n%u",fp); //value is 123
printf("\n%f",*fp);//points to the value of stored address i.e. value at 123. 0.000000 is the value as we have converted it to float from int it got initialized to 0
*fp = 1.0; //storing the value to address 123

printf("\n%f",*fp);//value is 1.000000
int y = *ip;//storing the value

printf("\n%f",y);//it will also gives 1.000000