———–摘自《c和指针》6.9指针常量———————————————————————————————————————————-
假定变量a存储于位置100,下面这条语句的作用是什么?
*100 =25;
它看上去像是把25赋值给a,因为a是位置100所存储的变量。但是,这是错误的,因为字面值100的类型是整型,而间接访问操作只能作用于指针类型表达式。
如果你确实想把25存储于位置100,你必须使用强制类型转换。
*(int*)100 = 25;
强制类型转换把值100从“整型”转换为“指向整型的指针”,这样对它进行间接访问就是合法的。如果a存储于位置100,那么这条语句就把值25存储于a。
但是你需要这种技巧的机会是绝无仅有的。
你通常无法预测编译器会把某个特定的变量放在内存中的什么位置,所以你无法预先知道它的地址。用&操作符得到变量的地址是很容易的,但表达式在程序执行时才会进行求值,此时已经来不及把它的结果作为字面值常量复制到源代码。
这个技巧唯一有用之处是你偶尔需要通过地址访问内存中某个特定的位置,它并不是用于访问某个变量,而是访问硬件本身。例如,操作系统需要与输入输出设备控制器通信,启动I/O操作并从前面的操作中获得结果。在有些机器上,与设备控制器的通信是通过在某个特定内存地址读取和写入值来实现的。但是,与其说这些操作访问的是内存,还不如说它们访问的是设备控制器接口。这样,这些位置必须通过它们的地址访问,此时这些地址是预先已知的。
————————————————————————————————————————————————————————————
可以把指针的值当做一个整数取出来,也可以把一个整数值当作地址赋给一个指针。
int a=123,b;
int *ptr=&a;
char *str;
b=(int)ptr; //把指针ptr的值当作一个整数取出来。
str=(char*)b; //把这个整数的值当作一个地址赋给指针str。
注意:
例如:
unsigned int a;
a=N; //N必须代表一个合法的地址
ptr=a;
上面强调了a的值必须代表一个合法的地址,否则的话,你在使用ptr的时候,就会出现非法操作错误。
————————————————————————————————————————————————————————————
ps:一般不用一个整数给一个指针变量赋初值,但是可以用。(绝无仅有)
当向指针变量赋值时,赋的值必须是地址常量或变量,不能是普通整数。
运行如下代码:
int *pi = (int*)0xbfc5aaac;
一般情况下,会报“段错误”,因为这个地址可能没有映射到物理内存;
因此使用指针要特别小心,很容易将指针指向错误的地址,访问这样的地址可能导致段错误,可能读到无意义的值
为什么一般不用一个整数给一个指针变量赋初值?
应该是为了安全和兼容的问题。您将整数赋值给指针变量,就是赋给这个变量一个绝对地址。
您能确保您使用这个绝对地址时:
(1)您是否保证没有访问系统禁止您访问的空间;
(2)假设(1)满足,您能保证在任何计算机上访问这个空间的效果都一样?
如果这两点都能保证,您确实可以直接赋值(其中包含了一个强者转换的过程)。
不过,可能大多数情况下谁都没这个把握哦,也许X86系统的系统中断函数地址还20多年来始终维持不变?
tips:
- 任何一个指针变量本身数据值的类型都是unsigned long int
- 指针赋值运算常见的有以下几种形式:
把一个变量的地址赋予一个指向相同数据类型的指针;
把一个指针的值赋予相同数据类型的另外一个指针;
把数组的地址赋予指向相同数据类型的指针。
部分内容摘自互联网:
http://learn.akae.cn/media/ch23s01.html
http://zhidao.baidu.com/question/210714496.html?fr=qrl&cid=869&index=1