【更新-2012.3.16】字符串与指针常量
【问题描述】
看一个常见的实例,我们经常进行类似于下例的初始化操作:
书本告诉我们上述操作等价于:
注意:实际上不能这么做,因为message指针未分配内存。
问题:
为什么不是
下面从指针的角度分析。
【分析】
1 指针常量和常量指针
我们常看到这两个概念,很容易混淆,其实很简单,看下面两组用const关键字修饰的概念:
Type * const pointer ; - 指针常量,指针指向的地址是常量,即地址不可变,但指向的内容可以变。
const Type *pointer ;或Type const *pointer; - 常量指针,指针指向常量,即地址可以变,但指向的内容不能变。
【参考链接】
http://www.cppblog.com/cc/archive/2011/11/04/4045.html
这个写得很好,不过我认为还是不必记忆,只要记住指针结合性就可以了。
【指针结合性】
http://blog.csdn.net/tandesir/article/details/7177489
【修改·2012-2-24】
2 字符串与常量指针
其实字符串"Hello C"是常量指针,为什么这么说呢?因为,char *message = "Hello C";等价于char message[] = "Hello C";。访问字符串,实质是在访问字符串存储的地址。只不过这个指针很奇特,因为他存储的内容是const的。所以,不能对字符串进行赋值以试图修改其值。
既然"Hello C“是指针,那么对*message赋值显然就不对了。其一,*message不是指针;其二,*message的内容是常量,也是不可变的。
2 字符串与指针常量
字符串"Hello C"是指针常量,可以通过指针访问,不可修改其地址(初始化或赋值操作时,地址就确定了),但其值(内容)可能会因为越界等问题发生改变。因为,char *message = "Hello C";等价于char message[] = "Hello C";。访问字符串,实质是在访问字符串存储的地址。既然"Hello C“是常量,那么对*message赋值显然就不对了。其一,*message不是指针;其二,*message的内容(类似于"hello C"的字符串)是常量,也是不可变的。但message本身没有被const修饰,因此既不是常量指针,也不是指针常量。
【增-2012.3.16】
3 strcpy为什么要传递数组作为dest参数?
这是我们经常遇到的例子。gcc编译时,不会出错,但执行时,往往报段错误。这是什么原因?
"/usr/temp/xxxxxxxxxx"是一个常量指针,在初始化时,char *pathname进行了强制转换,pathname存储的是一个指针常量。在使用strcpy时,对这个指针常量的值进行了修改,这个结果是未定义的。正确的做法是将pathname声明为一个数组类型。
4 一个例子
将二进制值转换为字符:
【分析】“0123456789ABCDEF”是一个指针常量,“0123456789ABCDEF”[0]值为0,“0123456789ABCDEF”[1]值为1,依次类推。“0123456789ABCDEF”+0与“0123456789ABCDEF”[0]等价。