C语言中有的指针是容易把人弄晕的一个知识点。比如int *p=0x10000; *p=1;,后面的那个运算符“*”叫做“间接访问运算符”,所以这句话的意思是把1赋值给以p中的数据为地址存储单元中,就是存储单元0x10000中为1,不是直接把1赋值给p,而是间接访问了一下。
我们再来看看下面这句话:*((int *) 0x11111)=1;,这句话是把1赋值给谁呢?前面的0x11111被强制转换为指向int类型的指针,指针本质就是地址,既然最外面的“*”叫做“间接访问运算符”,所以这句话的意思应该是把1赋值给以存储单元0x11111中的数据为地址的单元中,假如0x11111中的值为0x10000,那么就是把1赋给了存储单元0x10000中;但是事实并非如此,上面那句话执行过后0x11111中的值变成了1,就是1被直接赋值到了存储单元0x11111中,好像没有间接访问啊?
所以个人认为“*”不应该翻译成“间接访问运算符”,最好译成就“指针运算符”或也可以叫地址运算符,“*”本质作用是把它后面的数据当做地址来对待而不是运算数据,就像x86中地址用“[]”标定(如[0x10000]);这样上面两句就好理解了,*p=1是把后面的变量P作为地址处理,变量p值是0x10000,所以0x10000被赋值1;*(int *)0x11111=1是把常量0x11111作为地址,所以0x11111被赋值1。这样就不会混淆了!
下面再来看看这个语句:(int *)0x11111=1;这个语句好像是把1赋值给了存储单元0x11111,理由是0x11111被强制转换为了指针,指针本质就是地址,那么,这句话把数据1赋值给存储单元0x11111是理所当然的了;可事实并非如此,在turbo c2.0编译时编译器会报错:lvalue required in function main,好像是提示需要一个左值。明明是被转换为了指针(地址),怎么不能对其赋值呢?原因就是指针型数据扮演着地址和普通数据的双重身份,不仅可以当做地址去访问,还能像普通的数据一样,可以进行运算,(int *) 0x11111=1;虽然把0x11111转换成了指针类型的数据,但是在(int *) 0x11111=1;中没有表明要把0x11111当做地址来看待,所以编译器把它当做一个常数,导致错误;如果这样写:*(int *)0x11111;,前面加了个地址运算符就是表明把0x11111当做地址来访问,就达到预期效果了。 |