以下代码操纵指向同一位置的指针;我很困惑为什么当我运行代码时,输出没有显示值重合。
#include "stdio.h"
main()
{
int i=3,*x;
float j=1.5,*y;
char k='c',*z;
x=&i;
y=&j;
z=&k;
printf("\nAddress of x= %u",x);
printf("\nAddress of y= %u",y);
printf("\nAddress of z= %u",z);
x++;
y++;y++;y++;y++;
z++;
printf("\nNew Address of x= %u",x);
printf("\nNew Address of y= %u",y);
printf("\nNew Address of z= %u",z);
printf("\nNew Value of i= %d",i);
printf("\nNew Value of j= %f",j);
printf("\nNew Value of k= %c\n",k);
}
输出:
地址x = 3219901868
地址y = 3219901860
地址z = 3219901875
新地址x = 3219901872
新地址y = 3219901876
新地址z = 3219901876
i = 3的新值 新值j = 1.500000
新值k = c
变量y和z的新地址相同。两个变量如何具有相同的地址,并且具有不同的值? 注意:我在Ubuntu 9.04上使用了gcc编译器
答案 0 :(得分:12)
您要打印的内容不是x / y / z的地址,而是它们指向的地址。然后,通过修改指针(使用++),最终得到y和z指向内存中的相同地址。
关于值 - 首先你应该注意到你实际上没有改变j和k的值,并且当你打印这些值时,指针不再指向它们。
第二件事是,即使你确实打印了指针指向的值,你仍然会得到一个不同的值,因为在一种情况下,数据将被解释为一个浮点数而另一个被解释为一个char。
答案 1 :(得分:0)
只有当指针指向数组中的元素时,以这种方式递增指针才有用。
实际上,递增指针只会将其值增加指针类型指示的大小,因此:
答案 2 :(得分:0)
阿。指针算术的危险性。
所以y = &j
将指针y设置为浮动“j”的当前地址
然后你说y++
因为你已经将y定义为浮点指针,这被解释为将浮点变量的长度添加到指针y。
但是你只定义了一个浮点“j”,所以y现在指向“j”之后已经分配的任何东西 - 在这种情况下,它恰好是“k”变量的地址,该变量是在立即定义的 - 但实际上它可以是任何东西。
如果将“j”定义为浮点数组,则它将指向数组中与j [1]等效的第二个条目。即使你没有将j定义为一个数组,Incendently C也允许你使用j [1]!
答案 3 :(得分:0)
此外,虽然您的示例中不是这种情况,但两个变量可能(看起来)具有相同的地址但值不同。 假设你做了:
void display_addr_and_val(const int& var){
printf("Addr:%p Val:%d\n",&var, var);
}
void main(){
int x=0;
int y=1;
display_addr_and_val(x);
display_addr_and_val(y);
}
..理论上你可以得到x和y所示的相同地址(如果打开优化)。因为“display_addr_and_val”的参数是const引用,所以代码可以重写为:
void display_addr_and_val(const int& var){
printf("Addr:%p Val:%d\n",&var, var);
}
void main(){
int x=0;
display_addr_and_val(x);
int y=1;
display_addr_and_val(y);
}
现在,在此版本的代码中,您可能会发现“x”和“y”的生命周期中没有重叠。这意味着实际上编译器可能会选择为它们使用相同的堆栈槽。
当然,这种情况不会经常发生,但理论上没有理由说明为什么不应该发生 - 所以最重要的是,当你假设有关地址时,你应该格外小心变量 - 尤其是本地变量(例如,不要假设它们的地址将按给定的顺序分配,或者所有不同的变量将使用不同的地址)
答案 4 :(得分:0)
这是简单的指针数学。 float的地址至少增加了sizeof(float),(它应该是4,但你的增量为16,它取决于硬件和用于存储浮点数的实际大小),而char的地址增加了sizeof(char)(1)
你有y + 16 = z + 1这并不奇怪,记住“下一个浮动”(现在指向的“事物”)确实不是浮点数,而是浮点数后的内存位置等等它适用于z(它不会指向char);
它只是意味着浮点位置在char位置“之前”为15个字节。即y + 15 = z。
编辑:y,我总是指用&取得的浮点数的地址,因此对于z ...:即在你加入它们之前。 y + 16是y的递增值(在你执行y ++之后)和z + 1在z ++之后递增的z值。
编辑 2:愚蠢的我,我没有注意到你增加了4倍! sizeof(float)是4,4 * 4 = 16 ......!在你的机器上它也是4(正如IEEE对单精度fp数字的预期...)所以它意味着y +(sizeof(float)* 4 = z + sizeof(char)......它仍然意味着y位置是z之前的15个字节(字符的地址)